1 /*
2 * $Header: /home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/TagSupport.java,v 1.17 2002/08/20 05:02:51 werken Exp $
3 * $Revision: 1.17 $
4 * $Date: 2002/08/20 05:02:51 $
5 *
6 * ====================================================================
7 *
8 * The Apache Software License, Version 1.1
9 *
10 * Copyright (c) 1999-2002 The Apache Software Foundation. All rights
11 * reserved.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 *
17 * 1. Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 *
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in
22 * the documentation and/or other materials provided with the
23 * distribution.
24 *
25 * 3. The end-user documentation included with the redistribution, if
26 * any, must include the following acknowlegement:
27 * "This product includes software developed by the
28 * Apache Software Foundation (http://www.apache.org/)."
29 * Alternately, this acknowlegement may appear in the software itself,
30 * if and wherever such third-party acknowlegements normally appear.
31 *
32 * 4. The names "The Jakarta Project", "Commons", and "Apache Software
33 * Foundation" must not be used to endorse or promote products derived
34 * from this software without prior written permission. For written
35 * permission, please contact apache@apache.org.
36 *
37 * 5. Products derived from this software may not be called "Apache"
38 * nor may "Apache" appear in their names without prior written
39 * permission of the Apache Group.
40 *
41 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
42 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
43 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
44 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
45 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
46 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
47 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
48 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
49 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
50 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
51 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
52 * SUCH DAMAGE.
53 * ====================================================================
54 *
55 * This software consists of voluntary contributions made by many
56 * individuals on behalf of the Apache Software Foundation. For more
57 * information on the Apache Software Foundation, please see
58 * <http://www.apache.org/>.
59 *
60 * $Id: TagSupport.java,v 1.17 2002/08/20 05:02:51 werken Exp $
61 */
62 package org.apache.commons.jelly;
63
64 import org.apache.commons.jelly.impl.CompositeTextScriptBlock;
65 import org.apache.commons.jelly.impl.ScriptBlock;
66 import org.apache.commons.jelly.impl.TextScript;
67
68 import java.io.StringWriter;
69 import java.io.Writer;
70 import java.util.List;
71
72 /*** <p><code>TagSupport</code> an abstract base class which is useful to
73 * inherit from if developing your own tag.</p>
74 *
75 * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
76 * @version $Revision: 1.17 $
77 */
78
79 public abstract class TagSupport implements Tag {
80
81 /*** the parent of this tag */
82 protected Tag parent;
83
84 /*** the body of the tag */
85 protected Script body;
86 /*** The current context */
87
88 protected Boolean shouldTrim;
89 protected boolean hasTrimmed;
90
91 protected JellyContext context;
92
93 /***
94 * Searches up the parent hierarchy from the given tag
95 * for a Tag of the given type
96 *
97 * @param from the tag to start searching from
98 * @param tagClass the type of the tag to find
99 * @return the tag of the given type or null if it could not be found
100 */
101 public static Tag findAncestorWithClass(Tag from, Class tagClass) {
102 while (from != null) {
103 if (tagClass.isInstance(from)) {
104 return from;
105 }
106 from = from.getParent();
107 }
108 return null;
109 }
110
111 public TagSupport() {
112 }
113
114 public TagSupport(boolean shouldTrim) {
115 setTrim( shouldTrim );
116 }
117
118 /***
119 * Sets whether whitespace inside this tag should be trimmed or not.
120 * Defaults to true so whitespace is trimmed
121 */
122 public void setTrim(boolean shouldTrim) {
123 if ( shouldTrim ) {
124 this.shouldTrim = Boolean.TRUE;
125 }
126 else {
127 this.shouldTrim = Boolean.FALSE;
128 }
129 }
130
131 public boolean isTrim() {
132 if ( this.shouldTrim == null ) {
133 Tag parent = getParent();
134 if ( parent == null ) {
135 return true;
136 }
137 else {
138 if ( parent instanceof TagSupport ) {
139 TagSupport parentSupport = (TagSupport) parent;
140
141 this.shouldTrim = ( parentSupport.isTrim() ? Boolean.TRUE : Boolean.FALSE );
142 }
143 else {
144 this.shouldTrim = Boolean.TRUE;
145 }
146 }
147 }
148
149 return this.shouldTrim.booleanValue();
150 }
151
152 /*** @return the parent of this tag */
153 public Tag getParent() {
154 return parent;
155 }
156
157 /*** Sets the parent of this tag */
158 public void setParent(Tag parent) {
159 this.parent = parent;
160 }
161
162 /*** @return the body of the tag */
163 public Script getBody() {
164 return body;
165 }
166
167 /*** Sets the body of the tag */
168 public void setBody(Script body) {
169 this.body = body;
170 this.hasTrimmed = false;
171 }
172
173 /*** @return the context in which the tag will be run */
174 public JellyContext getContext() {
175 return context;
176 }
177
178 /*** Sets the context in which the tag will be run */
179 public void setContext(JellyContext context) throws Exception {
180 this.context = context;
181 }
182
183 /***
184 * Invokes the body of this tag using the given output
185 */
186 public void invokeBody(XMLOutput output) throws Exception {
187 if ( isTrim() && ! hasTrimmed ) {
188 trimBody();
189 }
190 getBody().run(context, output);
191 }
192
193 // Implementation methods
194 //-------------------------------------------------------------------------
195 /***
196 * Searches up the parent hierarchy for a Tag of the given type
197 * @return the tag of the given type or null if it could not be found
198 */
199 protected Tag findAncestorWithClass(Class parentClass) {
200 return findAncestorWithClass(getParent(), parentClass);
201 }
202
203 /***
204 * Evaluates the given body using a buffer and returns the String
205 * of the result.
206 *
207 * @return the text evaluation of the body
208 */
209 protected String getBodyText() throws Exception {
210 StringWriter writer = new StringWriter();
211 invokeBody(XMLOutput.createXMLOutput(writer));
212 return writer.toString();
213 }
214
215 /***
216 * Evaluates the given body using a buffer and returns the String
217 * of the result.
218 *
219 * @param shouldEscape Signal if the text should be escaped.
220 *
221 * @return the text evaluation of the body
222 */
223 protected String getBodyText(boolean shouldEscape) throws Exception {
224 StringWriter writer = new StringWriter();
225 invokeBody(XMLOutput.createXMLOutput(writer,shouldEscape));
226 return writer.toString();
227 }
228
229
230 /***
231 * Find all text nodes inside the top level of this body and
232 * if they are just whitespace then remove them
233 */
234 protected void trimBody() {
235
236 // #### should refactor this code into
237 // #### trimWhitespace() methods on the Script objects
238
239 if ( body instanceof CompositeTextScriptBlock ) {
240 CompositeTextScriptBlock block = (CompositeTextScriptBlock) body;
241 List list = block.getScriptList();
242 int size = list.size();
243 if ( size > 0 ) {
244 Script script = (Script) list.get(0);
245 if ( script instanceof TextScript ) {
246 TextScript textScript = (TextScript) script;
247 textScript.trimStartWhitespace();
248 }
249 if ( size > 1 ) {
250 script = (Script) list.get(size - 1);
251 if ( script instanceof TextScript ) {
252 TextScript textScript = (TextScript) script;
253 textScript.trimEndWhitespace();
254 }
255 }
256 }
257 }
258 else
259 if ( body instanceof ScriptBlock ) {
260 ScriptBlock block = (ScriptBlock) body;
261 List list = block.getScriptList();
262 for ( int i = list.size() - 1; i >= 0; i-- ) {
263 Script script = (Script) list.get(i);
264 if ( script instanceof TextScript ) {
265 TextScript textScript = (TextScript) script;
266 String text = textScript.getText();
267 text = text.trim();
268 if ( text.length() == 0 ) {
269 list.remove(i);
270 }
271 else {
272 textScript.setText(text);
273 }
274 }
275 }
276 }
277 else if ( body instanceof TextScript ) {
278 TextScript textScript = (TextScript) body;
279 textScript.trimWhitespace();
280 }
281
282 this.hasTrimmed = true;
283 }
284 }
This page was automatically generated by Maven