KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > jelly > TagSupport


1 /*
2  * Copyright 2002,2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.commons.jelly;
17
18 import java.io.StringWriter JavaDoc;
19 import java.util.Arrays JavaDoc;
20 import java.util.Collection JavaDoc;
21 import java.util.Iterator JavaDoc;
22
23 import org.apache.commons.jelly.util.TagUtils;
24
25 /** <p><code>TagSupport</code> an abstract base class which is useful to
26   * inherit from if developing your own tag.</p>
27   *
28   * @author <a HREF="mailto:jstrachan@apache.org">James Strachan</a>
29   * @version $Revision: 155420 $
30   */

31
32 public abstract class TagSupport implements Tag {
33
34     /** the parent of this tag */
35     protected Tag parent;
36
37     /** the body of the tag */
38     protected Script body;
39     /** The current context */
40
41     protected Boolean JavaDoc shouldTrim;
42     protected boolean hasTrimmed;
43
44     protected JellyContext context;
45
46     /** whether xml text should be escaped */
47     private boolean escapeText = true;
48
49     /**
50      * Searches up the parent hierarchy from the given tag
51      * for a Tag of the given type
52      *
53      * @param from the tag to start searching from
54      * @param tagClass the type of the tag to find
55      * @return the tag of the given type or null if it could not be found
56      */

57     public static Tag findAncestorWithClass(Tag from, Class JavaDoc tagClass) {
58         // we could implement this as
59
// return findAncestorWithClass(from,Collections.singleton(tagClass));
60
// but this is so simple let's save the object creation for now
61
while (from != null) {
62             if (tagClass.isInstance(from)) {
63                 return from;
64             }
65             from = from.getParent();
66         }
67         return null;
68     }
69
70     /**
71      * Searches up the parent hierarchy from the given tag
72      * for a Tag matching one or more of given types.
73      *
74      * @param from the tag to start searching from
75      * @param tagClasses a Collection of Class types that might match
76      * @return the tag of the given type or null if it could not be found
77      */

78     public static Tag findAncestorWithClass(Tag from, Collection JavaDoc tagClasses) {
79         while (from != null) {
80             for(Iterator JavaDoc iter = tagClasses.iterator();iter.hasNext();) {
81                 Class JavaDoc klass = (Class JavaDoc)(iter.next());
82                 if (klass.isInstance(from)) {
83                     return from;
84                 }
85             }
86             from = from.getParent();
87         }
88         return null;
89     }
90
91     /**
92      * Searches up the parent hierarchy from the given tag
93      * for a Tag matching one or more of given types.
94      *
95      * @param from the tag to start searching from
96      * @param tagClasses an array of types that might match
97      * @return the tag of the given type or null if it could not be found
98      * @see #findAncestorWithClass(Tag,Collection)
99      */

100     public static Tag findAncestorWithClass(Tag from, Class JavaDoc[] tagClasses) {
101         return findAncestorWithClass(from,Arrays.asList(tagClasses));
102     }
103
104     public TagSupport() {
105     }
106
107     public TagSupport(boolean shouldTrim) {
108         setTrim( shouldTrim );
109     }
110
111     /**
112      * Sets whether whitespace inside this tag should be trimmed or not.
113      * Defaults to true so whitespace is trimmed
114      */

115     public void setTrim(boolean shouldTrim) {
116         if ( shouldTrim ) {
117             this.shouldTrim = Boolean.TRUE;
118         }
119         else {
120             this.shouldTrim = Boolean.FALSE;
121         }
122     }
123
124     public boolean isTrim() {
125         if ( this.shouldTrim == null ) {
126             Tag parent = getParent();
127             if ( parent == null ) {
128                 return true;
129             }
130             else {
131                 if ( parent instanceof TagSupport ) {
132                     TagSupport parentSupport = (TagSupport) parent;
133
134                     this.shouldTrim = ( parentSupport.isTrim() ? Boolean.TRUE : Boolean.FALSE );
135                 }
136                 else {
137                     this.shouldTrim = Boolean.TRUE;
138                 }
139             }
140         }
141
142         return this.shouldTrim.booleanValue();
143     }
144
145     /** @return the parent of this tag */
146     public Tag getParent() {
147         return parent;
148     }
149
150     /** Sets the parent of this tag */
151     public void setParent(Tag parent) {
152         this.parent = parent;
153     }
154
155     /** @return the body of the tag */
156     public Script getBody() {
157         if (! hasTrimmed) {
158             hasTrimmed = true;
159             if (isTrim()) {
160                 trimBody();
161             }
162         }
163         return body;
164     }
165
166     /** Sets the body of the tag */
167     public void setBody(Script body) {
168         this.body = body;
169         this.hasTrimmed = false;
170     }
171
172     /** @return the context in which the tag will be run */
173     public JellyContext getContext() {
174         return context;
175     }
176
177     /** Sets the context in which the tag will be run */
178     public void setContext(JellyContext context) throws JellyTagException {
179         this.context = context;
180     }
181
182     /**
183      * Invokes the body of this tag using the given output
184      */

185     public void invokeBody(XMLOutput output) throws JellyTagException {
186         getBody().run(context, output);
187     }
188
189     // Implementation methods
190
//-------------------------------------------------------------------------
191
/**
192      * Searches up the parent hierarchy for a Tag of the given type.
193      * @return the tag of the given type or null if it could not be found
194      */

195     protected Tag findAncestorWithClass(Class JavaDoc parentClass) {
196         return findAncestorWithClass(getParent(), parentClass);
197     }
198
199     /**
200      * Searches up the parent hierarchy for a Tag of one of the given types.
201      * @return the tag of the given type or null if it could not be found
202      * @see #findAncestorWithClass(Collection)
203      */

204     protected Tag findAncestorWithClass(Class JavaDoc[] parentClasses) {
205         return findAncestorWithClass(getParent(),parentClasses);
206     }
207
208     /**
209      * Searches up the parent hierarchy for a Tag of one of the given types.
210      * @return the tag of the given type or null if it could not be found
211      */

212     protected Tag findAncestorWithClass(Collection JavaDoc parentClasses) {
213         return findAncestorWithClass(getParent(),parentClasses);
214     }
215
216     /**
217      * Executes the body of the tag and returns the result as a String.
218      *
219      * @return the text evaluation of the body
220      */

221     protected String JavaDoc getBodyText() throws JellyTagException {
222         return getBodyText(escapeText);
223     }
224
225     /**
226      * Executes the body of the tag and returns the result as a String.
227      *
228      * @param shouldEscape Signal if the text should be escaped.
229      *
230      * @return the text evaluation of the body
231      */

232     protected String JavaDoc getBodyText(boolean shouldEscape) throws JellyTagException {
233         StringWriter JavaDoc writer = new StringWriter JavaDoc();
234         invokeBody(XMLOutput.createXMLOutput(writer, shouldEscape));
235         return writer.toString();
236     }
237
238
239     /**
240      * Find all text nodes inside the top level of this body and
241      * if they are just whitespace then remove them
242      */

243     protected void trimBody() {
244         TagUtils.trimScript(body);
245     }
246
247     /**
248      * Returns whether the body of this tag will be escaped or not.
249      */

250     public boolean isEscapeText() {
251         return escapeText;
252     }
253
254     /**
255      * Sets whether the body of the tag should be escaped as text (so that &lt; and &gt; are
256      * escaped as &amp;lt; and &amp;gt;), which is the default or leave the text as XML.
257      */

258     public void setEscapeText(boolean escapeText) {
259         this.escapeText = escapeText;
260     }
261 }
262
Popular Tags