1. /*
  2. * The Apache Software License, Version 1.1
  3. *
  4. * Copyright (c) 1999 The Apache Software Foundation. All rights
  5. * reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. *
  14. * 2. Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in
  16. * the documentation and/or other materials provided with the
  17. * distribution.
  18. *
  19. * 3. The end-user documentation included with the redistribution, if
  20. * any, must include the following acknowlegement:
  21. * "This product includes software developed by the
  22. * Apache Software Foundation (http://www.apache.org/)."
  23. * Alternately, this acknowlegement may appear in the software itself,
  24. * if and wherever such third-party acknowlegements normally appear.
  25. *
  26. * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
  27. * Foundation" must not be used to endorse or promote products derived
  28. * from this software without prior written permission. For written
  29. * permission, please contact apache@apache.org.
  30. *
  31. * 5. Products derived from this software may not be called "Apache"
  32. * nor may "Apache" appear in their names without prior written
  33. * permission of the Apache Group.
  34. *
  35. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46. * SUCH DAMAGE.
  47. * ====================================================================
  48. *
  49. * This software consists of voluntary contributions made by many
  50. * individuals on behalf of the Apache Software Foundation. For more
  51. * information on the Apache Software Foundation, please see
  52. * <http://www.apache.org/>.
  53. *
  54. */
  55. package javax.servlet.jsp.tagext;
  56. import javax.servlet.jsp.*;
  57. import javax.servlet.jsp.tagext.*;
  58. import javax.servlet.*;
  59. import java.io.Writer;
  60. import java.io.Serializable;
  61. import java.util.Hashtable;
  62. import java.util.Enumeration;
  63. /**
  64. * A base class for defining new tag handlers implementing Tag.
  65. *
  66. * <p> The TagSupport class is a utility class intended to be used as
  67. * the base class for new tag handlers. The TagSupport class
  68. * implements the Tag and IterationTag interfaces and adds additional
  69. * convenience methods including getter methods for the properties in
  70. * Tag. TagSupport has one static method that is included to
  71. * facilitate coordination among cooperating tags.
  72. *
  73. * <p> Many tag handlers will extend TagSupport and only redefine a
  74. * few methods.
  75. */
  76. public class TagSupport implements IterationTag, Serializable {
  77. /**
  78. * Find the instance of a given class type that is closest to a given
  79. * instance.
  80. * This method uses the getParent method from the Tag
  81. * interface.
  82. * This method is used for coordination among cooperating tags.
  83. *
  84. * <p>
  85. * The current version of the specification only provides one formal
  86. * way of indicating the observable type of a tag handler: its
  87. * tag handler implementation class, described in the tag-class
  88. * subelement of the tag element. This is extended in an
  89. * informal manner by allowing the tag library author to
  90. * indicate in the description subelement an observable type.
  91. * The type should be a subtype of the tag handler implementation
  92. * class or void.
  93. * This addititional constraint can be exploited by a
  94. * specialized container that knows about that specific tag library,
  95. * as in the case of the JSP standard tag library.
  96. *
  97. * <p>
  98. * When a tag library author provides information on the
  99. * observable type of a tag handler, client programmatic code
  100. * should adhere to that constraint. Specifically, the Class
  101. * passed to findAncestorWithClass should be a subtype of the
  102. * observable type.
  103. *
  104. *
  105. * @param from The instance from where to start looking.
  106. * @param klass The subclass of Tag or interface to be matched
  107. * @returns the nearest ancestor that implements the interface
  108. * or is an instance of the class specified
  109. */
  110. public static final Tag findAncestorWithClass(Tag from, Class klass) {
  111. boolean isInterface = false;
  112. if (from == null ||
  113. klass == null ||
  114. (!Tag.class.isAssignableFrom(klass) &&
  115. !(isInterface = klass.isInterface()))) {
  116. return null;
  117. }
  118. for (;;) {
  119. Tag tag = from.getParent();
  120. if (tag == null) {
  121. return null;
  122. }
  123. if ((isInterface && klass.isInstance(tag)) ||
  124. klass.isAssignableFrom(tag.getClass()))
  125. return tag;
  126. else
  127. from = tag;
  128. }
  129. }
  130. /**
  131. * Default constructor, all subclasses are required to define only
  132. * a public constructor with the same signature, and to call the
  133. * superclass constructor.
  134. *
  135. * This constructor is called by the code generated by the JSP
  136. * translator.
  137. */
  138. public TagSupport() { }
  139. /**
  140. * Default processing of the start tag, returning SKIP_BODY.
  141. *
  142. * @returns SKIP_BODY
  143. *
  144. * @see Tag#doStartTag()
  145. */
  146. public int doStartTag() throws JspException {
  147. return SKIP_BODY;
  148. }
  149. /**
  150. * Default processing of the end tag returning EVAL_PAGE.
  151. *
  152. * @returns EVAL_PAGE
  153. *
  154. * @see Tag#doEndTag()
  155. */
  156. public int doEndTag() throws JspException {
  157. return EVAL_PAGE;
  158. }
  159. /**
  160. * Default processing for a body
  161. *
  162. * @return SKIP_BODY
  163. *
  164. * @see IterationTag#doAfterBody()
  165. */
  166. public int doAfterBody() throws JspException {
  167. return SKIP_BODY;
  168. }
  169. // Actions related to body evaluation
  170. /**
  171. * Release state.
  172. *
  173. * @see Tag#release()
  174. */
  175. public void release() {
  176. parent = null;
  177. }
  178. /**
  179. * Set the nesting tag of this tag.
  180. *
  181. * @param t The parent Tag.
  182. * @see Tag#setParent(Tag)
  183. */
  184. public void setParent(Tag t) {
  185. parent = t;
  186. }
  187. /**
  188. * The Tag instance most closely enclosing this tag instance.
  189. * @see Tag#getParent()
  190. *
  191. * @returns the parent tag instance or null
  192. */
  193. public Tag getParent() {
  194. return parent;
  195. }
  196. /**
  197. * Set the id attribute for this tag.
  198. *
  199. * @param id The String for the id.
  200. */
  201. public void setId(String id) {
  202. this.id = id;
  203. }
  204. /**
  205. * The value of the id attribute of this tag; or null.
  206. *
  207. * @returns the value of the id attribute, or null
  208. */
  209. public String getId() {
  210. return id;
  211. }
  212. /**
  213. * Set the page context.
  214. *
  215. * @param pageContenxt The PageContext.
  216. * @see Tag#setPageContext
  217. */
  218. public void setPageContext(PageContext pageContext) {
  219. this.pageContext = pageContext;
  220. }
  221. /**
  222. * Associate a value with a String key.
  223. *
  224. * @param k The key String.
  225. * @param o The value to associate.
  226. */
  227. public void setValue(String k, Object o) {
  228. if (values == null) {
  229. values = new Hashtable();
  230. }
  231. values.put(k, o);
  232. }
  233. /**
  234. * Get a the value associated with a key.
  235. *
  236. * @param k The string key.
  237. * @returns The value associated with the key, or null.
  238. */
  239. public Object getValue(String k) {
  240. if (values == null) {
  241. return null;
  242. } else {
  243. return values.get(k);
  244. }
  245. }
  246. /**
  247. * Remove a value associated with a key.
  248. *
  249. * @param k The string key.
  250. */
  251. public void removeValue(String k) {
  252. if (values != null) {
  253. values.remove(k);
  254. }
  255. }
  256. /**
  257. * Enumerate the values kept by this tag handler.
  258. *
  259. * @returns An enumeration of all the values set.
  260. */
  261. public Enumeration getValues() {
  262. if (values == null) {
  263. return null;
  264. }
  265. return values.keys();
  266. }
  267. // private fields
  268. private Tag parent;
  269. private Hashtable values;
  270. protected String id;
  271. // protected fields
  272. protected PageContext pageContext;
  273. }