cocoon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cziege...@apache.org
Subject svn commit: r123778 - /cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceManager.java /cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ConfigurationBuilder.java
Date Fri, 31 Dec 2004 10:10:30 GMT
Author: cziegeler
Date: Fri Dec 31 02:10:27 2004
New Revision: 123778

URL: http://svn.apache.org/viewcvs?view=rev&rev=123778
Log:
Add our own configuration builder - not used yet
Added:
   cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ConfigurationBuilder.java 
 (contents, props changed)
Modified:
   cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceManager.java

Modified: cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceManager.java
Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceManager.java?view=diff&rev=123778&p1=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceManager.java&r1=123777&p2=cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceManager.java&r2=123778
==============================================================================
--- cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceManager.java
(original)
+++ cocoon/trunk/src/core/java/org/apache/cocoon/core/container/CocoonServiceManager.java
Fri Dec 31 02:10:27 2004
@@ -17,7 +17,6 @@
 package org.apache.cocoon.core.container;
 
 import java.io.IOException;
-import java.net.MalformedURLException;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Iterator;

Added: cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ConfigurationBuilder.java
Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ConfigurationBuilder.java?view=auto&rev=123778
==============================================================================
--- (empty file)
+++ cocoon/trunk/src/core/java/org/apache/cocoon/core/container/ConfigurationBuilder.java
Fri Dec 31 02:10:27 2004
@@ -0,0 +1,378 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cocoon.core.container;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.Iterator;
+
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.configuration.DefaultConfiguration;
+import org.xml.sax.Attributes;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.AttributesImpl;
+import org.xml.sax.helpers.DefaultHandler;
+import org.xml.sax.helpers.NamespaceSupport;
+
+/**
+ * A ConfigurationBuilder builds {@link Configuration}s from XML,
+ * via a SAX2 compliant parser.
+ *
+ * <p>
+ * The mapping from XML namespaces to {@link Configuration} namespaces is pretty
+ * straightforward, with one caveat: attribute namespaces are (deliberately) not
+ * supported. Enabling namespace processing has the following effects:</p>
+ * <ul>
+ *  <li>Attributes starting with <code>xmlns:</code> are interpreted as
+ *  declaring a prefix:namespaceURI mapping, and won't result in the creation of
+ *  <code>xmlns</code>-prefixed attributes in the <code>Configuration</code>.
+ *  </li>
+ *  <li>
+ *  Prefixed XML elements, like <tt>&lt;doc:title xmlns:doc="http://foo.com"&gt;,</tt>
+ *  will result in a <code>Configuration</code> with <code>{@link
+ *  Configuration#getName getName()}.equals("title")</code> and <code>{@link
+ *  Configuration#getNamespace getNamespace()}.equals("http://foo.com")</code>.
+ *  </li>
+ * </ul>
+ * <p>
+ * Whitespace handling. Since mixed content is not allowed in the
+ * configurations, whitespace is completely discarded in non-leaf nodes.
+ * For the leaf nodes the default behavior is to trim the space
+ * surrounding the value. This can be changed by specifying
+ * <code>xml:space</code> attribute with value of <code>preserve</code>
+ * in that case the whitespace is left intact.
+ * </p>
+ *
+ * @version CVS $Revision: 1.33 $ $Date: 2004/04/03 23:55:54 $
+ */
+public class ConfigurationBuilder
+    extends DefaultHandler
+    implements ErrorHandler {
+    
+    private XMLReader parser;
+    
+    /**
+     * Likely number of nested configuration items. If more is
+     * encountered the lists will grow automatically.
+     */
+    private static final int EXPECTED_DEPTH = 4;
+    private final ArrayList elements = new ArrayList( EXPECTED_DEPTH );
+    private final ArrayList prefixes = new ArrayList( EXPECTED_DEPTH );
+    private final ArrayList values = new ArrayList( EXPECTED_DEPTH );
+    
+    /**
+     * Contains true at index n if space in the configuration with
+     * depth n is to be preserved.
+     */
+    private final BitSet preserveSpace = new BitSet();
+    private Configuration configuration;
+    private Locator locator;
+    private final NamespaceSupport namespaceSupport = new NamespaceSupport();
+
+    /**
+     * Create a Configuration Builder
+     */
+    public ConfigurationBuilder() {
+        try {
+            final SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
+
+            saxParserFactory.setNamespaceAware( true );
+
+            final SAXParser saxParser = saxParserFactory.newSAXParser();
+
+            this.parser = saxParser.getXMLReader();
+
+            this.parser.setContentHandler( this );
+            this.parser.setErrorHandler( this );
+        } catch( final Exception se ) {
+            throw new Error( "Unable to setup SAX parser" + se );
+        }
+    }
+
+    /**
+     * Build a configuration object using an XML InputSource object
+     * @param input an <code>InputSource</code> value
+     * @return a <code>Configuration</code> object
+     * @throws SAXException if a parsing error occurs
+     * @throws IOException if an I/O error occurs
+     * @throws ConfigurationException if an error occurs
+     */
+    public Configuration build( final InputSource input )
+    throws SAXException, IOException, ConfigurationException {
+        synchronized( this ) {
+            this.clear();
+            this.parser.parse( input );
+            return this.configuration;
+        }
+    }
+
+    /**
+     * Sets the <code>EntityResolver</code> to 
+     * be used by parser. Useful when dealing with xml
+     * files that reference external entities.
+     * 
+     * @param resolver implementation of <code>EntityResolver</code>
+     */
+    public void setEntityResolver( final EntityResolver resolver ) {
+        this.parser.setEntityResolver( resolver );
+    }
+
+    /**
+     * Clears all data from this configuration handler.
+     */
+    protected void clear() {
+        this.elements.clear();
+        Iterator i = this.prefixes.iterator();
+        while( i.hasNext() ) {
+            ( (ArrayList)i.next() ).clear();
+        }
+        this.prefixes.clear();
+        this.values.clear();
+        this.locator = null;
+    }
+
+    /* (non-Javadoc)
+     * @see org.xml.sax.ContentHandler#setDocumentLocator(org.xml.sax.Locator)
+     */
+    public void setDocumentLocator( final Locator locator ) {
+        this.locator = locator;
+    }
+
+    /* (non-Javadoc)
+     * @see org.xml.sax.ContentHandler#startDocument()
+     */
+    public void startDocument()
+    throws SAXException {
+        this.namespaceSupport.reset();
+        super.startDocument();
+    }
+
+    /* (non-Javadoc)
+     * @see org.xml.sax.ContentHandler#endDocument()
+     */
+    public void endDocument()
+    throws SAXException {
+        super.endDocument();
+        this.namespaceSupport.reset();
+    }
+
+    /* (non-Javadoc)
+     * @see org.xml.sax.ContentHandler#characters(char[], int, int)
+     */
+    public void characters( final char[] ch, int start, int end )
+    throws SAXException {
+        // it is possible to play micro-optimization here by doing
+        // manual trimming and thus preserve some precious bits
+        // of memory, but it's really not important enough to justify
+        // resulting code complexity
+        final int depth = this.values.size() - 1;
+        final StringBuffer valueBuffer = (StringBuffer)this.values.get( depth );
+        valueBuffer.append( ch, start, end );
+    }
+
+    /* (non-Javadoc)
+     * @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
+     */
+    public void endElement( final String namespaceURI,
+                            final String localName,
+                            final String rawName )
+    throws SAXException {
+        final int depth = this.elements.size() - 1;
+        final DefaultConfiguration finishedConfiguration =
+        (DefaultConfiguration)this.elements.remove( depth );
+        final String accumulatedValue =
+        ( (StringBuffer)this.values.remove( depth ) ).toString();
+        final ArrayList prefixes = (ArrayList)this.prefixes.remove( depth );
+
+        final Iterator i = prefixes.iterator();
+        while( i.hasNext() ) {
+            endPrefixMapping( (String)i.next() );
+        }
+        prefixes.clear();
+
+        if( finishedConfiguration.getChildren().length == 0 ) {
+            // leaf node
+            String finishedValue;
+            if( this.preserveSpace.get( depth ) ) {
+                finishedValue = accumulatedValue;
+            } else if( 0 == accumulatedValue.length() ) {
+                finishedValue = null;
+            } else {
+                finishedValue = accumulatedValue.trim();
+            }
+            finishedConfiguration.setValue( finishedValue );
+        } else {
+            final String trimmedValue = accumulatedValue.trim();
+            if( trimmedValue.length() > 0 ) {
+                throw new SAXException( "Not allowed to define mixed content in the " 
+                        + "element " + finishedConfiguration.getName() + " at "
+                        + finishedConfiguration.getLocation() );
+            }
+        }
+
+        if( 0 == depth ) {
+            this.configuration = finishedConfiguration;
+        }
+        this.namespaceSupport.popContext();
+    }
+
+    /**
+     * Create a new <code>DefaultConfiguration</code> with the specified
+     * local name, namespace, and location.
+     *
+     * @param localName a <code>String</code> value
+     * @param namespaceURI a <code>String</code> value
+     * @param location a <code>String</code> value
+     * @return a <code>DefaultConfiguration</code> value
+     */
+    protected DefaultConfiguration createConfiguration( final String localName,
+                                                        final String namespaceURI,
+                                                        final String location ) {
+        String prefix = this.namespaceSupport.getPrefix( namespaceURI );
+        if( prefix == null ) {
+            prefix = "";
+        }
+        return new DefaultConfiguration( localName, location, namespaceURI, prefix );
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String,
org.xml.sax.Attributes)
+     */
+    public void startElement( final String namespaceURI,
+                              final String localName,
+                              final String rawName,
+                              final Attributes attributes )
+    throws SAXException {
+        this.namespaceSupport.pushContext();
+        final DefaultConfiguration configuration =
+            createConfiguration( localName, namespaceURI, getLocationString() );
+        // depth of new configuration (not decrementing here, configuration
+        // is to be added)
+        final int depth = this.elements.size();
+        boolean preserveSpace = false; // top level element trims space by default
+
+        if( depth > 0 ) {
+            final DefaultConfiguration parent =
+                (DefaultConfiguration)this.elements.get( depth - 1 );
+            parent.addChild( configuration );
+            // inherits parent's space preservation policy
+            preserveSpace = this.preserveSpace.get( depth - 1 );
+        }
+
+        this.elements.add( configuration );
+        this.values.add( new StringBuffer() );
+
+        final ArrayList prefixes = new ArrayList();
+        AttributesImpl componentAttr = new AttributesImpl();
+
+        for( int i = 0; i < attributes.getLength(); i++ ) {
+            if( attributes.getQName( i ).startsWith( "xmlns" ) )
+            {
+                prefixes.add( attributes.getLocalName( i ) );
+                this.startPrefixMapping( attributes.getLocalName( i ),
+                                         attributes.getValue( i ) );
+            } else if( attributes.getQName( i ).equals( "xml:space" ) ) {
+                preserveSpace = attributes.getValue( i ).equals( "preserve" );
+            } else {
+                componentAttr.addAttribute( attributes.getURI( i ),
+                                            attributes.getLocalName( i ),
+                                            attributes.getQName( i ),
+                                            attributes.getType( i ),
+                                            attributes.getValue( i ) );
+            }
+        }
+
+        if( preserveSpace ) {
+            this.preserveSpace.set( depth );
+        } else {
+            this.preserveSpace.clear( depth );
+        }
+
+        this.prefixes.add( prefixes );
+
+        final int attributesSize = componentAttr.getLength();
+
+        for( int i = 0; i < attributesSize; i++ ) {
+            final String name = componentAttr.getQName( i );
+            final String value = componentAttr.getValue( i );
+            configuration.setAttribute( name, value );
+        }
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException)
+     */
+    public void error( final SAXParseException exception )
+    throws SAXException {
+        throw exception;
+    }
+
+    /* (non-Javadoc)
+     * @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException)
+     */
+    public void warning( final SAXParseException exception )
+    throws SAXException {
+        throw exception;
+    }
+
+    /* (non-Javadoc)
+     * @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException)
+     */
+    public void fatalError( final SAXParseException exception )
+    throws SAXException {
+        throw exception;
+    }
+
+    /**
+     * Returns a string showing the current system ID, line number and column number.
+     *
+     * @return a <code>String</code> value
+     */
+    private String getLocationString() {
+        if( null == this.locator ) {
+            return "Unknown";
+        } else {
+            final int columnNumber = this.locator.getColumnNumber();
+            return
+            this.locator.getSystemId() + ":"
+                + this.locator.getLineNumber()
+                + ( columnNumber >= 0 ? ( ":" + columnNumber ) : "" );
+        }
+    }
+    
+    /* (non-Javadoc)
+     * @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String, java.lang.String)
+     */
+    public void startPrefixMapping( String prefix, String uri )
+    throws SAXException {
+        this.namespaceSupport.declarePrefix( prefix, uri );
+        super.startPrefixMapping( prefix, uri );
+    }
+
+}

Mime
View raw message