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