001: /* ForEach.java
002:
003: {{IS_NOTE
004: Purpose:
005:
006: Description:
007:
008: History:
009: Tue Sep 6 15:33:11 2005, Created by tomyeh
010: }}IS_NOTE
011:
012: Copyright (C) 2005 Potix Corporation. All Rights Reserved.
013:
014: {{IS_RIGHT
015: This program is distributed under GPL Version 2.0 in the hope that
016: it will be useful, but WITHOUT ANY WARRANTY.
017: }}IS_RIGHT
018: */
019: package org.zkoss.web.servlet.dsp.action;
020:
021: import java.util.List;
022: import java.util.Collection;
023: import java.util.Map;
024: import java.util.ListIterator;
025: import java.util.Iterator;
026: import java.util.Enumeration;
027: import java.io.StringWriter;
028: import java.io.IOException;
029:
030: import org.zkoss.web.mesg.MWeb;
031: import org.zkoss.web.servlet.ServletException;
032:
033: /**
034: * Iterators thru a collection/array of items.
035: *
036: * @author tomyeh
037: */
038: public class ForEach extends AbstractAction {
039: private String _var, _varStatus;
040: private Object _items;
041: private int _beg = 0, _end = Integer.MAX_VALUE;
042: private boolean _trim = true;
043: private boolean _endSpecified, _itemsSpecified;
044:
045: /** Returns the variable name used to iterate thru items. */
046: public String getVar() {
047: return _var;
048: }
049:
050: /** Sets the variable name used to iterate thru items. */
051: public void setVar(String var) {
052: _var = var;
053: }
054:
055: /** Returns the variable name used to hold the current iteration
056: * status, an instance of {@link LoopStatus}.
057: */
058: public String getVarStatus() {
059: return _varStatus;
060: }
061:
062: /** Sets the variable name used to hold the current iteration status.
063: */
064: public void setVarStatus(String varStatus) {
065: _varStatus = varStatus;
066: }
067:
068: /** Returns the attribute items. */
069: public Object getItems() {
070: return _items;
071: }
072:
073: /** Sets the attribute items. */
074: public void setItems(Object items) {
075: _items = items;
076: _itemsSpecified = true;
077: }
078:
079: /** Returns the index of the item at which the iteration begins.
080: */
081: public int getBegin() {
082: return _beg;
083: }
084:
085: /** Sets the index of the item at which the iteration begins.
086: * <p>Default: 0.
087: */
088: public void setBegin(int beg) {
089: if (beg < 0)
090: throw new IllegalArgumentException("Non-negative only");
091: _beg = beg;
092: }
093:
094: /** Returns the index of the item at which the iteration ends (inclusive).
095: */
096: public int getEnd() {
097: return _end;
098: }
099:
100: /** Sets the index of the item at which the iteration ends (inclusive).
101: * <p>Default: Integer.MAX_VALUE.
102: */
103: public void setEnd(int end) {
104: _end = end;
105: _endSpecified = true;
106: }
107:
108: /** Returns whether to trim the result. */
109: public boolean isTrim() {
110: return _trim;
111: }
112:
113: /** Sets whether to trim the result.
114: * <p>Default: true.
115: */
116: public void setTrim(boolean trim) {
117: _trim = trim;
118: }
119:
120: //-- Action --//
121: public void render(ActionContext ac, boolean nested)
122: throws javax.servlet.ServletException, IOException {
123: //at least items or end must be specified
124: if (!nested || (_itemsSpecified && _items == null)
125: || (_endSpecified && _end < _beg)
126: || (!_itemsSpecified && !_endSpecified)
127: || !isEffective())
128: return;
129:
130: final Object old1 = _var != null ? ac.getAttribute(_var,
131: ac.PAGE_SCOPE) : null;
132: final Object old2;
133: final Status st;
134: if (_varStatus != null) {
135: old2 = ac.getAttribute(_varStatus, ac.PAGE_SCOPE);
136: ac.setAttribute(_varStatus, st = new Status(),
137: ac.PAGE_SCOPE);
138: } else {
139: old2 = null;
140: st = null;
141: }
142:
143: if (_items == null) { //use begin and end only
144: renderWith(ac, st);
145: } else if (_items.getClass().isArray()) {
146: if (_items instanceof Object[])
147: renderWith(ac, st, (Object[]) _items);
148: else if (_items instanceof int[])
149: renderWith(ac, st, (int[]) _items);
150: else if (_items instanceof short[])
151: renderWith(ac, st, (short[]) _items);
152: else if (_items instanceof long[])
153: renderWith(ac, st, (long[]) _items);
154: else if (_items instanceof byte[])
155: renderWith(ac, st, (byte[]) _items);
156: else if (_items instanceof char[])
157: renderWith(ac, st, (char[]) _items);
158: else if (_items instanceof double[])
159: renderWith(ac, st, (double[]) _items);
160: else if (_items instanceof float[])
161: renderWith(ac, st, (float[]) _items);
162: else
163: throw new InternalError("Unknown " + _items.getClass());
164: } else if (_beg > 0 && (_items instanceof List)) {
165: final List l = (List) _items;
166: final int size = l.size();
167: renderWith(ac, st, l
168: .listIterator(_beg > size ? size : _beg));
169: } else if (_items instanceof Collection) {
170: renderWith(ac, st, ((Collection) _items).iterator());
171: } else if (_items instanceof Map) {
172: renderWith(ac, st, ((Map) _items).entrySet().iterator());
173: } else if (_items instanceof Iterator) {
174: renderWith(ac, st, (Iterator) _items);
175: } else if (_items instanceof Enumeration) {
176: renderWith(ac, st, (Enumeration) _items);
177: } else if (_items instanceof String) {
178: renderWith(ac, st, (String) _items);
179: } else {
180: throw new ServletException(
181: MWeb.DSP_UNKNOWN_ATTRIBUTE_VALUE, new Object[] {
182: this , "items",
183: new Integer(ac.getLineNumber()) });
184: }
185:
186: if (_var != null)
187: ac.setAttribute(_var, old1, ac.PAGE_SCOPE);
188: if (_varStatus != null)
189: ac.setAttribute(_varStatus, old2, ac.PAGE_SCOPE);
190: }
191:
192: private void renderWith(ActionContext ac, Status st)
193: throws javax.servlet.ServletException, IOException {
194: final StringWriter out = _trim ? new StringWriter() : null;
195: for (int j = _beg; j <= _end; ++j) {
196: final Object val = new Integer(j);
197: if (_var != null)
198: ac.setAttribute(_var, val, ac.PAGE_SCOPE);
199: if (st != null)
200: st.update(j, val);
201: ac.renderFragment(out);
202: }
203: if (out != null)
204: ac.getOut().write(out.toString().trim());
205: }
206:
207: private void renderWith(ActionContext ac, Status st, ListIterator it)
208: throws javax.servlet.ServletException, IOException {
209: final StringWriter out = _trim ? new StringWriter() : null;
210: for (int j = 0, cnt = _end - _beg + 1; it.hasNext()
211: && --cnt >= 0; ++j) {
212: final Object val = it.next();
213: if (_var != null)
214: ac.setAttribute(_var, val, ac.PAGE_SCOPE);
215: if (st != null)
216: st.update(j, val);
217: ac.renderFragment(out);
218: }
219: if (out != null)
220: ac.getOut().write(out.toString().trim());
221: }
222:
223: private void renderWith(ActionContext ac, Status st, Iterator it)
224: throws javax.servlet.ServletException, IOException {
225: final StringWriter out = _trim ? new StringWriter() : null;
226:
227: for (int j = 0; ++j <= _beg && it.hasNext();)
228: //skip
229: it.next();
230:
231: for (int j = 0, cnt = _end - _beg + 1; it.hasNext()
232: && --cnt >= 0; ++j) {
233: final Object val = it.next();
234: if (_var != null)
235: ac.setAttribute(_var, val, ac.PAGE_SCOPE);
236: if (st != null)
237: st.update(j, val);
238: ac.renderFragment(out);
239: }
240: if (out != null)
241: ac.getOut().write(out.toString().trim());
242: }
243:
244: private void renderWith(ActionContext ac, Status st, Enumeration enm)
245: throws javax.servlet.ServletException, IOException {
246: final StringWriter out = _trim ? new StringWriter() : null;
247:
248: for (int j = 0; ++j <= _beg && enm.hasMoreElements();)
249: //skip
250: enm.nextElement();
251:
252: for (int j = 0, cnt = _end - _beg + 1; enm.hasMoreElements()
253: && --cnt >= 0; ++j) {
254: final Object val = enm.nextElement();
255: if (_var != null)
256: ac.setAttribute(_var, val, ac.PAGE_SCOPE);
257: if (st != null)
258: st.update(j, val);
259: ac.renderFragment(out);
260: }
261: if (out != null)
262: ac.getOut().write(out.toString().trim());
263: }
264:
265: private void renderWith(ActionContext ac, Status st, Object[] ary)
266: throws javax.servlet.ServletException, IOException {
267: final StringWriter out = _trim ? new StringWriter() : null;
268: for (int j = _beg; j < ary.length && j <= _end; ++j) {
269: final Object val = ary[j];
270: if (_var != null)
271: ac.setAttribute(_var, val, ac.PAGE_SCOPE);
272: if (st != null)
273: st.update(j, val);
274: ac.renderFragment(out);
275: }
276: if (out != null)
277: ac.getOut().write(out.toString().trim());
278: }
279:
280: private void renderWith(ActionContext ac, Status st, int[] ary)
281: throws javax.servlet.ServletException, IOException {
282: final StringWriter out = _trim ? new StringWriter() : null;
283: for (int j = _beg; j < ary.length && j <= _end; ++j) {
284: final Object val = new Integer(ary[j]);
285: if (_var != null)
286: ac.setAttribute(_var, val, ac.PAGE_SCOPE);
287: if (st != null)
288: st.update(j, val);
289: ac.renderFragment(out);
290: }
291: if (out != null)
292: ac.getOut().write(out.toString().trim());
293: }
294:
295: private void renderWith(ActionContext ac, Status st, short[] ary)
296: throws javax.servlet.ServletException, IOException {
297: final StringWriter out = _trim ? new StringWriter() : null;
298: for (int j = _beg; j < ary.length && j <= _end; ++j) {
299: final Object val = new Short(ary[j]);
300: if (_var != null)
301: ac.setAttribute(_var, val, ac.PAGE_SCOPE);
302: if (st != null)
303: st.update(j, val);
304: ac.renderFragment(out);
305: }
306: if (out != null)
307: ac.getOut().write(out.toString().trim());
308: }
309:
310: private void renderWith(ActionContext ac, Status st, long[] ary)
311: throws javax.servlet.ServletException, IOException {
312: final StringWriter out = _trim ? new StringWriter() : null;
313: for (int j = _beg; j < ary.length && j <= _end; ++j) {
314: final Object val = new Long(ary[j]);
315: if (_var != null)
316: ac.setAttribute(_var, val, ac.PAGE_SCOPE);
317: if (st != null)
318: st.update(j, val);
319: ac.renderFragment(out);
320: }
321: if (out != null)
322: ac.getOut().write(out.toString().trim());
323: }
324:
325: private void renderWith(ActionContext ac, Status st, char[] ary)
326: throws javax.servlet.ServletException, IOException {
327: final StringWriter out = _trim ? new StringWriter() : null;
328: for (int j = _beg; j < ary.length && j <= _end; ++j) {
329: final Object val = new Character(ary[j]);
330: if (_var != null)
331: ac.setAttribute(_var, val, ac.PAGE_SCOPE);
332: if (st != null)
333: st.update(j, val);
334: ac.renderFragment(out);
335: }
336: if (out != null)
337: ac.getOut().write(out.toString().trim());
338: }
339:
340: private void renderWith(ActionContext ac, Status st, byte[] ary)
341: throws javax.servlet.ServletException, IOException {
342: final StringWriter out = _trim ? new StringWriter() : null;
343: for (int j = _beg; j < ary.length && j <= _end; ++j) {
344: final Object val = new Byte(ary[j]);
345: if (_var != null)
346: ac.setAttribute(_var, val, ac.PAGE_SCOPE);
347: if (st != null)
348: st.update(j, val);
349: ac.renderFragment(out);
350: }
351: if (out != null)
352: ac.getOut().write(out.toString().trim());
353: }
354:
355: private void renderWith(ActionContext ac, Status st, float[] ary)
356: throws javax.servlet.ServletException, IOException {
357: final StringWriter out = _trim ? new StringWriter() : null;
358: for (int j = _beg; j < ary.length && j <= _end; ++j) {
359: final Object val = new Float(ary[j]);
360: if (_var != null)
361: ac.setAttribute(_var, val, ac.PAGE_SCOPE);
362: if (st != null)
363: st.update(j, val);
364: ac.renderFragment(out);
365: }
366: if (out != null)
367: ac.getOut().write(out.toString().trim());
368: }
369:
370: private void renderWith(ActionContext ac, Status st, double[] ary)
371: throws javax.servlet.ServletException, IOException {
372: final StringWriter out = _trim ? new StringWriter() : null;
373: for (int j = _beg; j < ary.length && j <= _end; ++j) {
374: final Object val = new Double(ary[j]);
375: if (_var != null)
376: ac.setAttribute(_var, val, ac.PAGE_SCOPE);
377: if (st != null)
378: st.update(j, val);
379: ac.renderFragment(out);
380: }
381: if (out != null)
382: ac.getOut().write(out.toString().trim());
383: }
384:
385: private void renderWith(ActionContext ac, Status st, String txt)
386: throws javax.servlet.ServletException, IOException {
387: final StringBuffer sb = new StringBuffer();
388: int idx = 0;
389: final StringWriter out = _trim ? new StringWriter() : null;
390: for (int j = _beg, len = txt.length(); j < len && j <= _end; ++j) {
391: char cc = txt.charAt(j);
392: if (cc == ',') {
393: final Object val = sb.toString();
394: if (_var != null)
395: ac.setAttribute(_var, val, ac.PAGE_SCOPE);
396: if (st != null)
397: st.update(idx++, val);
398: ac.renderFragment(out);
399: sb.setLength(0);
400: } else if (cc == '\\' && j + 1 < len) {
401: cc = txt.charAt(j + 1);
402: switch (cc) {
403: case 'n':
404: cc = '\n';
405: break;
406: case 'r':
407: cc = '\r';
408: break;
409: case 't':
410: cc = '\t';
411: break;
412: case 'b':
413: cc = '\b';
414: break;
415: }
416: }
417: sb.append(cc);
418: }
419: if (sb.length() > 0) {
420: final Object val = sb.toString();
421: if (_var != null)
422: ac.setAttribute(_var, val, ac.PAGE_SCOPE);
423: if (st != null)
424: st.update(idx++, val);
425: ac.renderFragment(out);
426: }
427: if (out != null)
428: ac.getOut().write(out.toString().trim());
429: }
430:
431: //-- Object --//
432: public String toString() {
433: return "forEach";
434: }
435:
436: private static class Status implements LoopStatus {
437: private int _j;
438: private Object _cur;
439:
440: public int getIndex() {
441: return _j;
442: }
443:
444: public Object getCurrent() {
445: return _cur;
446: }
447:
448: private void update(int j, Object cur) {
449: _j = j;
450: _cur = cur;
451: }
452: }
453: }
|