Source code: com/aendvari/tethys/tag/logic/IterateTag.java
1 /*
2 * IterateTag.java
3 *
4 * Copyright (c) 2001, 2002 Aendvari, Ltd. All Rights Reserved.
5 *
6 * See the file LICENSE for terms of use.
7 *
8 */
9
10 package com.aendvari.tethys.tag.logic;
11
12 import java.util.*;
13 import java.io.IOException;
14
15 import javax.servlet.http.*;
16 import javax.servlet.jsp.*;
17 import javax.servlet.jsp.tagext.*;
18
19 import com.aendvari.common.model.*;
20
21 import com.aendvari.tethys.context.*;
22 import com.aendvari.tethys.context.model.*;
23
24 import com.aendvari.tethys.tag.*;
25 import com.aendvari.tethys.tag.model.*;
26
27
28 /**
29 * <p>Implementation class for the "iterate" tag.</p>
30 *
31 * @author Scott Milne
32 *
33 */
34
35 public class IterateTag extends ModelTreeBodyTag
36 {
37 /* Variables */
38
39 /** the default name to retrieve the index by */
40 static final public String DefaultIndexName = "iteratorIndex";
41
42 /** the iterator to use for the items */
43 private Iterator iterator;
44
45 /** the name to retrieve the index by */
46 private String indexName;
47
48 /** the iteration index */
49 private int iteratorIndex;
50
51 /** the iteration context */
52 private ModelContext iteratorContext;
53
54 /* Constructor */
55
56 public IterateTag()
57 {
58 super();
59
60 iterator = null;
61 iteratorIndex = 1;
62 indexName = null;
63 }
64
65 public Integer getIteratorIndex()
66 {
67 return new Integer(iteratorIndex);
68 }
69
70 public String getIndexName()
71 {
72 return indexName;
73 }
74
75 public void setIndexName(String setIndexName)
76 {
77 indexName = setIndexName;
78 }
79
80 /**
81 * Returns the iterator context as this tag's context, to provide
82 * context changes to sub-tags.
83 */
84
85 public ModelContext getModelContext() { return iteratorContext; }
86
87 public int doStartTag() throws JspTagException
88 {
89 if( iterator == null )
90 {
91 // establish tag context
92 establishModelContext();
93
94 // get the context model node
95 ModelNode contextNode = modelContext.getModelNode();
96
97 // get the model tree
98 ModelTree modelTree = contextNode.getOwnerModelTree();
99
100 // get the value from the path
101 iterator = modelTree.getNodes(contextNode, path).iterator();
102 }
103
104 // use the default name if one was not provided
105 if( indexName == null )
106 {
107 indexName = DefaultIndexName;
108 }
109
110 // since both XML and the OSM start their indexes at 1,
111 // make the variable do the same
112 iteratorIndex = 1;
113
114 // if there is another element available, set it
115 if( iterator.hasNext() )
116 {
117 try
118 {
119 setNextNode();
120 }
121 catch (Exception e)
122 {
123 throw new JspTagException("IterateTag: " + e.getMessage());
124 }
125
126 //
127 // COMPATIBILITY NOTICE
128 //
129 // If you are using JSP 1.1, this value is non-functional, use the following instead:
130 //
131 // EVAL_BODY_TAG
132 //
133 return EVAL_BODY_AGAIN;
134 }
135 else
136 {
137 return SKIP_BODY;
138 }
139 }
140
141 public int doAfterBody() throws JspException
142 {
143 BodyContent body = getBodyContent();
144 try
145 {
146 body.writeOut(getPreviousOut());
147 }
148 catch (IOException e)
149 {
150 throw new JspTagException("IterateTag: " + e.getMessage());
151 }
152
153 // clear up so the next time the body content is empty
154 body.clearBody();
155
156 if( iterator.hasNext() )
157 {
158 try
159 {
160 setNextNode();
161 }
162 catch (Exception e)
163 {
164 throw new JspTagException("IterateTag: " + e.getMessage());
165 }
166
167 //
168 // COMPATIBILITY NOTICE
169 //
170 // If you are using JSP 1.1, this value is non-functional, use the following instead:
171 //
172 // EVAL_BODY_TAG
173 //
174 return EVAL_BODY_AGAIN;
175 }
176 else
177 {
178 return SKIP_BODY;
179 }
180 }
181
182 private void setNextNode() throws JspException
183 {
184 try
185 {
186 // get the context map
187 ContextMap contextMap = ModelTagData.getData(
188 pageContext, getDataScope()).getModelContextMap();
189
190 // get the tag context
191 ModelContext tagContext = getParentModelContext();
192
193 ModelNode modelNode = (ModelNode)iterator.next();
194
195 String indexedPath = path + "[" + iteratorIndex + "]";
196
197 // now set this context into the request
198 iteratorContext = new ModelContext(
199 tagContext.extendLocation(name),
200 modelContext.extendModelPath(indexedPath),
201 modelNode);
202
203 contextMap.setContext(iteratorContext);
204
205 pageContext.setAttribute(indexName, getIteratorIndex());
206 iteratorIndex++;
207 }
208 catch (Exception e)
209 {
210 throw new JspTagException("IterateTag:" + e.toString());
211 }
212 }
213
214 /**
215 * Clean up after processing this enumeration.
216 *
217 * @exception JspException if a JSP exception has occurred
218 *
219 */
220
221 public int doEndTag() throws JspException
222 {
223 // Continue processing this page
224 return EVAL_PAGE;
225 }
226
227 /**
228 * Release all allocated resources.
229 *
230 */
231
232 public void release()
233 {
234 super.release();
235
236 iterator = null;
237 iteratorIndex = 0;
238 indexName = null;
239 }
240 }
241