001: /*
002: * Copyright (c) 2002-2003 by OpenSymphony
003: * All rights reserved.
004: */
005: package com.opensymphony.webwork.components;
006:
007: import java.io.Writer;
008: import java.util.ArrayList;
009: import java.util.Iterator;
010: import java.util.List;
011:
012: import org.apache.commons.logging.Log;
013: import org.apache.commons.logging.LogFactory;
014:
015: import com.opensymphony.webwork.components.Param.UnnamedParametric;
016: import com.opensymphony.webwork.util.MakeIterator;
017: import com.opensymphony.webwork.util.MergeIteratorFilter;
018: import com.opensymphony.xwork.util.OgnlValueStack;
019:
020: /**
021: * <!-- START SNIPPET: javadoc -->
022: * <p>Component for MergeIteratorTag, which job is to merge iterators and successive
023: * call to the merged iterator will cause each merge iterator to have a chance to
024: * expose its element, subsequently next call will allow the next iterator to expose
025: * its element. Once the last iterator is done exposing its element, the first iterator
026: * is allowed to do so again (unless it is exhausted of entries).</P>
027: *
028: * <p>Internally the task are delegated to MergeIteratorFilter</p>
029: *
030: * <p>Example if there are 3 lists being merged, each list have 3 entries, the following will
031: * be the logic.</P>
032: * <ol>
033: * <li>Display first element of the first list</li>
034: * <li>Display first element of the second list</li>
035: * <li>Display first element of the third list</li>
036: * <li>Display second element of the first list</li>
037: * <li>Display second element of the second list</li>
038: * <li>Display second element of the third list</li>
039: * <li>Display third element of the first list</li>
040: * <li>Display thrid element of the second list</li>
041: * <li>Display third element of the thrid list</li>
042: * </ol>
043: * <!-- END SNIPPET: javadoc -->
044: *
045: * <!-- START SNIPPET: params -->
046: * <ul>
047: * <li>id (String) - the id where the resultant merged iterator will be stored in the stack's context</li>
048: * </ul>
049: * <!-- END SNIPPET: params -->
050: *
051: *
052: * <!-- START SNIPPET: javacode -->
053: * public class MergeIteratorTagAction extends ActionSupport {
054: *
055: * private List myList1;
056: * private List myList2;
057: * private List myList3;
058: *
059: * public List getMyList1() {
060: * return myList1;
061: * }
062: *
063: * public List getMyList2() {
064: * return myList2;
065: * }
066: *
067: * public List getMyList3() {
068: * return myList3;
069: * }
070: *
071: *
072: * public String execute() throws Exception {
073: *
074: * myList1 = new ArrayList();
075: * myList1.add("1");
076: * myList1.add("2");
077: * myList1.add("3");
078: *
079: * myList2 = new ArrayList();
080: * myList2.add("a");
081: * myList2.add("b");
082: * myList2.add("c");
083: *
084: * myList3 = new ArrayList();
085: * myList3.add("A");
086: * myList3.add("B");
087: * myList3.add("C");
088: *
089: * return "done";
090: * }
091: * }
092: * <!-- END SNIPPET: javacode -->
093: *
094: * <!-- START SNIPPET: example -->
095: * <ww:merge id="myMergedIterator1">
096: * <ww:param value="%{myList1}" />
097: * <ww:param value="%{myList2}" />
098: * <ww:param value="%{myList3}" />
099: * </ww:merge>
100: * <ww:iterator value="%{#myMergedIterator1}">
101: * <ww:property />
102: * </ww:iterator>
103: * <!-- END SNIPPET: example -->
104: *
105: * <!-- START SNIPPET: description -->
106: * This wil generate "1aA2bB3cC".
107: * <!-- START SNIPPET: description -->
108: *
109: * @author tm_jee (tm_jee (at) yahoo.co.uk)
110: * @version $Date: 2006-03-18 17:28:55 +0100 (Sat, 18 Mar 2006) $ $Id: MergeIterator.java 2468 2006-03-18 16:28:55Z rgielen $
111: * @see com.opensymphony.webwork.util.MergeIteratorFilter
112: * @see com.opensymphony.webwork.views.jsp.iterator.MergeIteratorTag
113: *
114: * @ww.tag name="merge" tld-body-content="JSP" tld-tag-class="com.opensymphony.webwork.views.jsp.iterator.MergeIteratorTag"
115: * description="Merge the values of a list of iterators into one iterator"
116: */
117: public class MergeIterator extends Component implements
118: UnnamedParametric {
119:
120: private static final Log _log = LogFactory
121: .getLog(MergeIterator.class);
122:
123: private MergeIteratorFilter mergeIteratorFilter = null;
124: private List _parameters;
125:
126: public MergeIterator(OgnlValueStack stack) {
127: super (stack);
128: }
129:
130: public boolean start(Writer writer) {
131:
132: mergeIteratorFilter = new MergeIteratorFilter();
133: _parameters = new ArrayList();
134:
135: return super .start(writer);
136: }
137:
138: public boolean end(Writer writer, String body) {
139:
140: for (Iterator parametersIterator = _parameters.iterator(); parametersIterator
141: .hasNext();) {
142: Object iteratorEntryObj = parametersIterator.next();
143: if (!MakeIterator.isIterable(iteratorEntryObj)) {
144: _log
145: .warn("param with value resolved as "
146: + iteratorEntryObj
147: + " cannot be make as iterator, it will be ignored and hence will not appear in the merged iterator");
148: continue;
149: }
150: mergeIteratorFilter.setSource(MakeIterator
151: .convert(iteratorEntryObj));
152: }
153:
154: mergeIteratorFilter.execute();
155:
156: // if id exists, we put it in the stack's context
157: if (getId() != null && getId().length() > 0) {
158: getStack().getContext().put(getId(), mergeIteratorFilter);
159: }
160:
161: mergeIteratorFilter = null;
162:
163: return super .end(writer, body);
164: }
165:
166: /**
167: * the id where the resultant merged iterator will be stored in the stack's context
168: * @ww.tagattribute required="false"
169: */
170: public void setId(String id) {
171: super .setId(id);
172: }
173:
174: // == UnnamedParametric interface implementation ---------------------
175: public void addParameter(Object value) {
176: _parameters.add(value);
177: }
178: }
|