1 /*
2 * $Header: /home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/define/DynamicTag.java,v 1.7 2002/05/17 15:18:12 jstrachan Exp $
3 * $Revision: 1.7 $
4 * $Date: 2002/05/17 15:18:12 $
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: DynamicTag.java,v 1.7 2002/05/17 15:18:12 jstrachan Exp $
61 */
62 package org.apache.commons.jelly.tags.betwixt;
63
64 import java.net.URL;
65
66 import org.apache.commons.betwixt.XMLIntrospector;
67 import org.apache.commons.betwixt.io.BeanReader;
68
69 import org.apache.commons.jelly.JellyException;
70 import org.apache.commons.jelly.MissingAttributeException;
71 import org.apache.commons.jelly.TagSupport;
72 import org.apache.commons.jelly.XMLOutput;
73
74 import org.apache.commons.logging.Log;
75 import org.apache.commons.logging.LogFactory;
76
77 /***
78 * Parses some XML specified via the given URI (which can be relative or an absolute URL) and outputs the
79 * parsed object. Typically this tag is customized by setting the introspector attribute or nesting a child
80 * introspector tag inside it.</p>
81 *
82 * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
83 * @version $Revision: 1.7 $
84 */
85 public class ParseTag extends TagSupport {
86
87 /*** The Log to which logging calls will be made. */
88 private static final Log log = LogFactory.getLog(ParseTag.class);
89
90 /*** the BeanReader used to parse the XML */
91 private BeanReader reader = new BeanReader();
92
93 private String uri;
94 private String var;
95 private String rootClass;
96 private String path;
97 private XMLIntrospector introspector;
98 private boolean useContextClassLoader;
99 private ClassLoader classLoader;
100
101
102 public ParseTag() {
103 }
104
105 // Tag interface
106 //-------------------------------------------------------------------------
107 public void doTag(final XMLOutput output) throws Exception {
108 if ( var == null ) {
109 throw new MissingAttributeException( "var" );
110 }
111 if ( rootClass == null ) {
112 throw new MissingAttributeException( "rootClass" );
113 }
114
115 reader.setXMLIntrospector(getIntrospector());
116
117 Class theClass = null;
118 try {
119 theClass = getClassLoader().loadClass( rootClass );
120 }
121 catch (Exception e) {
122 throw new JellyException( "Could not load class called: " + rootClass, e );
123 }
124
125 if ( theClass == null ) {
126 throw new JellyException( "Could not load class called: " + rootClass );
127 }
128 if ( path != null ) {
129 reader.registerBeanClass( path, theClass );
130 }
131 else {
132 reader.registerBeanClass( theClass );
133 }
134
135 Object value = null;
136 if ( uri != null ) {
137 invokeBody(output);
138
139 URL url = context.getResource( uri );
140 value = reader.parse( url.toString() );
141 }
142 else {
143
144 // invoke the body and pass that into the reader
145 XMLOutput newOutput = new XMLOutput( reader );
146
147 invokeBody(newOutput);
148
149 value = reader.getRoot();
150 }
151 context.setVariable( var, value );
152 }
153
154 // Properties
155 //-------------------------------------------------------------------------
156
157 /***
158 * @return the introspector to be used, lazily creating one if required.
159 */
160 public XMLIntrospector getIntrospector() {
161 if (introspector == null) {
162 introspector = new XMLIntrospector();
163 }
164 return introspector;
165 }
166 /***
167 * Sets the Betwixt XMLIntrospector instance used to define the metadata for how a
168 * bean should appear as XML.
169 */
170 public void setIntrospector(XMLIntrospector introspector) {
171 this.introspector = introspector;
172 }
173
174 /***
175 * Sets the URI from which XML is parsed. This can be relative to this Jelly script, use
176 * an absolute URI or a full URL
177 */
178 public void setUri(String uri) {
179 this.uri = uri;
180 }
181
182 /***
183 * Sets the variable name to output with the result of the XML parse.
184 */
185 public void setVar(String var) {
186 this.var = var;
187 }
188
189 /***
190 * Sets the name of the root class to use for parsing the XML
191 */
192 public void setRootClass(String rootClass) {
193 this.rootClass = rootClass;
194 }
195
196 /***
197 * Sets the path that the root class should be bound to.
198 * This is optional and often unnecessary though can be used to ignore some wrapping
199 * elements, such as the <rss> element in the RSS unit test.
200 */
201 public void setPath(String path) {
202 this.path = path;
203 }
204
205
206 /***
207 * Sets whether or not the current threads's context class loader
208 * should be used to load the bean classes or not.
209 * This can be useful if running inside a web application or inside some
210 * application server.
211 */
212 public void setUseContextClassLoader(boolean useContextClassLoader) {
213 this.useContextClassLoader = useContextClassLoader;
214 }
215
216 /***
217 * Sets the ClassLoader to be used to load bean classes from.
218 * If this is not specified then either the ClassLoader used to load this tag library
219 * is used or, if the 'useContextClassLoader' property is true, then the
220 * current threads context class loader is used instead.
221 */
222 public void setClassLoader(ClassLoader classLoader) {
223 this.classLoader = classLoader;
224 }
225
226
227 // Implementation methods
228 //-------------------------------------------------------------------------
229
230 /***
231 * @return the ClassLoader to be used to load bean classes.
232 */
233 protected ClassLoader getClassLoader() {
234 if ( classLoader != null ) {
235 return classLoader;
236 }
237 if ( useContextClassLoader ) {
238 return Thread.currentThread().getContextClassLoader();
239 }
240 else {
241 return getClass().getClassLoader();
242 }
243 }
244 }
This page was automatically generated by Maven