%line | %branch | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
org.apache.commons.jelly.tags.xml.TransformTag |
|
|
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.tags.xml; |
|
17 | ||
18 | import java.io.File; |
|
19 | import java.io.IOException; |
|
20 | import java.io.InputStream; |
|
21 | import java.io.Reader; |
|
22 | import java.io.StringReader; |
|
23 | import java.io.StringWriter; |
|
24 | import java.net.MalformedURLException; |
|
25 | import java.net.URL; |
|
26 | import java.util.Iterator; |
|
27 | import java.util.List; |
|
28 | ||
29 | import javax.xml.transform.Result; |
|
30 | import javax.xml.transform.Source; |
|
31 | import javax.xml.transform.TransformerConfigurationException; |
|
32 | import javax.xml.transform.TransformerException; |
|
33 | import javax.xml.transform.TransformerFactory; |
|
34 | import javax.xml.transform.URIResolver; |
|
35 | import javax.xml.transform.sax.SAXResult; |
|
36 | import javax.xml.transform.sax.SAXSource; |
|
37 | import javax.xml.transform.sax.SAXTransformerFactory; |
|
38 | import javax.xml.transform.sax.TransformerHandler; |
|
39 | import javax.xml.transform.stream.StreamSource; |
|
40 | ||
41 | import org.apache.commons.jelly.JellyContext; |
|
42 | import org.apache.commons.jelly.JellyException; |
|
43 | import org.apache.commons.jelly.JellyTagException; |
|
44 | import org.apache.commons.jelly.MissingAttributeException; |
|
45 | import org.apache.commons.jelly.Script; |
|
46 | import org.apache.commons.jelly.Tag; |
|
47 | import org.apache.commons.jelly.XMLOutput; |
|
48 | import org.apache.commons.jelly.impl.ScriptBlock; |
|
49 | import org.apache.commons.jelly.impl.StaticTagScript; |
|
50 | import org.apache.commons.jelly.impl.TagScript; |
|
51 | import org.apache.commons.jelly.impl.WeakReferenceWrapperScript; |
|
52 | import org.apache.commons.logging.Log; |
|
53 | import org.apache.commons.logging.LogFactory; |
|
54 | import org.dom4j.Document; |
|
55 | import org.dom4j.io.DocumentResult; |
|
56 | import org.dom4j.io.DocumentSource; |
|
57 | import org.xml.sax.ContentHandler; |
|
58 | import org.xml.sax.DTDHandler; |
|
59 | import org.xml.sax.EntityResolver; |
|
60 | import org.xml.sax.ErrorHandler; |
|
61 | import org.xml.sax.InputSource; |
|
62 | import org.xml.sax.SAXException; |
|
63 | import org.xml.sax.SAXNotRecognizedException; |
|
64 | import org.xml.sax.SAXNotSupportedException; |
|
65 | import org.xml.sax.XMLReader; |
|
66 | import org.xml.sax.ext.LexicalHandler; |
|
67 | import org.xml.sax.helpers.XMLReaderFactory; |
|
68 | ||
69 | /** A tag which parses some XML, applies an xslt transform to it |
|
70 | * and defines a variable with the transformed Document. |
|
71 | * The XML can either be specified as its body or can be passed in via the |
|
72 | * xml property which can be a Reader, InputStream, URL or String URI. |
|
73 | * |
|
74 | * The XSL can be passed in via the |
|
75 | * xslt property which can be a Reader, InputStream, URL or String URI. |
|
76 | * |
|
77 | * @author Robert Leftwich |
|
78 | * @version $Revision: 1.6 $ |
|
79 | */ |
|
80 | 8 | public class TransformTag extends ParseTag { |
81 | ||
82 | /** The Log to which logging calls will be made. */ |
|
83 | 4 | private static final Log log = LogFactory.getLog(TransformTag.class); |
84 | ||
85 | /** Propert name for lexical handler */ |
|
86 | private static final String LEXICAL_HANDLER_PROPERTY = |
|
87 | "http://xml.org/sax/properties/lexical-handler"; |
|
88 | ||
89 | /** The xslt to parse, either a String URI, a Reader or InputStream */ |
|
90 | private Object xslt; |
|
91 | ||
92 | /** The xsl transformer factory */ |
|
93 | private SAXTransformerFactory tf; |
|
94 | ||
95 | /** the transformer handler, doing the real work */ |
|
96 | private TransformerHandler transformerHandler; |
|
97 | ||
98 | /** |
|
99 | * Constructor for TransformTag. |
|
100 | */ |
|
101 | public TransformTag() { |
|
102 | 20 | super(); |
103 | 20 | this.tf = (SAXTransformerFactory) TransformerFactory.newInstance(); |
104 | 20 | } |
105 | ||
106 | // Tag interface |
|
107 | //------------------------------------------------------------------------- |
|
108 | ||
109 | /** |
|
110 | * Process this tag instance |
|
111 | * |
|
112 | * @param output The pipeline for xml events |
|
113 | * @throws Exception - when required attributes are missing |
|
114 | */ |
|
115 | public void doTag(XMLOutput output) throws MissingAttributeException, JellyTagException { |
|
116 | ||
117 | 16 | if (null == this.getXslt()) { |
118 | 0 | throw new MissingAttributeException("The xslt attribute cannot be null"); |
119 | } |
|
120 | ||
121 | // set a resolver to locate uri |
|
122 | 16 | this.tf.setURIResolver(createURIResolver()); |
123 | ||
124 | try { |
|
125 | 16 | this.transformerHandler = |
126 | this.tf.newTransformerHandler(class="keyword">this.getObjAsSAXSource(class="keyword">this.getXslt())); |
|
127 | 16 | } |
128 | catch (TransformerConfigurationException e) { |
|
129 | 0 | throw new JellyTagException(e); |
130 | } |
|
131 | ||
132 | // run any nested param tags |
|
133 | 16 | this.doNestedParamTag(output); |
134 | ||
135 | try { |
|
136 | // get a reader to provide SAX events to transformer |
|
137 | 16 | XMLReader xmlReader = this.createXMLReader(); |
138 | 16 | xmlReader.setContentHandler(this.transformerHandler); |
139 | 16 | xmlReader.setProperty(LEXICAL_HANDLER_PROPERTY, this.transformerHandler); |
140 | ||
141 | // handle result differently, depending on if var is specified |
|
142 | 16 | String varName = this.getVar(); |
143 | 16 | if (null == varName) { |
144 | // pass the result of the transform out as SAX events |
|
145 | 8 | this.transformerHandler.setResult(class="keyword">this.createSAXResult(output)); |
146 | 8 | xmlReader.parse(this.getXMLInputSource()); |
147 | } |
|
148 | else { |
|
149 | // pass the result of the transform out as a document |
|
150 | 8 | DocumentResult result = new DocumentResult(); |
151 | 8 | this.transformerHandler.setResult(result); |
152 | 8 | xmlReader.parse(this.getXMLInputSource()); |
153 | ||
154 | // output the result as a variable |
|
155 | 8 | Document transformedDoc = result.getDocument(); |
156 | 8 | this.context.setVariable(varName, transformedDoc); |
157 | } |
|
158 | 16 | } |
159 | catch (SAXException e) { |
|
160 | 0 | throw new JellyTagException(e); |
161 | } |
|
162 | catch (IOException e) { |
|
163 | 0 | throw new JellyTagException(e); |
164 | } |
|
165 | ||
166 | 16 | } |
167 | ||
168 | // Properties |
|
169 | //------------------------------------------------------------------------- |
|
170 | ||
171 | /** |
|
172 | * Gets the source of the XSL which is either a String URI, Reader or |
|
173 | * InputStream |
|
174 | * |
|
175 | * @returns xslt The source of the xslt |
|
176 | */ |
|
177 | public Object getXslt() { |
|
178 | 32 | return this.xslt; |
179 | } |
|
180 | ||
181 | /** |
|
182 | * Sets the source of the XSL which is either a String URI, Reader or |
|
183 | * InputStream |
|
184 | * |
|
185 | * @param xslt The source of the xslt |
|
186 | */ |
|
187 | public void setXslt(Object xslt) { |
|
188 | 16 | this.xslt = xslt; |
189 | 16 | } |
190 | ||
191 | public void setParameterValue(String name, Object value) { |
|
192 | 11 | this.transformerHandler.getTransformer().setParameter(name, value); |
193 | 11 | } |
194 | ||
195 | // Implementation methods |
|
196 | //------------------------------------------------------------------------- |
|
197 | ||
198 | /** |
|
199 | * Creates a new URI Resolver so that URIs inside the XSLT document can be |
|
200 | * resolved using the JellyContext |
|
201 | * |
|
202 | * @return a URI Resolver for the JellyContext |
|
203 | */ |
|
204 | protected URIResolver createURIResolver() { |
|
205 | 16 | return new URIResolver() { |
206 | public Source resolve(String href, String base) |
|
207 | throws TransformerException { |
|
208 | ||
209 | if (log.isDebugEnabled() ) { |
|
210 | log.debug( "base: " + base + " href: " + href ); |
|
211 | } |
|
212 | ||
213 | // pass if we don't have a systemId |
|
214 | if (null == href) |
|
215 | return null; |
|
216 | ||
217 | // @todo |
|
218 | // #### this is a pretty simplistic implementation. |
|
219 | // #### we should really handle this better such that if |
|
220 | // #### base is specified as an absolute URL |
|
221 | // #### we trim the end off it and append href |
|
222 | return new StreamSource(context.getResourceAsStream(href)); |
|
223 | } |
|
224 | }; |
|
225 | } |
|
226 | ||
227 | /** |
|
228 | * Factory method to create a new SAXResult for the given |
|
229 | * XMLOutput so that the output of an XSLT transform will go |
|
230 | * directly into the XMLOutput that we are given. |
|
231 | * |
|
232 | * @param output The destination of the transform output |
|
233 | * @return A SAXResult for the transfrom output |
|
234 | */ |
|
235 | protected Result createSAXResult(XMLOutput output) { |
|
236 | 8 | SAXResult result = new SAXResult(output); |
237 | 8 | result.setLexicalHandler(output); |
238 | 8 | return result; |
239 | } |
|
240 | ||
241 | /** |
|
242 | * Factory method to create a new XMLReader for this tag |
|
243 | * so that the input of the XSLT transform comes from |
|
244 | * either the xml var, the nested tag or the tag body. |
|
245 | * |
|
246 | * @return XMLReader for the transform input |
|
247 | * @throws SAXException |
|
248 | * If the value of the "org.xml.sax.driver" system property |
|
249 | * is null, or if the class cannot be loaded and instantiated. |
|
250 | */ |
|
251 | protected XMLReader createXMLReader() throws SAXException { |
|
252 | 16 | XMLReader xmlReader = null; |
253 | 16 | Object xmlReaderSourceObj = this.getXml(); |
254 | // if no xml source specified then get from body |
|
255 | // otherwise convert it to a SAX source |
|
256 | 16 | if (null == xmlReaderSourceObj) { |
257 | 12 | xmlReader = new TagBodyXMLReader(this); |
258 | } |
|
259 | else { |
|
260 | 4 | xmlReader = XMLReaderFactory.createXMLReader(); |
261 | } |
|
262 | ||
263 | 16 | return xmlReader; |
264 | } |
|
265 | ||
266 | /** |
|
267 | * Helper method to get the appropriate xml input source |
|
268 | * so that the input of the XSLT transform comes from |
|
269 | * either the xml var, the nested tag or the tag body. |
|
270 | * |
|
271 | * @return InputSource for the transform input |
|
272 | */ |
|
273 | protected InputSource getXMLInputSource() { |
|
274 | 16 | InputSource xmlInputSource = null; |
275 | 16 | Object xmlInputSourceObj = this.getXml(); |
276 | // if no xml source specified then get from tag body |
|
277 | // otherwise convert it to an input source |
|
278 | 16 | if (null == xmlInputSourceObj) { |
279 | 12 | xmlInputSource = new TagBodyInputSource(); |
280 | } else { |
|
281 | 4 | xmlInputSource = this.getInputSourceFromObj(xmlInputSourceObj); |
282 | } |
|
283 | 16 | return xmlInputSource; |
284 | } |
|
285 | ||
286 | /** |
|
287 | * Helper method to convert the specified object to a SAX source |
|
288 | * |
|
289 | * @return SAXSource from the source object or null |
|
290 | */ |
|
291 | protected SAXSource getObjAsSAXSource(Object saxSourceObj) { |
|
292 | 16 | SAXSource saxSource = null; |
293 | 16 | if (null != saxSourceObj) { |
294 | 16 | if (saxSourceObj instanceof Document) { |
295 | 4 | saxSource = new DocumentSource((Document) saxSourceObj); |
296 | } else { |
|
297 | 12 | InputSource xmlInputSource = |
298 | this.getInputSourceFromObj(saxSourceObj); |
|
299 | 12 | saxSource = new SAXSource(xmlInputSource); |
300 | } |
|
301 | } |
|
302 | ||
303 | 16 | return saxSource; |
304 | } |
|
305 | ||
306 | /** |
|
307 | * Helper method to get an xml input source for the supplied object |
|
308 | * |
|
309 | * @return InputSource for the object or null |
|
310 | */ |
|
311 | protected InputSource getInputSourceFromObj(Object sourceObj ) { |
|
312 | 16 | InputSource xmlInputSource = null; |
313 | 16 | if (sourceObj instanceof Document) { |
314 | 0 | SAXSource saxSource = new DocumentSource((Document) sourceObj); |
315 | 0 | xmlInputSource = saxSource.getInputSource(); |
316 | } else { |
|
317 | 16 | if (sourceObj instanceof String) { |
318 | 16 | String uri = (String) sourceObj; |
319 | 16 | xmlInputSource = new InputSource(context.getResourceAsStream(uri)); |
320 | } |
|
321 | 0 | else if (sourceObj instanceof Reader) { |
322 | 0 | xmlInputSource = new InputSource((Reader) sourceObj); |
323 | } |
|
324 | 0 | else if (sourceObj instanceof InputStream) { |
325 | 0 | xmlInputSource = new InputSource((InputStream) sourceObj); |
326 | } |
|
327 | 0 | else if (sourceObj instanceof URL) { |
328 | 0 | String uri = ((URL) sourceObj).toString(); |
329 | 0 | xmlInputSource = new InputSource(context.getResourceAsStream(uri)); |
330 | } |
|
331 | 0 | else if (sourceObj instanceof File) { |
332 | try { |
|
333 | 0 | String uri = ((File) sourceObj).toURL().toString(); |
334 | 0 | xmlInputSource = new InputSource(context.getResourceAsStream(uri)); |
335 | 0 | } |
336 | catch (MalformedURLException e) { |
|
337 | 0 | throw new IllegalArgumentException( |
338 | "This should never occur. We should always be able to convert a File to a URL" + e ); |
|
339 | 0 | } |
340 | } |
|
341 | else { |
|
342 | 0 | throw new IllegalArgumentException( |
343 | "Invalid source argument. Must be a String, Reader, InputStream or URL." |
|
344 | + " Was type; " |
|
345 | + sourceObj.getClass().getName() |
|
346 | + " with value: " |
|
347 | + sourceObj); |
|
348 | } |
|
349 | } |
|
350 | ||
351 | 16 | return xmlInputSource; |
352 | } |
|
353 | ||
354 | /** |
|
355 | * Helper method to run any nested param tags |
|
356 | * |
|
357 | * @param output The destination for any SAX output (not actually used) |
|
358 | */ |
|
359 | private void doNestedParamTag(XMLOutput output) throws JellyTagException { |
|
360 | // find any nested param tags and run them |
|
361 | 16 | Script bodyScript = this.getBody(); |
362 | ||
363 | 16 | if (bodyScript instanceof WeakReferenceWrapperScript) { |
364 | 16 | WeakReferenceWrapperScript wrws = (WeakReferenceWrapperScript) bodyScript; |
365 | 16 | invokeNestedTagsOfType(wrws, ParamTag.class,context,output); |
366 | 0 | }else if (bodyScript instanceof ScriptBlock) { |
367 | 0 | ScriptBlock scriptBlock = (ScriptBlock) bodyScript; |
368 | 0 | List scriptList = scriptBlock.getScriptList(); |
369 | 0 | for (Iterator iter = scriptList.iterator(); iter.hasNext(); ) { |
370 | 0 | Script script = (Script) iter.next(); |
371 | 0 | if (script instanceof TagScript) { |
372 | ||
373 | 0 | Tag tag = null; |
374 | try { |
|
375 | 0 | tag = ((TagScript) script).getTag(); |
376 | 0 | } catch (JellyException e) { |
377 | 0 | throw new JellyTagException(e); |
378 | } |
|
379 | ||
380 | 0 | if (tag instanceof ParamTag) { |
381 | 0 | script.run(context, output); |
382 | } |
|
383 | ||
384 | ||
385 | } |
|
386 | } |
|
387 | } |
|
388 | 16 | } |
389 | ||
390 | /** Locates all child TagScripts, whose tags are of the type |
|
391 | * given. These tags are executed with the provided JellyContext and output. |
|
392 | * <p/> |
|
393 | * <strong>This method is in place |
|
394 | * to support specific features in the XML tag library and |
|
395 | * shouldn't be used by anyone at all. |
|
396 | * This method will be removed in a near-future verison of jelly.</strong> |
|
397 | * <p/> |
|
398 | * |
|
399 | * XXX if possible, this is actually more bogus than "containsScriptType", it must be removed ASAP |
|
400 | * |
|
401 | * @param clazz Execute all child tags of this type |
|
402 | * @param output The output to use when executing the tags. |
|
403 | * @throws JellyTagException |
|
404 | */ |
|
405 | public void invokeNestedTagsOfType(WeakReferenceWrapperScript wrws, Class clazz, JellyContext context, XMLOutput output) throws JellyTagException { |
|
406 | 16 | Object bodyScript = wrws.script(); |
407 | ||
408 | 16 | if (bodyScript instanceof ScriptBlock) { |
409 | 16 | ScriptBlock scriptBlock = (ScriptBlock) bodyScript; |
410 | 16 | List scriptList = scriptBlock.getScriptList(); |
411 | 50 | for (Iterator iter = scriptList.iterator(); iter.hasNext(); ) { |
412 | 18 | Script script = (Script) iter.next(); |
413 | 18 | if (script instanceof TagScript) { |
414 | ||
415 | 18 | Tag tag = null; |
416 | try { |
|
417 | 18 | tag = ((TagScript) script).getTag(); |
418 | 18 | } catch (JellyException e) { |
419 | 0 | throw new JellyTagException(e); |
420 | } |
|
421 | ||
422 | 18 | if (tag instanceof ParamTag) { |
423 | 6 | script.run(context, output); |
424 | } |
|
425 | } // instanceof |
|
426 | } // for |
|
427 | } // if |
|
428 | 16 | } |
429 | ||
430 | ||
431 | /** A helper class that converts a transform tag body to an XMLReader |
|
432 | * to hide the details of where the input for the transform is obtained |
|
433 | * |
|
434 | * @author <a href="mailto:robert@leftwich.info">Robert Leftwich</a> |
|
435 | * @version $Revision: 1.6 $ |
|
436 | */ |
|
437 | private class TagBodyXMLReader implements XMLReader { |
|
438 | ||
439 | /** The tag whose body is to be read. */ |
|
440 | private Tag tag; |
|
441 | ||
442 | /** The destination for the sax events generated by the reader. */ |
|
443 | private XMLOutput xmlOutput; |
|
444 | ||
445 | /** Storage for a DTDHandler if set by the user of the reader. */ |
|
446 | private DTDHandler dtdHandler; |
|
447 | ||
448 | /** Storage for a ErrorHandler if set by the user of the reader. */ |
|
449 | private ErrorHandler errorHandler; |
|
450 | ||
451 | /** Storage for a EntityResolver if set by the user of the reader. */ |
|
452 | private EntityResolver entityResolver; |
|
453 | ||
454 | /** |
|
455 | * Construct an XMLReader for the specified Tag |
|
456 | * |
|
457 | * @param tag The Tag to convert to an XMLReader |
|
458 | */ |
|
459 | public TagBodyXMLReader(Tag tag) |
|
460 | { |
|
461 | this.tag = tag; |
|
462 | this.xmlOutput = new XMLOutput(); |
|
463 | } |
|
464 | ||
465 | // Methods |
|
466 | //------------------------------------------------------------------------- |
|
467 | ||
468 | /** |
|
469 | * Parse an XML source. |
|
470 | * |
|
471 | * @param input The source of the xml |
|
472 | * @throws SAXException - |
|
473 | * Any SAX exception, possibly wrapping another exception. |
|
474 | * @throws IOException - |
|
475 | * An IO exception from the parser, possibly from a byte |
|
476 | stream or character stream supplied by the application. |
|
477 | */ |
|
478 | public void parse(InputSource input) |
|
479 | throws IOException, SAXException |
|
480 | { |
|
481 | // safety check that we are being used correctly |
|
482 | if (input instanceof TagBodyInputSource) { |
|
483 | this.doInvokeBody(); |
|
484 | } else { |
|
485 | throw new SAXException("Invalid input source"); |
|
486 | } |
|
487 | } |
|
488 | ||
489 | /** |
|
490 | * Parse an XML source specified by a system id |
|
491 | * |
|
492 | * @param input The system identifier (URI) |
|
493 | * @throws SAXException - |
|
494 | * Any SAX exception, possibly wrapping another exception. |
|
495 | * @throws IOException - |
|
496 | * An IO exception from the parser, possibly from a byte |
|
497 | stream or character stream supplied by the application. |
|
498 | */ |
|
499 | public void parse(String systemId) |
|
500 | throws IOException, SAXException |
|
501 | { |
|
502 | this.doInvokeBody(); |
|
503 | } |
|
504 | ||
505 | // Helper methods |
|
506 | //------------------------------------------------------------------------- |
|
507 | ||
508 | /** |
|
509 | * Actually invoke the tag body to generate the SAX events |
|
510 | * |
|
511 | * @throws SAXException - |
|
512 | * Any SAX exception, possibly wrapping another exception. |
|
513 | */ |
|
514 | private void doInvokeBody() throws SAXException { |
|
515 | try { |
|
516 | if (this.shouldParseBody()) { |
|
517 | XMLReader anXMLReader = XMLReaderFactory.createXMLReader(); |
|
518 | anXMLReader.setContentHandler(this.xmlOutput); |
|
519 | anXMLReader.setProperty(LEXICAL_HANDLER_PROPERTY,this.xmlOutput); |
|
520 | StringWriter writer = new StringWriter(); |
|
521 | this.tag.invokeBody(XMLOutput.createXMLOutput(writer)); |
|
522 | Reader reader = new StringReader(writer.toString()); |
|
523 | anXMLReader.parse(new InputSource(reader)); |
|
524 | } else { |
|
525 | this.tag.invokeBody(class="keyword">this.xmlOutput); |
|
526 | } |
|
527 | } catch (Exception ex) { |
|
528 | throw new SAXException(ex); |
|
529 | } |
|
530 | } |
|
531 | ||
532 | /** |
|
533 | * Helper method to determin if nested body needs to be parsed by (an |
|
534 | * xml parser, i.e. its only text) to generate SAX events or not |
|
535 | * |
|
536 | * @return True if tag body should be parsed or false if invoked only |
|
537 | * @throws JellyTagException |
|
538 | */ |
|
539 | private boolean shouldParseBody() throws JellyTagException { |
|
540 | boolean result = false; |
|
541 | // check to see if we need to parse the body or just invoke it |
|
542 | Script bodyScript = this.tag.getBody(); |
|
543 | ||
544 | if (bodyScript instanceof WeakReferenceWrapperScript) { |
|
545 | WeakReferenceWrapperScript wrws = (WeakReferenceWrapperScript) bodyScript; |
|
546 | return wrws.containsScriptType(StaticTagScript.class); |
|
547 | } |
|
548 | ||
549 | if (bodyScript instanceof ScriptBlock) { |
|
550 | ScriptBlock scriptBlock = (ScriptBlock) bodyScript; |
|
551 | List scriptList = scriptBlock.getScriptList(); |
|
552 | for (Iterator iter = scriptList.iterator(); iter.hasNext(); ) { |
|
553 | Script script = (Script) iter.next(); |
|
554 | if (script instanceof StaticTagScript) { |
|
555 | result = true; |
|
556 | break; |
|
557 | } |
|
558 | } |
|
559 | } |
|
560 | return result; |
|
561 | } |
|
562 | ||
563 | // Properties |
|
564 | //------------------------------------------------------------------------- |
|
565 | ||
566 | /** |
|
567 | * Gets the SAX ContentHandler to feed SAX events into |
|
568 | * |
|
569 | * @return the SAX ContentHandler to use to feed SAX events into |
|
570 | */ |
|
571 | public ContentHandler getContentHandler() { |
|
572 | return this.xmlOutput.getContentHandler(); |
|
573 | } |
|
574 | ||
575 | /** |
|
576 | * Sets the SAX ContentHandler to feed SAX events into |
|
577 | * |
|
578 | * @param contentHandler is the ContentHandler to use. |
|
579 | * This value cannot be null. |
|
580 | */ |
|
581 | public void setContentHandler(ContentHandler contentHandler) { |
|
582 | this.xmlOutput.setContentHandler(contentHandler); |
|
583 | // often classes will implement LexicalHandler as well |
|
584 | if (contentHandler instanceof LexicalHandler) { |
|
585 | this.xmlOutput.setLexicalHandler((LexicalHandler) contentHandler); |
|
586 | } |
|
587 | } |
|
588 | ||
589 | /** |
|
590 | * Gets the DTD Handler to feed SAX events into |
|
591 | * |
|
592 | * @return the DTD Handler to use to feed SAX events into |
|
593 | */ |
|
594 | public DTDHandler getDTDHandler() { |
|
595 | return this.dtdHandler; |
|
596 | } |
|
597 | ||
598 | /** |
|
599 | * Sets the DTD Handler to feed SAX events into |
|
600 | * |
|
601 | * @param the DTD Handler to use to feed SAX events into |
|
602 | */ |
|
603 | public void setDTDHandler(DTDHandler dtdHandler) { |
|
604 | this.dtdHandler = dtdHandler; |
|
605 | } |
|
606 | ||
607 | /** |
|
608 | * Gets the Error Handler to feed SAX events into |
|
609 | * |
|
610 | * @return the Error Handler to use to feed SAX events into |
|
611 | */ |
|
612 | public ErrorHandler getErrorHandler() { |
|
613 | return this.errorHandler; |
|
614 | } |
|
615 | ||
616 | /** |
|
617 | * Sets the Error Handler to feed SAX events into |
|
618 | * |
|
619 | * @param the Error Handler to use to feed SAX events into |
|
620 | */ |
|
621 | public void setErrorHandler(ErrorHandler errorHandler) { |
|
622 | // save the error handler |
|
623 | this.errorHandler = errorHandler; |
|
624 | } |
|
625 | ||
626 | /** |
|
627 | * Gets the Entity Resolver to feed SAX events into |
|
628 | * |
|
629 | * @return the Entity Resolver to use to feed SAX events into |
|
630 | */ |
|
631 | public EntityResolver getEntityResolver() { |
|
632 | return this.entityResolver; |
|
633 | } |
|
634 | ||
635 | /** |
|
636 | * Sets the Entity Resolver to feed SAX events into |
|
637 | * |
|
638 | * @param the Entity Resolver to use to feed SAX events into |
|
639 | */ |
|
640 | public void setEntityResolver(EntityResolver entityResolver) { |
|
641 | this.entityResolver = entityResolver; |
|
642 | } |
|
643 | ||
644 | /** |
|
645 | * Lookup the value of a property |
|
646 | * |
|
647 | * @param name - The property name, which is a fully-qualified URI. |
|
648 | * @return - The current value of the property. |
|
649 | * @throws SAXNotRecognizedException - |
|
650 | * When the XMLReader does not recognize the property name. |
|
651 | * @throws SAXNotSupportedException - |
|
652 | * When the XMLReader recognizes the property name but |
|
653 | * cannot determine its value at this time. |
|
654 | */ |
|
655 | public Object getProperty(String name) |
|
656 | throws SAXNotRecognizedException, SAXNotSupportedException |
|
657 | { |
|
658 | // respond to the lexical handler request |
|
659 | if (name.equalsIgnoreCase(LEXICAL_HANDLER_PROPERTY)) { |
|
660 | return this.xmlOutput.getLexicalHandler(); |
|
661 | } else { |
|
662 | // do nothing |
|
663 | return null; |
|
664 | } |
|
665 | } |
|
666 | ||
667 | /** |
|
668 | * Set the value of a property |
|
669 | * |
|
670 | * @param name - The property name, which is a fully-qualified URI. |
|
671 | * @param value - The property value |
|
672 | * @throws SAXNotRecognizedException - |
|
673 | * When the XMLReader does not recognize the property name. |
|
674 | * @throws SAXNotSupportedException - |
|
675 | * When the XMLReader recognizes the property name but |
|
676 | * cannot determine its value at this time. |
|
677 | */ |
|
678 | public void setProperty(String name, Object value) |
|
679 | throws SAXNotRecognizedException, SAXNotSupportedException |
|
680 | { |
|
681 | // respond to the lexical handler setting |
|
682 | if (name.equalsIgnoreCase(LEXICAL_HANDLER_PROPERTY)) { |
|
683 | this.xmlOutput.setLexicalHandler((LexicalHandler) value); |
|
684 | } |
|
685 | } |
|
686 | ||
687 | /** |
|
688 | * Lookup the value of a feature |
|
689 | * |
|
690 | * @param name - The feature name, which is a fully-qualified URI. |
|
691 | * @return - The current state of the feature (true or false) |
|
692 | * @throws SAXNotRecognizedException - |
|
693 | * When the XMLReader does not recognize the feature name. |
|
694 | * @throws SAXNotSupportedException - |
|
695 | * When the XMLReader recognizes the feature name but |
|
696 | * cannot determine its value at this time. |
|
697 | */ |
|
698 | public boolean getFeature(String name) |
|
699 | throws SAXNotRecognizedException, SAXNotSupportedException |
|
700 | { |
|
701 | // do nothing |
|
702 | return false; |
|
703 | } |
|
704 | ||
705 | /** |
|
706 | * Set the value of a feature |
|
707 | * |
|
708 | * @param name - The feature name, which is a fully-qualified URI. |
|
709 | * @param value - The current state of the feature (true or false) |
|
710 | * @throws SAXNotRecognizedException - |
|
711 | * When the XMLReader does not recognize the feature name. |
|
712 | * @throws SAXNotSupportedException - |
|
713 | * When the XMLReader recognizes the feature name but |
|
714 | * cannot determine its value at this time. |
|
715 | */ |
|
716 | public void setFeature(String name, boolean value) |
|
717 | throws SAXNotRecognizedException, SAXNotSupportedException |
|
718 | { |
|
719 | // do nothing |
|
720 | } |
|
721 | } |
|
722 | ||
723 | /** A marker class used by the TagBodyXMLReader as a sanity check |
|
724 | * (i.e. The source is not actually used) |
|
725 | * |
|
726 | */ |
|
727 | private class TagBodyInputSource extends InputSource { |
|
728 | ||
729 | /** |
|
730 | * Construct an instance of this marker class |
|
731 | */ |
|
732 | public TagBodyInputSource() { |
|
733 | } |
|
734 | } |
|
735 | ||
736 | } |
This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |