View Javadoc

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 }