1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.apache.myfaces.trinidad.webapp;
20
21 import java.util.Enumeration;
22 import java.util.Hashtable;
23
24 import javax.servlet.jsp.JspException;
25 import javax.servlet.jsp.PageContext;
26 import javax.servlet.jsp.tagext.IterationTag;
27 import javax.servlet.jsp.tagext.Tag;
28
29 /**
30 * This is the Trinidad version of the JSP <code>TagSupport</code> class.
31 * The main difference is that this class is <b>NOT</b> implementing the
32 * <code>Serializable</code> interface.
33 *
34 * @author Apache Tomcat team
35 */
36 public class TrinidadTagSupport implements IterationTag
37 {
38 /**
39 * Find the instance of a given class type that is closest to a given
40 * instance. This method uses the getParent method from the Tag interface.
41 * This method is used for coordination among cooperating tags.
42 *
43 * <p>
44 * The current version of the specification only provides one formal way of
45 * indicating the observable type of a tag handler: its tag handler
46 * implementation class, described in the tag-class subelement of the tag
47 * element. This is extended in an informal manner by allowing the tag library
48 * author to indicate in the description subelement an observable type. The
49 * type should be a subtype of the tag handler implementation class or void.
50 * This addititional constraint can be exploited by a specialized container
51 * that knows about that specific tag library, as in the case of the JSP
52 * standard tag library.
53 *
54 * <p>
55 * When a tag library author provides information on the observable type of a
56 * tag handler, client programmatic code should adhere to that constraint.
57 * Specifically, the Class passed to findAncestorWithClass should be a subtype
58 * of the observable type.
59 *
60 *
61 * @param from
62 * The instance from where to start looking.
63 * @param klass
64 * The subclass of Tag or interface to be matched
65 * @return the nearest ancestor that implements the interface or is an
66 * instance of the class specified
67 */
68 public static final Tag findAncestorWithClass(Tag from,
69 // TCK signature test fails with generics
70 @SuppressWarnings("unchecked") Class klass)
71 {
72 boolean isInterface = false;
73
74 if (from == null
75 || klass == null
76 || (!Tag.class.isAssignableFrom(klass) && !(isInterface = klass
77 .isInterface())))
78 {
79 return null;
80 }
81
82 for (;;)
83 {
84 Tag tag = from.getParent();
85
86 if (tag == null)
87 {
88 return null;
89 }
90
91 if ((isInterface && klass.isInstance(tag))
92 || klass.isAssignableFrom(tag.getClass()))
93 return tag;
94 else
95 from = tag;
96 }
97 }
98
99 /**
100 * Default constructor, all subclasses are required to define only a public
101 * constructor with the same signature, and to call the superclass
102 * constructor.
103 *
104 * This constructor is called by the code generated by the JSP translator.
105 */
106
107 public TrinidadTagSupport()
108 {
109 }
110
111 /**
112 * Default processing of the start tag, returning SKIP_BODY.
113 *
114 * @return SKIP_BODY
115 * @throws JspException
116 * if an error occurs while processing this tag
117 *
118 * @see Tag#doStartTag()
119 */
120
121 public int doStartTag() throws JspException
122 {
123 return SKIP_BODY;
124 }
125
126 /**
127 * Default processing of the end tag returning EVAL_PAGE.
128 *
129 * @return EVAL_PAGE
130 * @throws JspException
131 * if an error occurs while processing this tag
132 *
133 * @see Tag#doEndTag()
134 */
135
136 public int doEndTag() throws JspException
137 {
138 return EVAL_PAGE;
139 }
140
141 /**
142 * Default processing for a body.
143 *
144 * @return SKIP_BODY
145 * @throws JspException
146 * if an error occurs while processing this tag
147 *
148 * @see IterationTag#doAfterBody()
149 */
150
151 public int doAfterBody() throws JspException
152 {
153 return SKIP_BODY;
154 }
155
156 // Actions related to body evaluation
157
158 /**
159 * Release state.
160 *
161 * @see Tag#release()
162 */
163
164 public void release()
165 {
166 parent = null;
167 id = null;
168 if (values != null)
169 {
170 values.clear();
171 }
172 values = null;
173 }
174
175 /**
176 * Set the nesting tag of this tag.
177 *
178 * @param t
179 * The parent Tag.
180 * @see Tag#setParent(Tag)
181 */
182
183 public void setParent(Tag t)
184 {
185 parent = t;
186 }
187
188 /**
189 * The Tag instance most closely enclosing this tag instance.
190 *
191 * @see Tag#getParent()
192 *
193 * @return the parent tag instance or null
194 */
195
196 public Tag getParent()
197 {
198 return parent;
199 }
200
201 /**
202 * Set the id attribute for this tag.
203 *
204 * @param id
205 * The String for the id.
206 */
207
208 public void setId(String id)
209 {
210 this.id = id;
211 }
212
213 /**
214 * The value of the id attribute of this tag; or null.
215 *
216 * @return the value of the id attribute, or null
217 */
218
219 public String getId()
220 {
221 return id;
222 }
223
224 /**
225 * Set the page context.
226 *
227 * @param pageContext
228 * The PageContext.
229 * @see Tag#setPageContext
230 */
231
232 public void setPageContext(PageContext pageContext)
233 {
234 this.pageContext = pageContext;
235 }
236
237 /**
238 * Associate a value with a String key.
239 *
240 * @param k
241 * The key String.
242 * @param o
243 * The value to associate.
244 */
245
246 public void setValue(String k, Object o)
247 {
248 if (values == null)
249 {
250 values = new Hashtable<String, Object>();
251 }
252 values.put(k, o);
253 }
254
255 /**
256 * Get a the value associated with a key.
257 *
258 * @param k
259 * The string key.
260 * @return The value associated with the key, or null.
261 */
262
263 public Object getValue(String k)
264 {
265 if (values == null)
266 {
267 return null;
268 } else
269 {
270 return values.get(k);
271 }
272 }
273
274 /**
275 * Remove a value associated with a key.
276 *
277 * @param k
278 * The string key.
279 */
280
281 public void removeValue(String k)
282 {
283 if (values != null)
284 {
285 values.remove(k);
286 }
287 }
288
289 /**
290 * Enumerate the keys for the values kept by this tag handler.
291 *
292 * @return An enumeration of all the keys for the values set, or null or an
293 * empty Enumeration if no values have been set.
294 */
295
296 public Enumeration<String> getValues()
297 {
298 if (values == null)
299 {
300 return null;
301 }
302 return values.keys();
303 }
304
305 // private fields
306
307 private Tag parent;
308 private Hashtable<String, Object> values;
309 /**
310 * The value of the id attribute of this tag; or null.
311 */
312 protected String id;
313
314 // protected fields
315
316 /**
317 * The PageContext.
318 */
319 protected PageContext pageContext;
320 }