001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.cocoon.taglib.jxpath.core;
019:
020: import org.apache.cocoon.taglib.IterationTag;
021: import org.apache.cocoon.taglib.core.ForEachSupport;
022: import org.apache.cocoon.taglib.core.LoopTag;
023:
024: import org.xml.sax.Attributes;
025: import org.xml.sax.SAXException;
026:
027: /**
028: * <p>A handler for <forEach> that accepts attributes as Strings
029: * and evaluates them as expressions at runtime.</p>
030: *
031: * Migration from JSTL1.0
032: * @see org.apache.taglibs.standard.tag.el.core.ForEachTag
033: *
034: * @author <a href="mailto:volker.schmitt@basf-it-services.com">Volker Schmitt</a>
035: * @version CVS $Id: ForEachTag.java 433543 2006-08-22 06:22:54Z crossley $
036: */
037: public class ForEachTag extends ForEachSupport implements LoopTag,
038: IterationTag {
039:
040: //*********************************************************************
041: // 'Private' state (implementation details)
042:
043: private String begin_; // stores EL-based property
044: private String end_; // stores EL-based property
045: private String step_; // stores EL-based property
046: private String items_; // stores EL-based property
047:
048: //*********************************************************************
049: // Constructor
050:
051: public ForEachTag() {
052: super ();
053: init();
054: }
055:
056: //*********************************************************************
057: // Tag logic
058:
059: /* Begins iterating by processing the first item. */
060: public int doStartTag(String namespaceURI, String localName,
061: String qName, Attributes atts) throws SAXException {
062:
063: // evaluate any expressions we were passed, once per invocation
064: evaluateExpressions();
065:
066: // chain to the parent implementation
067: return super .doStartTag(namespaceURI, localName, qName, atts);
068: }
069:
070: // Releases any resources we may have (or inherit)
071: public void recycle() {
072: init();
073: super .recycle();
074:
075: }
076:
077: //*********************************************************************
078: // Accessor methods
079:
080: // for EL-based attribute
081: public void setBegin(String begin_) {
082: this .begin_ = begin_;
083: this .beginSpecified = true;
084: }
085:
086: // for EL-based attribute
087: public void setEnd(String end_) {
088: this .end_ = end_;
089: this .endSpecified = true;
090: }
091:
092: // for EL-based attribute
093: public void setStep(String step_) {
094: this .step_ = step_;
095: this .stepSpecified = true;
096: }
097:
098: public void setItems(String items_) {
099: this .items_ = items_;
100: }
101:
102: //*********************************************************************
103: // Private (utility) methods
104:
105: // (re)initializes state (during release() or construction)
106: private void init() {
107: // defaults for interface with page author
108: begin_ = null; // (no expression)
109: end_ = null; // (no expression)
110: step_ = null; // (no expression)
111: items_ = null; // (no expression)
112: }
113:
114: /* Evaluates expressions as necessary */
115: private void evaluateExpressions() throws SAXException {
116:
117: if (begin_ != null) {
118: begin = Integer.parseInt(begin_);
119: }
120: if (end_ != null) {
121: end = Integer.parseInt(end_);
122: }
123: if (step_ != null) {
124: step = Integer.parseInt(step_);
125: }
126: if (items_ != null) {
127: rawItems = getVariable(items_);
128: }
129:
130: /*
131: * Note: we don't check for type mismatches here; we assume
132: * the expression evaluator will return the expected type
133: * (by virtue of knowledge we give it about what that type is).
134: * A ClassCastException here is truly unexpected, so we let it
135: * propagate up.
136: */
137: /*
138: if (begin_ != null) {
139: Object r = ExpressionEvaluatorManager.evaluate("begin", begin_, Integer.class, this, pageContext);
140: if (r == null)
141: throw new NullAttributeException("forEach", "begin");
142: begin = ((Integer) r).intValue();
143: validateBegin();
144: }
145:
146: if (end_ != null) {
147: Object r = ExpressionEvaluatorManager.evaluate("end", end_, Integer.class, this, pageContext);
148: if (r == null)
149: throw new NullAttributeException("forEach", "end");
150: end = ((Integer) r).intValue();
151: validateEnd();
152: }
153:
154: if (step_ != null) {
155: Object r = ExpressionEvaluatorManager.evaluate("step", step_, Integer.class, this, pageContext);
156: if (r == null)
157: throw new NullAttributeException("forEach", "step");
158: step = ((Integer) r).intValue();
159: validateStep();
160: }
161:
162: if (items_ != null) {
163: rawItems = ExpressionEvaluatorManager.evaluate("items", items_, Object.class, this, pageContext);
164: // use an empty list to indicate "no iteration", if relevant
165: if (rawItems == null)
166: rawItems = new ArrayList();
167: }
168: */
169: }
170: }
|