1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.struts2.components;
22
23 import java.io.Writer;
24 import java.util.ArrayList;
25 import java.util.Iterator;
26 import java.util.List;
27
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30 import org.apache.struts2.views.annotations.StrutsTag;
31 import org.apache.struts2.views.annotations.StrutsTagAttribute;
32 import org.apache.struts2.components.Param.UnnamedParametric;
33 import org.apache.struts2.util.MakeIterator;
34 import org.apache.struts2.util.MergeIteratorFilter;
35
36 import com.opensymphony.xwork2.util.ValueStack;
37
38 /***
39 * <!-- START SNIPPET: javadoc -->
40 * <p>Component for MergeIteratorTag, which job is to merge iterators and successive
41 * call to the merged iterator will cause each merge iterator to have a chance to
42 * expose its element, subsequently next call will allow the next iterator to expose
43 * its element. Once the last iterator is done exposing its element, the first iterator
44 * is allowed to do so again (unless it is exhausted of entries).</P>
45 *
46 * <p>Internally the task are delegated to MergeIteratorFilter</p>
47 *
48 * <p>Example if there are 3 lists being merged, each list have 3 entries, the following will
49 * be the logic.</P>
50 * <ol>
51 * <li>Display first element of the first list</li>
52 * <li>Display first element of the second list</li>
53 * <li>Display first element of the third list</li>
54 * <li>Display second element of the first list</li>
55 * <li>Display second element of the second list</li>
56 * <li>Display second element of the third list</li>
57 * <li>Display third element of the first list</li>
58 * <li>Display thrid element of the second list</li>
59 * <li>Display third element of the thrid list</li>
60 * </ol>
61 * <!-- END SNIPPET: javadoc -->
62 *
63 * <!-- START SNIPPET: params -->
64 * <ul>
65 * <li>id (String) - the id where the resultant merged iterator will be stored in the stack's context</li>
66 * </ul>
67 * <!-- END SNIPPET: params -->
68 *
69 *
70 * <!-- START SNIPPET: javacode -->
71 * public class MergeIteratorTagAction extends ActionSupport {
72 *
73 * private List myList1;
74 * private List myList2;
75 * private List myList3;
76 *
77 * public List getMyList1() {
78 * return myList1;
79 * }
80 *
81 * public List getMyList2() {
82 * return myList2;
83 * }
84 *
85 * public List getMyList3() {
86 * return myList3;
87 * }
88 *
89 *
90 * public String execute() throws Exception {
91 *
92 * myList1 = new ArrayList();
93 * myList1.add("1");
94 * myList1.add("2");
95 * myList1.add("3");
96 *
97 * myList2 = new ArrayList();
98 * myList2.add("a");
99 * myList2.add("b");
100 * myList2.add("c");
101 *
102 * myList3 = new ArrayList();
103 * myList3.add("A");
104 * myList3.add("B");
105 * myList3.add("C");
106 *
107 * return "done";
108 * }
109 * }
110 * <!-- END SNIPPET: javacode -->
111 *
112 * <!-- START SNIPPET: example -->
113 * <s:merge id="myMergedIterator1">
114 * <s:param value="%{myList1}" />
115 * <s:param value="%{myList2}" />
116 * <s:param value="%{myList3}" />
117 * </s:merge>
118 * <s:iterator value="%{#myMergedIterator1}">
119 * <s:property />
120 * </s:iterator>
121 * <!-- END SNIPPET: example -->
122 *
123 * <!-- START SNIPPET: description -->
124 * This wil generate "1aA2bB3cC".
125 * <!-- START SNIPPET: description -->
126 *
127 * @see org.apache.struts2.util.MergeIteratorFilter
128 * @see org.apache.struts2.views.jsp.iterator.MergeIteratorTag
129 *
130 */
131 @StrutsTag(name="merge", tldTagClass="org.apache.struts2.views.jsp.iterator.MergeIteratorTag", description="Merge the values " +
132 "of a list of iterators into one iterator")
133 public class MergeIterator extends Component implements UnnamedParametric {
134
135 private static final Log _log = LogFactory.getLog(MergeIterator.class);
136
137 private MergeIteratorFilter mergeIteratorFilter = null;
138 private List _parameters;
139
140 public MergeIterator(ValueStack stack) {
141 super(stack);
142 }
143
144 public boolean start(Writer writer) {
145
146 mergeIteratorFilter = new MergeIteratorFilter();
147 _parameters = new ArrayList();
148
149 return super.start(writer);
150 }
151
152 public boolean end(Writer writer, String body) {
153
154 for (Iterator parametersIterator = _parameters.iterator(); parametersIterator.hasNext(); ) {
155 Object iteratorEntryObj = parametersIterator.next();
156 if (! MakeIterator.isIterable(iteratorEntryObj)) {
157 _log.warn("param with value resolved as "+iteratorEntryObj+" cannot be make as iterator, it will be ignored and hence will not appear in the merged iterator");
158 continue;
159 }
160 mergeIteratorFilter.setSource(MakeIterator.convert(iteratorEntryObj));
161 }
162
163 mergeIteratorFilter.execute();
164
165
166 if (getId() != null && getId().length() > 0) {
167 getStack().getContext().put(getId(), mergeIteratorFilter);
168 }
169
170 mergeIteratorFilter = null;
171
172 return super.end(writer, body);
173 }
174
175 @StrutsTagAttribute(description="The id where the resultant merged iterator will be stored in the stack's context")
176 public void setId(String id) {
177 super.setId(id);
178 }
179
180
181 public void addParameter(Object value) {
182 _parameters.add(value);
183 }
184 }