View Javadoc
1   package gboat2.base.view.components;
2   
3   import java.lang.reflect.Array;
4   import java.util.Collection;
5   import java.util.Map;
6   
7   import javax.servlet.http.HttpServletRequest;
8   import javax.servlet.http.HttpServletResponse;
9   
10  import org.apache.commons.lang3.RandomStringUtils;
11  import org.apache.commons.lang3.StringUtils;
12  import org.apache.struts2.components.ClosingUIBean;
13  import org.apache.struts2.util.MakeIterator;
14  import org.apache.struts2.views.annotations.StrutsTag;
15  import org.apache.struts2.views.annotations.StrutsTagAttribute;
16  
17  import com.opensymphony.xwork2.util.ValueStack;
18  
19  /**
20   * <p>
21   * 创建一个可以折叠的面板(Accordion),详见 <a target="_blank" href="http://api.jqueryui.com/accordion/">Accordion Widget</a>
22   * </p>
23   * <pre>
24   * <strong>示例1: 手动创建</strong>
25   * &lt;g2:accordion id="accordion"&gt;
26   *     &lt;g2:accordionItem title="公司简介"&gt;
27   *         &lt;p&gt;广联达是服务于建筑产品的建造者、运维者和使用者的信息化平台运营商,为客户提供建设工程全生命周期的信息化解决方案。公司将持续引领产业发展、推动社会进步,用科技创造美好生活和居住环境! &lt;/p&gt;
28   *         &lt;p&gt;广联达软件股份有限公司成立于1998年,2010年5月在深圳中小企业板成功上市(股票简称:广联达,股票代码:002410),成为中国建设工程领域信息化产业首家上市软件公司。&lt;/p&gt;
29   *     &lt;/g2:accordionItem&gt;
30   *     &lt;g2:accordionItem title="发展历程"&gt;
31   *         &lt;ul&gt;
32   *             &lt;li&gt;从成立之初的7位创始人,到如今的全国三千五百余名员工、四十余家分支机构的建设信息;&lt;/li&gt;
33   *             &lt;li&gt;从方庄地下室,到中关村软件软园内总建筑面积超过四万平米的两栋自主产权大厦;&lt;/li&gt;
34   *             &lt;li&gt;从单一的预算软件,发展到工程造价、工程信息、工程施工、工程设计、企业管理、教育培训、电子政务以及面向各类客户的互联网应用等八大类、七十余种产品;&lt;/li&gt;
35   *             &lt;li&gt;企业用户数量达到十五万余家,其中工具类产品直接使用者五十万,管理类产品直接使用者百余万;&lt;/li&gt;
36   *         &lt;/ul&gt;
37   *    &lt;/g2:accordionItem&gt;
38   *    &lt;g2:accordionItem title="公司荣誉"&gt;
39   *         &lt;dl&gt;
40   *             &lt;dt&gt;2013所获荣誉&lt;/dt&gt;
41   *             &lt;dd&gt;2013—2014年度国家规划布局内重点软件企业&lt;/dd&gt;
42   *             &lt;dd&gt;“中国软件创新力20强”称号&lt;/dd&gt;
43   *             &lt;dd&gt;广联达的“基于CAD识别的三维模型重建技术在安装算量软件中的应用及产业化”荣获北京市科学技术奖三等奖&lt;/dd&gt;
44   *         &lt;/dl&gt;
45   *     &lt;/g2:accordionItem&gt;
46   * &lt;/g2:accordion&gt;
47   * 
48   * <strong>示例2: 使用 Map 创建</strong>
49   * JSP 代码:
50   * &lt;g2:accordion id=&quot;accordionlist&quot; list=&quot;accordion&quot;/&gt;
51   * 
52   * Action 代码:
53   * private Map&lt;String, String&gt; accordion;
54   *
55   * public String execute() throws Exception {
56   *   accordion = new LinkedHashMap&lt;String, String&gt;();
57   *   accordion.put(
58   *       &quot;Section 1&quot;,
59   *       &quot;Mauris mauris ante, blandit et, ultrices a, suscipit eget, quam. Integer ut neque. Vivamus nisi metus, molestie vel, gravida in, condimentum sit amet, nunc. Nam a nibh. Donec suscipit eros. Nam mi. Proin viverra leo ut odio. Curabitur malesuada. Vestibulum a velit eu ante scelerisque vulputate.&quot;);
60   *   accordion.put(
61   *       &quot;Section 2&quot;,
62   *       &quot;Sed non urna. Donec et ante. Phasellus eu ligula. Vestibulum sit amet purus. Vivamus hendrerit, dolor at aliquet laoreet, mauris turpis porttitor velit, faucibus interdum tellus libero ac justo. Vivamus non quam. In suscipit faucibus urna.&quot;);
63   *   accordion.put(
64   *       &quot;Section 3&quot;,
65   *       &quot;Nam enim risus, molestie et, porta ac, aliquam ac, risus. Quisque lobortis. Phasellus pellentesque purus in massa. Aenean in pede. Phasellus ac libero ac tellus pellentesque semper. Sed ac felis. Sed commodo, magna quis lacinia ornare, quam ante aliquam nisi, eu iaculis leo purus venenatis dui.&quot;);
66   *   accordion.put(
67   *       &quot;Section 4&quot;,
68   *       &quot;Cras dictum. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean lacinia mauris vel est. Suspendisse eu nisl. Nullam ut libero. Integer dignissim consequat lectus. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.&quot;);
69   *   return SUCCESS;
70   * }
71   *
72   * public Map&lt;String, String&gt; getAccordion() {
73   *   return accordion;
74   * }
75   * </pre>
76   *
77   * @author <a href="http://www.jgeppert.com">Johannes Geppert</a>
78   */
79  @StrutsTag(
80          name = "accordion",
81          tldTagClass = "gboat2.base.view.jsp.AccordionTag",
82          description = "创建一个可以折叠的面板(Accordion),详见 http://api.jqueryui.com/accordion/")
83  public class Accordion extends ClosingUIBean {
84      public static final String TEMPLATE = "accordion";
85      public static final String TEMPLATE_CLOSE = "accordion-close";
86  
87      public static final String JQUERYACTION = "accordion";
88  
89      protected boolean throwExceptionOnNullValueAttribute = false;
90  
91      protected String active;
92      protected String animate;
93      protected String collapsible;
94      protected String event;
95      protected String header;
96      protected String heightStyle;
97      protected Object list;
98      protected String listKey;
99      protected String listValue;
100     protected String href;
101     protected String paramKeys;
102     protected String paramValues;
103     
104     protected String onActivateTopics;
105     protected String onBeforeActivateTopics;
106     protected String onCreateTopics;
107 
108     public Accordion(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
109         super(stack, request, response);
110     }
111 
112     @Override
113     public String getDefaultOpenTemplate() {
114         return TEMPLATE;
115     }
116 
117     @Override
118     protected String getDefaultTemplate() {
119         return TEMPLATE_CLOSE;
120     }
121 
122     @SuppressWarnings("rawtypes")
123     @Override
124     public void evaluateExtraParams() {
125         super.evaluateExtraParams();
126 
127         addParameter("jqueryaction", JQUERYACTION);
128 
129         if (active != null)
130             addParameter("active", findValue(active, Integer.class));
131         
132         if (animate != null)
133             addParameter("animate", findString(animate));
134         
135         if (collapsible != null)
136             addParameter("collapsible", findValue(this.collapsible, Boolean.class));
137         
138         if (event != null)
139             addParameter("event", findString(event));
140 
141         if (header != null)
142             addParameter("header", findString(header));
143         
144         if (heightStyle != null)
145             addParameter("heightStyle", findString(heightStyle));
146 
147         Object value = null;
148         if (list == null) {
149             list = parameters.get("list");
150         }
151         if (list instanceof String) {
152             value = findValue((String) list);
153         } else if (list instanceof Collection) {
154             value = list;
155         } else if (MakeIterator.isIterable(list)) {
156             value = MakeIterator.convert(list);
157         }
158         if (value == null) {
159             if (throwExceptionOnNullValueAttribute) {
160                 // will throw an exception if not found
161                 value = findValue((list == null) ? (String) list : list.toString(), "list",
162                         "The requested list key '" + list + "' could not be resolved as a collection/array/map/enumeration/iterator type. Example: people or people.{name}");
163             } else {
164                 value = findValue((list == null) ? (String) list : list.toString());
165             }
166         }
167 
168         if (value instanceof Collection) {
169             addParameter("list", value);
170         } else {
171             addParameter("list", MakeIterator.convert(value));
172         }
173 
174         if (value instanceof Collection) {
175             addParameter("listSize", Integer.valueOf(((Collection) value).size()));
176         } else if (value instanceof Map) {
177             addParameter("listSize", Integer.valueOf(((Map) value).size()));
178         } else if (value != null && value.getClass().isArray()) {
179             addParameter("listSize", Integer.valueOf(Array.getLength(value)));
180         }
181 
182         if (listKey != null) {
183             listKey = stripExpressionIfAltSyntax(listKey);
184             addParameter("listKey", listKey);
185         } else if (value instanceof Map) {
186             addParameter("listKey", "key");
187         }
188 
189         if (listValue != null) {
190             listValue = stripExpressionIfAltSyntax(listValue);
191             addParameter("listValue", listValue);
192         } else if (value instanceof Map) {
193             addParameter("listValue", "value");
194         }
195 
196         if (href != null)
197             addParameter("href", findString(href));
198         
199         if (paramKeys != null)
200             addParameter("paramKeys", findString(paramKeys));
201         
202         if (paramValues != null)
203             addParameter("paramValues", findString(paramValues));
204         
205         if (onActivateTopics != null)
206             addParameter("onActivateTopics", findString(onActivateTopics));
207         
208         if (onBeforeActivateTopics != null)
209             addParameter("onBeforeActivateTopics", findString(onBeforeActivateTopics));
210         
211         if (onCreateTopics != null)
212             addParameter("onCreateTopics", findString(onCreateTopics));
213 
214         if (StringUtils.isBlank(id)) {
215             this.id = "accordion_" + RandomStringUtils.randomNumeric(3);
216             addParameter("id", this.id);
217         }
218     }
219 
220     @StrutsTagAttribute(description = "当前打开哪一个面板,0 表示第一个", type = "Integer", defaultValue = "0")
221     public void setActive(String active) {
222         this.active = active;
223     }
224 
225     @StrutsTagAttribute(description = "切换面板时要使用的 easing 动画形式 名称,可选值请参见 http://api.jqueryui.com/easings/")
226     public void setAnimate(String animate) {
227         this.animate = animate;
228     }
229 
230     @StrutsTagAttribute(description = "是否允许折叠展开的面板", type = "Boolean", defaultValue = "false")
231     public void setCollapsible(String collapsible) {
232         this.collapsible = collapsible;
233     }
234 
235     @Override
236     @StrutsTagAttribute(description = "如果设置为 true,则禁用该 Accordion(折叠面板)", type = "Boolean", defaultValue = "false")
237     public void setDisabled(String disabled) {
238         super.setDisabled(disabled);
239     }
240 
241     @StrutsTagAttribute(description = "Accordion(折叠面板) 头部会作出反应的事件,用以激活相关的面板。可以指定多个事件,用空格隔开,如 mouseover", defaultValue = "click")
242     public void setEvent(String event) {
243         this.event = event;
244     }
245 
246     public String getHeader() {
247         return header;
248     }
249 
250     @StrutsTagAttribute(description = "折叠面板的头部标签名(Tag Name)", defaultValue = "h3")
251     public void setHeader(String header) {
252         this.header = header;
253     }
254 
255     @StrutsTagAttribute(description = "控制 Accordion(折叠面板) 和每个面板的高度,可选值:'auto' - 所有的面板将会被设置为最高的面板的高度; 'fill' - 基于 accordion 的父元素的高度,扩展到可用的高度; 'content' - 每个面板的高度取决于它的内容", defaultValue = "auto")
256     public void setHeightStyle(String heightStyle) {
257         this.heightStyle = heightStyle;
258     }
259 
260     @StrutsTagAttribute(description = "从一个已有列表(集合)加载可折叠面板,该列表可以是 Array/Map/Collection 等 Iterator 对象")
261     public void setList(Object list) {
262         this.list = list;
263     }
264 
265     @StrutsTagAttribute(description = "从一个列表中加载可折叠面板时的标题内容")
266     public void setListKey(String listKey) {
267         this.listKey = listKey;
268     }
269 
270     @StrutsTagAttribute(description = "从一个列表中加载可折叠面板时的面板内容")
271     public void setListValue(String listValue) {
272         this.listValue = listValue;
273     }
274 
275     @StrutsTagAttribute(description = "如果需要通过 Ajax 从远程服务器加载面板内容,则通过此属性设置 ajax 请求的 URL")
276     public void setHref(String href) {
277         this.href = href;
278     }
279 
280     @StrutsTagAttribute(description = "跟在 href 后面的参数名称,多值之间使用逗号分隔,如: queryParam1,queryParam2")
281     public void setParamKeys(String paramKeys) {
282         this.paramKeys = paramKeys;
283     }
284 
285     @StrutsTagAttribute(description = "跟在 href 后面的参数值,多值之间使用逗号分隔,与 paramKeys 一一对应,如: queryValue1,queryValue2")
286     public void setParamValues(String paramValues) {
287         this.paramValues = paramValues;
288     }
289 
290     @StrutsTagAttribute(description = "面板被激活后(在动画完成之后)发布的消息主题,多值之间使用逗号分隔")
291     public void setOnActivateTopics(String onActivateTopics) {
292         this.onActivateTopics = onActivateTopics;
293     }
294 
295     @StrutsTagAttribute(description = "面板被激活前发布的消息主题,多值之间使用逗号分隔")
296     public void setOnBeforeActivateTopics(String onBeforeActivateTopics) {
297         this.onBeforeActivateTopics = onBeforeActivateTopics;
298     }
299 
300     @StrutsTagAttribute(description = "当创建 accordion 时发布的消息主题,多值之间使用逗号分隔")
301     public void setOnCreateTopics(String onCreateTopics) {
302         this.onCreateTopics = onCreateTopics;
303     }
304 }