avalon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cziege...@apache.org
Subject cvs commit: jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/xml EntityResolver.java JaxpParser.java
Date Thu, 27 Dec 2001 15:00:32 GMT
cziegeler    01/12/27 07:00:32

  Modified:    src/scratchpad/org/apache/avalon/excalibur/xml
                        JaxpParser.java
  Added:       src/scratchpad/org/apache/avalon/excalibur/xml
                        EntityResolver.java
  Log:
  Updated parser and added EntityResolver Role
  
  Revision  Changes    Path
  1.6       +152 -47   jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/xml/JaxpParser.java
  
  Index: JaxpParser.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/xml/JaxpParser.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- JaxpParser.java	2001/12/11 09:53:38	1.5
  +++ JaxpParser.java	2001/12/27 15:00:32	1.6
  @@ -7,11 +7,12 @@
    */
   package org.apache.avalon.excalibur.xml;
   
  -import org.apache.avalon.excalibur.pool.Recyclable;
  -import org.apache.avalon.framework.configuration.Configurable;
  -import org.apache.avalon.framework.configuration.Configuration;
  -import org.apache.avalon.framework.configuration.ConfigurationException;
  +import org.apache.avalon.excalibur.pool.Poolable;
  +import org.apache.avalon.framework.component.ComponentException;
  +import org.apache.avalon.framework.component.ComponentManager;
  +import org.apache.avalon.framework.component.Composable;
   import org.apache.avalon.framework.logger.AbstractLogEnabled;
  +import org.apache.avalon.framework.parameters.Parameterizable;
   import org.apache.avalon.framework.parameters.Parameters;
   import org.w3c.dom.Document;
   import org.xml.sax.*;
  @@ -22,82 +23,192 @@
   
   /**
    * An XMLParser that is only dependant on JAXP 1.1 compliant parsers.
  - * If only we can get rid of the need for the Document...
    *
  + * The configuration can contain the following parameters :
  + * <ul>
  + * <li>validate (boolean, default = <code>false</code>) : should the
parser
  + *     validate parsed documents ?
  + * </li>
  + * <li>namespace-prefixes (boolean, default = <code>false</code>) : do
we want
  + *     namespaces declarations also as 'xmlns:' attributes ?<br>
  + *     <i>Note</i> : setting this to <code>true</code> confuses
some XSL
  + *     processors (e.g. Saxon).
  + * </li>
  + * <li>reuse-parsers (boolean, default = <code>true</code>) : do we want
to reuse
  + *     parsers or create a new parser for each parse ?<br>
  + *     <i>Note</i> : even if this parameter is <code>true</code>,
parsers are not
  + *     recycled in case of parsing errors : some parsers (e.g. Xerces) don't like
  + *     to be reused after failure.
  + * </li>
  + * </ul>
  + *
    * @author <a href="mailto:bloritsch@apache.org">Berin Loritsch</a>
    * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
  - * @version CVS $Revision: 1.5 $ $Date: 2001/12/11 09:53:38 $
  + * @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a>
  + * @version CVS $Revision: 1.6 $ $Date: 2001/12/27 15:00:32 $
    */
   public class JaxpParser
   extends AbstractLogEnabled
  -implements Parser, ErrorHandler, Configurable, Recyclable {
  +implements Parser, ErrorHandler, Composable, Parameterizable, Poolable {
   
       /** the SAX Parser factory */
       protected SAXParserFactory factory;
   
       /** the Document Builder factory */
  -    protected DocumentBuilderFactory docfactory;
  +    protected DocumentBuilderFactory docFactory;
  +
  +    /** The SAX reader. It is created lazily by {@link #setupXMLReader()}
  +        and cleared if a parsing error occurs. */
  +    protected XMLReader reader;
  +
  +    /** The DOM builder. It is created lazily by {@link #setupDocumentBuilder()}
  +        and cleared if a parsing error occurs. */
  +    protected DocumentBuilder docBuilder;
  +
  +    /** the component manager */
  +    protected ComponentManager manager;
  +
  +    /** the Entity Resolver */
  +    protected EntityResolver resolver;
  +
  +    /** do we want namespaces also as attributes ? */
  +    protected boolean nsPrefixes;
   
  +    /** do we want to reuse parsers ? */
  +    protected boolean reuseParsers;
  +
       /**
  +     * Get the Entity Resolver from the component manager
  +     */
  +    public void compose(ComponentManager manager)
  +    throws ComponentException {
  +        this.manager = manager;
  +        if ( this.manager.hasComponent(EntityResolver.ROLE) )
  +        {
  +            this.resolver = (EntityResolver)this.manager.lookup(EntityResolver.ROLE);
  +            if ( this.getLogger().isDebugEnabled() )
  +            {
  +                this.getLogger().debug("JaxpParser: Using EntityResolver: " + this.resolver);
  +            }
  +        }
  +    }
  +
  +    /**
        * Configure
        */
  -    public void configure(Configuration config)
  -    throws ConfigurationException {
  -        Parameters params = Parameters.fromConfiguration(config);
  +    public void parameterize( Parameters params )
  +    {
  +        // Validation and namespace prefixes parameters
           boolean validate = params.getParameterAsBoolean("validate", false);
  +        this.nsPrefixes = params.getParameterAsBoolean("namespace-prefixes", false);
  +        this.reuseParsers = params.getParameterAsBoolean("reuse-parsers", true);
  +
           this.factory = SAXParserFactory.newInstance();
  -        this.docfactory = DocumentBuilderFactory.newInstance();
           this.factory.setNamespaceAware(true);
           this.factory.setValidating(validate);
  -        this.docfactory.setNamespaceAware(true);
  -        this.docfactory.setValidating(validate);
  -    }
   
  -    public void parse(InputSource in, ContentHandler consumer)
  -    throws SAXException, IOException {
  -        SAXParser parser = null;
  -
  -        try {
  -            parser = this.factory.newSAXParser();
  -        } catch (ParserConfigurationException e) {
  -            getLogger().error("Cannot produce a valid parser", e);
  -            throw new SAXException("Could not get valid parser" + e.getMessage(), e);
  +        this.docFactory = DocumentBuilderFactory.newInstance();
  +        docFactory.setNamespaceAware(true);
  +        docFactory.setValidating(validate);
  +        if ( this.getLogger().isDebugEnabled() )
  +        {
  +            this.getLogger().debug("JaxpParser: validating: " + validate +
  +                                   ", namespace-prefixes: " + this.nsPrefixes +
  +                                   ", reuse parser: " + this.reuseParsers);
           }
  +    }
   
  -        XMLReader reader = parser.getXMLReader();
  +    public void parse(InputSource in, ContentHandler consumer)
  +    throws SAXException, IOException
  +    {
  +        this.setupXMLReader();
  +
  +        // Ensure we will use a fresh new parser at next parse in case of failure
  +        XMLReader tmpReader = this.reader;
  +        this.reader = null;
   
  -        reader.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
           try {
  -            if (consumer instanceof XMLConsumer
  -                || consumer instanceof LexicalHandler) {
  -                reader.setProperty("http://xml.org/sax/properties/lexical-handler",
  +            if (consumer instanceof LexicalHandler) {
  +                tmpReader.setProperty("http://xml.org/sax/properties/lexical-handler",
                           (LexicalHandler)consumer);
               }
           } catch (SAXException e) {
               getLogger().warn("SAX2 driver does not support property: "+
                                "'http://xml.org/sax/properties/lexical-handler'");
           }
  +
  +        tmpReader.setErrorHandler( this );
  +        tmpReader.setContentHandler( consumer );
  +        if ( null != this.resolver ) {
  +            tmpReader.setEntityResolver( this.resolver );
  +        }
  +
   
  -        reader.setErrorHandler(this);
  -        reader.setContentHandler(consumer);
  -        reader.parse(in);
  +        tmpReader.parse(in);
  +
  +        // Here, parsing was successful : restore this.reader
  +        if ( this.reuseParsers )
  +            this.reader = tmpReader;
       }
   
  +
       /**
        * Parses a new Document object from the given InputSource.
        */
  -    public Document parseDocument(InputSource input) throws SAXException, IOException {
  -      DocumentBuilder builder = null;
  -      try {
  -        builder = this.docfactory.newDocumentBuilder();
  -      } catch (ParserConfigurationException pce) {
  -        getLogger().error("Could not build DocumentBuilder", pce);
  -        return null;
  -      }
  -      return builder.parse(input);
  +    public Document parseDocument(InputSource input)
  +    throws SAXException, IOException
  +    {
  +        this.setupDocumentBuilder();
  +
  +        // Ensure we will use a fresh new parser at next parse in case of failure
  +        DocumentBuilder tmpBuilder = this.docBuilder;
  +        this.docBuilder = null;
  +
  +        if ( null != this.resolver ) {
  +            tmpBuilder.setEntityResolver(this.resolver);
  +        }
  +
  +        Document result = tmpBuilder.parse(input);
  +
  +        // Here, parsing was successful : restore this.builder
  +        if (this.reuseParsers)
  +            this.docBuilder = tmpBuilder;
  +
  +        return result;
       }
   
       /**
  +     * Creates a new <code>XMLReader</code> if needed.
  +     */
  +    protected void setupXMLReader() throws SAXException {
  +        if (this.reader == null) {
  +            // Create the XMLReader
  +            try {
  +                this.reader = factory.newSAXParser().getXMLReader();
  +                this.reader.setFeature("http://xml.org/sax/features/namespace-prefixes",
this.nsPrefixes);
  +            } catch(Exception e) {
  +                getLogger().error("Cannot produce a valid parser", e);
  +                throw new SAXException("Cannot produce a valid parser", e);
  +            }
  +        }
  +    }
  +
  +    /**
  +     * Creates a new <code>DocumentBuilder</code> if needed.
  +     */
  +    protected void setupDocumentBuilder() {
  +        if (this.docBuilder == null) {
  +            try {
  +                this.docBuilder = this.docFactory.newDocumentBuilder();
  +            } catch (ParserConfigurationException pce) {
  +                getLogger().error("Could not create DocumentBuilder", pce);
  +                throw new org.apache.avalon.framework.CascadingRuntimeException(
  +                    "Could not create DocumentBuilder", pce);
  +            }
  +        }
  +    }
  +
  +    /**
        * Receive notification of a recoverable error.
        */
       public void error(SAXParseException e)
  @@ -125,11 +236,5 @@
           throw new SAXException("Warning parsing "+e.getSystemId()+" (line "+
                                  e.getLineNumber()+" col. "+e.getColumnNumber()+
                                  "): "+e.getMessage(),e);
  -    }
  -
  -    /**
  -     * Recycle
  -     */
  -    public void recycle() {
       }
   }
  
  
  
  1.1                  jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/xml/EntityResolver.java
  
  Index: EntityResolver.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  package org.apache.avalon.excalibur.xml;
  
  import org.apache.avalon.framework.component.Component;
  import org.xml.sax.InputSource;
  import org.xml.sax.SAXException;
  
  import java.io.IOException;
  
  /**
   * A component that uses catalogs for resolving Entities.
   *
   * @author <a href="mailto:dims@yahoo.com">Davanum Srinivas</a>
   * @version CVS $Revision: 1.1 $ $Date: 2001/12/27 15:00:32 $
   */
  public interface EntityResolver
  extends Component, org.xml.sax.EntityResolver {
  
      String ROLE = "org.apache.avalon.excalibur.xml.EntityResolver";
  
      /**
       * Allow the application to resolve external entities.
       *
       * <p>The Parser will call this method before opening any external
       * entity except the top-level document entity (including the
       * external DTD subset, external entities referenced within the
       * DTD, and external entities referenced within the document
       * element): the application may request that the parser resolve
       * the entity itself, that it use an alternative URI, or that it
       * use an entirely different input source.</p>
       *
       * <p>Application writers can use this method to redirect external
       * system identifiers to secure and/or local URIs, to look up
       * public identifiers in a catalogue, or to read an entity from a
       * database or other input source (including, for example, a dialog
       * box).</p>
       *
       * <p>If the system identifier is a URL, the SAX parser must
       * resolve it fully before reporting it to the application.</p>
       *
       * @param publicId The public identifier of the external entity
       *        being referenced, or null if none was supplied.
       * @param systemId The system identifier of the external entity
       *        being referenced.
       * @return An InputSource object describing the new input source,
       *         or null to request that the parser open a regular
       *         URI connection to the system identifier.
       * @exception org.xml.sax.SAXException Any SAX exception, possibly
       *            wrapping another exception.
       * @exception java.io.IOException A Java-specific IO exception,
       *            possibly the result of creating a new InputStream
       *            or Reader for the InputSource.
       * @see org.xml.sax.InputSource
       */
      InputSource resolveEntity(String publicId,
                                String systemId)
      throws SAXException, IOException;
  }
  
  
  

--
To unsubscribe, e-mail:   <mailto:avalon-cvs-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:avalon-cvs-help@jakarta.apache.org>


Mime
View raw message