Coverage report

  %line %branch
org.apache.commons.jelly.tags.xml.TransformTag
70% 
91% 

 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.