geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From djen...@apache.org
Subject svn commit: r821961 [25/30] - in /geronimo/sandbox/djencks/osgi/framework: ./ buildsupport/ buildsupport/car-maven-plugin/ buildsupport/car-maven-plugin/src/main/java/org/apache/geronimo/mavenplugins/car/ buildsupport/geronimo-maven-plugin/src/main/jav...
Date Mon, 05 Oct 2009 18:54:56 GMT
Added: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlStreamReader.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlStreamReader.java?rev=821961&view=auto
==============================================================================
--- geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlStreamReader.java (added)
+++ geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlStreamReader.java Mon Oct  5 18:54:50 2009
@@ -0,0 +1,270 @@
+/*
+ * Copyright 2004 Sun Microsystems, Inc.
+ *
+ * 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.geronimo.system.plugin.plexus.util.xml;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+
+/**
+ * Character stream that handles (or at least attemtps to) all the necessary Voodo to figure out the charset encoding of
+ * the XML document within the stream.
+ * <p>
+ * IMPORTANT: This class is not related in any way to the org.xml.sax.XMLReader. This one IS a character stream.
+ * <p>
+ * All this has to be done without consuming characters from the stream, if not the XML parser will not recognized the
+ * document as a valid XML. This is not 100% true, but it's close enough (UTF-8 BOM is not handled by all parsers right
+ * now, XmlReader handles it and things work in all parsers).
+ * <p>
+ * The XmlReader class handles the charset encoding of XML documents in Files, raw streams and HTTP streams by offering
+ * a wide set of constructors.
+ * <P>
+ * By default the charset encoding detection is lenient, the constructor with the lenient flag can be used for an script
+ * (following HTTP MIME and XML specifications). All this is nicely explained by Mark Pilgrim in his blog, <a
+ * href="http://diveintomark.org/archives/2004/02/13/xml-media-types"> Determining the character encoding of a feed</a>.
+ * <p>
+ * 
+ * @author Alejandro Abdelnur
+ * @version revision 1.17 taken on 26/06/2007 from Rome (see https://rome.dev.java.net/source/browse/rome/src/java/com/sun/syndication/io/XmlReader.java)
+ * @since 1.4.4
+ */
+public class XmlStreamReader
+extends XmlReader
+{
+    /**
+     * Creates a Reader for a File.
+     * <p>
+     * It looks for the UTF-8 BOM first, if none sniffs the XML prolog charset, if this is also missing defaults to
+     * UTF-8.
+     * <p>
+     * It does a lenient charset encoding detection, check the constructor with the lenient parameter for details.
+     * <p>
+     * 
+     * @param file
+     *            File to create a Reader from.
+     * @throws IOException
+     *             thrown if there is a problem reading the file.
+     * 
+     */
+    public XmlStreamReader( File file ) throws IOException
+    {
+        super( file );
+    }
+
+    /**
+     * Creates a Reader for a raw InputStream.
+     * <p>
+     * It follows the same logic used for files.
+     * <p>
+     * It does a lenient charset encoding detection, check the constructor with the lenient parameter for details.
+     * <p>
+     * 
+     * @param is
+     *            InputStream to create a Reader from.
+     * @throws IOException
+     *             thrown if there is a problem reading the stream.
+     * 
+     */
+    public XmlStreamReader( InputStream is ) throws IOException
+    {
+        super( is );
+    }
+
+    /**
+     * Creates a Reader for a raw InputStream.
+     * <p>
+     * It follows the same logic used for files.
+     * <p>
+     * If lenient detection is indicated and the detection above fails as per specifications it then attempts the
+     * following:
+     * <p>
+     * If the content type was 'text/html' it replaces it with 'text/xml' and tries the detection again.
+     * <p>
+     * Else if the XML prolog had a charset encoding that encoding is used.
+     * <p>
+     * Else if the content type had a charset encoding that encoding is used.
+     * <p>
+     * Else 'UTF-8' is used.
+     * <p>
+     * If lenient detection is indicated an XmlStreamReaderException is never thrown.
+     * <p>
+     * 
+     * @param is
+     *            InputStream to create a Reader from.
+     * @param lenient
+     *            indicates if the charset encoding detection should be relaxed.
+     * @throws IOException
+     *             thrown if there is a problem reading the stream.
+     * @throws XmlStreamReaderException
+     *             thrown if the charset encoding could not be determined according to the specs.
+     * 
+     */
+    public XmlStreamReader( InputStream is, boolean lenient ) throws IOException, XmlStreamReaderException
+    {
+        super( is, lenient );
+    }
+
+    /**
+     * Creates a Reader using the InputStream of a URL.
+     * <p>
+     * If the URL is not of type HTTP and there is not 'content-type' header in the fetched data it uses the same logic
+     * used for Files.
+     * <p>
+     * If the URL is a HTTP Url or there is a 'content-type' header in the fetched data it uses the same logic used for
+     * an InputStream with content-type.
+     * <p>
+     * It does a lenient charset encoding detection, check the constructor with the lenient parameter for details.
+     * <p>
+     * 
+     * @param url
+     *            URL to create a Reader from.
+     * @throws IOException
+     *             thrown if there is a problem reading the stream of the URL.
+     * 
+     */
+    public XmlStreamReader( URL url ) throws IOException
+    {
+        super( url );
+    }
+
+    /**
+     * Creates a Reader using the InputStream of a URLConnection.
+     * <p>
+     * If the URLConnection is not of type HttpURLConnection and there is not 'content-type' header in the fetched data
+     * it uses the same logic used for files.
+     * <p>
+     * If the URLConnection is a HTTP Url or there is a 'content-type' header in the fetched data it uses the same logic
+     * used for an InputStream with content-type.
+     * <p>
+     * It does a lenient charset encoding detection, check the constructor with the lenient parameter for details.
+     * <p>
+     * 
+     * @param conn
+     *            URLConnection to create a Reader from.
+     * @throws IOException
+     *             thrown if there is a problem reading the stream of the URLConnection.
+     * 
+     */
+    public XmlStreamReader( URLConnection conn ) throws IOException
+    {
+        super( conn );
+    }
+
+    /**
+     * Creates a Reader using an InputStream an the associated content-type header.
+     * <p>
+     * First it checks if the stream has BOM. If there is not BOM checks the content-type encoding. If there is not
+     * content-type encoding checks the XML prolog encoding. If there is not XML prolog encoding uses the default
+     * encoding mandated by the content-type MIME type.
+     * <p>
+     * It does a lenient charset encoding detection, check the constructor with the lenient parameter for details.
+     * <p>
+     * 
+     * @param is
+     *            InputStream to create the reader from.
+     * @param httpContentType
+     *            content-type header to use for the resolution of the charset encoding.
+     * @throws IOException
+     *             thrown if there is a problem reading the file.
+     * 
+     */
+    public XmlStreamReader( InputStream is, String httpContentType ) throws IOException
+    {
+        super( is, httpContentType );
+    }
+
+    /**
+     * Creates a Reader using an InputStream an the associated content-type header. This constructor is lenient
+     * regarding the encoding detection.
+     * <p>
+     * First it checks if the stream has BOM. If there is not BOM checks the content-type encoding. If there is not
+     * content-type encoding checks the XML prolog encoding. If there is not XML prolog encoding uses the default
+     * encoding mandated by the content-type MIME type.
+     * <p>
+     * If lenient detection is indicated and the detection above fails as per specifications it then attempts the
+     * following:
+     * <p>
+     * If the content type was 'text/html' it replaces it with 'text/xml' and tries the detection again.
+     * <p>
+     * Else if the XML prolog had a charset encoding that encoding is used.
+     * <p>
+     * Else if the content type had a charset encoding that encoding is used.
+     * <p>
+     * Else 'UTF-8' is used.
+     * <p>
+     * If lenient detection is indicated an XmlStreamReaderException is never thrown.
+     * <p>
+     * 
+     * @param is
+     *            InputStream to create the reader from.
+     * @param httpContentType
+     *            content-type header to use for the resolution of the charset encoding.
+     * @param lenient
+     *            indicates if the charset encoding detection should be relaxed.
+     * @throws IOException
+     *             thrown if there is a problem reading the file.
+     * @throws XmlStreamReaderException
+     *             thrown if the charset encoding could not be determined according to the specs.
+     * 
+     */
+    public XmlStreamReader( InputStream is, String httpContentType, boolean lenient, String defaultEncoding )
+        throws IOException, XmlStreamReaderException
+    {
+        super( is, httpContentType, lenient, defaultEncoding );
+    }
+
+    /**
+     * Creates a Reader using an InputStream an the associated content-type header. This constructor is lenient
+     * regarding the encoding detection.
+     * <p>
+     * First it checks if the stream has BOM. If there is not BOM checks the content-type encoding. If there is not
+     * content-type encoding checks the XML prolog encoding. If there is not XML prolog encoding uses the default
+     * encoding mandated by the content-type MIME type.
+     * <p>
+     * If lenient detection is indicated and the detection above fails as per specifications it then attempts the
+     * following:
+     * <p>
+     * If the content type was 'text/html' it replaces it with 'text/xml' and tries the detection again.
+     * <p>
+     * Else if the XML prolog had a charset encoding that encoding is used.
+     * <p>
+     * Else if the content type had a charset encoding that encoding is used.
+     * <p>
+     * Else 'UTF-8' is used.
+     * <p>
+     * If lenient detection is indicated an XmlStreamReaderException is never thrown.
+     * <p>
+     * 
+     * @param is
+     *            InputStream to create the reader from.
+     * @param httpContentType
+     *            content-type header to use for the resolution of the charset encoding.
+     * @param lenient
+     *            indicates if the charset encoding detection should be relaxed.
+     * @throws IOException
+     *             thrown if there is a problem reading the file.
+     * @throws XmlStreamReaderException
+     *             thrown if the charset encoding could not be determined according to the specs.
+     * 
+     */
+    public XmlStreamReader( InputStream is, String httpContentType, boolean lenient ) throws IOException, XmlStreamReaderException
+    {
+        super( is, httpContentType, lenient );
+    }
+}

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlStreamReader.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlStreamReader.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlStreamReader.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlStreamReaderException.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlStreamReaderException.java?rev=821961&view=auto
==============================================================================
--- geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlStreamReaderException.java (added)
+++ geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlStreamReaderException.java Mon Oct  5 18:54:50 2009
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2004 Sun Microsystems, Inc.
+ *
+ * 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.geronimo.system.plugin.plexus.util.xml;
+
+import java.io.InputStream;
+
+/**
+ * The XmlStreamReaderException is thrown by the XmlStreamReader constructors if the charset encoding can not be determined
+ * according to the XML 1.0 specification and RFC 3023.
+ * <p>
+ * The exception returns the unconsumed InputStream to allow the application to do an alternate processing with the
+ * stream. Note that the original InputStream given to the XmlStreamReader cannot be used as that one has been already read.
+ * <p>
+ *
+ * @author Alejandro Abdelnur
+ * @version revision 1.1 taken on 26/06/2007 from Rome (see https://rome.dev.java.net/source/browse/rome/src/java/com/sun/syndication/io/XmlReaderException.java)
+ */
+public class XmlStreamReaderException extends XmlReaderException
+{
+    /**
+     * Creates an exception instance if the charset encoding could not be determined.
+     * <p>
+     * Instances of this exception are thrown by the XmlReader.
+     * <p>
+     *
+     * @param msg
+     *            message describing the reason for the exception.
+     * @param bomEnc
+     *            BOM encoding.
+     * @param xmlGuessEnc
+     *            XML guess encoding.
+     * @param xmlEnc
+     *            XML prolog encoding.
+     * @param is
+     *            the unconsumed InputStream.
+     *
+     */
+    public XmlStreamReaderException( String msg, String bomEnc, String xmlGuessEnc, String xmlEnc, InputStream is )
+    {
+        super( msg, bomEnc, xmlGuessEnc, xmlEnc, is );
+    }
+
+    /**
+     * Creates an exception instance if the charset encoding could not be determined.
+     * <p>
+     * Instances of this exception are thrown by the XmlReader.
+     * <p>
+     *
+     * @param msg
+     *            message describing the reason for the exception.
+     * @param ctMime
+     *            MIME type in the content-type.
+     * @param ctEnc
+     *            encoding in the content-type.
+     * @param bomEnc
+     *            BOM encoding.
+     * @param xmlGuessEnc
+     *            XML guess encoding.
+     * @param xmlEnc
+     *            XML prolog encoding.
+     * @param is
+     *            the unconsumed InputStream.
+     *
+     */
+    public XmlStreamReaderException( String msg, String ctMime, String ctEnc, String bomEnc, String xmlGuessEnc,
+                               String xmlEnc, InputStream is )
+    {
+        super( msg, ctMime, ctEnc, bomEnc, xmlGuessEnc, xmlEnc, is );
+    }
+}

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlStreamReaderException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlStreamReaderException.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlStreamReaderException.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlStreamWriter.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlStreamWriter.java?rev=821961&view=auto
==============================================================================
--- geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlStreamWriter.java (added)
+++ geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlStreamWriter.java Mon Oct  5 18:54:50 2009
@@ -0,0 +1,163 @@
+package org.apache.geronimo.system.plugin.plexus.util.xml;
+
+/*
+ * Copyright The Codehaus 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.
+ */
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Character stream that handles (or at least attemtps to) all the necessary Voodo to figure out the charset encoding of
+ * the XML document written to the stream.
+ * @author <a href="mailto:hboutemy@codehaus.org">Herve Boutemy</a>
+ * @version $Id: XmlStreamWriter.java 8010 2009-01-07 12:59:50Z vsiveton $
+ * @since 1.4.4
+ */
+public class XmlStreamWriter
+extends Writer
+{
+    private static final int BUFFER_SIZE = 4096;
+
+    private StringWriter xmlPrologWriter = new StringWriter( BUFFER_SIZE );
+
+    private OutputStream out;
+
+    private Writer writer;
+
+    private String encoding;
+
+    public XmlStreamWriter( OutputStream out )
+    {
+        this.out = out;
+    }
+
+    public XmlStreamWriter( File file )
+    throws FileNotFoundException
+    {
+        this( new FileOutputStream( file ) );
+    }
+
+    public String getEncoding()
+    {
+        return encoding;
+    }
+
+    public void close()
+    throws IOException
+    {
+        if ( writer == null )
+        {
+            encoding = "UTF-8";
+            writer = new OutputStreamWriter( out, encoding );
+            writer.write( xmlPrologWriter.toString() );
+        }
+        writer.close();
+    }
+
+    public void flush()
+    throws IOException
+    {
+        if ( writer != null )
+        {
+            writer.flush();
+        }
+    }
+
+    private void detectEncoding( char[] cbuf, int off, int len )
+    throws IOException
+    {
+        int size = len;
+        StringBuffer xmlProlog = xmlPrologWriter.getBuffer();
+        if ( xmlProlog.length() + len > BUFFER_SIZE )
+        {
+            size = BUFFER_SIZE - xmlProlog.length();
+        }
+        xmlPrologWriter.write( cbuf, off, size );
+
+        // try to determine encoding
+        if ( xmlProlog.length() >= 5 )
+        {
+            if ( xmlProlog.substring( 0, 5 ).equals( "<?xml" ) )
+            {
+                // try to extract encoding from XML prolog
+                int xmlPrologEnd = xmlProlog.indexOf( "?>" );
+                if ( xmlPrologEnd > 0 )
+                {
+                    // ok, full XML prolog written: let's extract encoding
+                    Matcher m = ENCODING_PATTERN.matcher( xmlProlog.substring( 0, xmlPrologEnd ) );
+                    if ( m.find() )
+                    {
+                        encoding = m.group( 1 ).toUpperCase( Locale.ENGLISH );
+                        encoding = encoding.substring( 1, encoding.length() - 1 );
+                    }
+                    else
+                    {
+                        // no encoding found in XML prolog: using default encoding
+                        encoding = "UTF-8";
+                    }
+                }
+                else
+                {
+                    if ( xmlProlog.length() >= BUFFER_SIZE )
+                    {
+                        // no encoding found in first characters: using default encoding
+                        encoding = "UTF-8";
+                    }
+                }
+            }
+            else
+            {
+                // no XML prolog: using default encoding
+                encoding = "UTF-8";
+            }
+            if ( encoding != null )
+            {
+                // encoding has been chosen: let's do it
+                xmlPrologWriter = null;
+                writer = new OutputStreamWriter( out, encoding );
+                writer.write( xmlProlog.toString() );
+                if ( len > size )
+                {
+                    writer.write( cbuf, off + size, len - size );
+                }
+            }
+        }
+    }
+
+    public void write( char[] cbuf, int off, int len )
+    throws IOException
+    {
+        if ( xmlPrologWriter != null )
+        {
+            detectEncoding( cbuf, off, len );
+        }
+        else
+        {
+            writer.write( cbuf, off, len );
+        }
+    }
+
+    static final Pattern ENCODING_PATTERN = XmlReader.ENCODING_PATTERN;
+}

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlStreamWriter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlStreamWriter.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlStreamWriter.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlUtil.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlUtil.java?rev=821961&view=auto
==============================================================================
--- geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlUtil.java (added)
+++ geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlUtil.java Mon Oct  5 18:54:50 2009
@@ -0,0 +1,337 @@
+package org.apache.geronimo.system.plugin.plexus.util.xml;
+
+/*
+ * Copyright The Codehaus 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.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.Writer;
+
+import org.apache.geronimo.system.plugin.plexus.util.IOUtil;
+import org.apache.geronimo.system.plugin.plexus.util.ReaderFactory;
+import org.apache.geronimo.system.plugin.plexus.util.StringUtils;
+import org.apache.geronimo.system.plugin.plexus.util.WriterFactory;
+import org.apache.geronimo.system.plugin.plexus.util.xml.pull.MXParser;
+import org.apache.geronimo.system.plugin.plexus.util.xml.pull.XmlPullParser;
+import org.apache.geronimo.system.plugin.plexus.util.xml.pull.XmlPullParserException;
+
+/**
+ * Common XML utilities methods.
+ *
+ * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
+ * @version $Id: XmlUtil.java 8010 2009-01-07 12:59:50Z vsiveton $
+ * @since 1.5.7
+ */
+public class XmlUtil
+{
+    /** The default line indenter size i.e. 2. */
+    public static final int DEFAULT_INDENTATION_SIZE = 2;
+
+    /** The default line separator ("\n" on UNIX) */
+    public static final String DEFAULT_LINE_SEPARATOR = System.getProperty( "line.separator" );
+
+    /**
+     * Determines if a given File shall be handled as XML.
+     *
+     * @param f not null file
+     * @return <code>true</code> if the given file has XML content, <code>false</code> otherwise.
+     */
+    public static boolean isXml( File f )
+    {
+        if ( f == null )
+        {
+            throw new IllegalArgumentException( "f could not be null." );
+        }
+
+        if ( !f.isFile() )
+        {
+            throw new IllegalArgumentException( "The file '" + f.getAbsolutePath() + "' is not a file." );
+        }
+
+        Reader reader = null;
+        try
+        {
+            reader = ReaderFactory.newXmlReader( f );
+            XmlPullParser parser = new MXParser();
+            parser.setInput( reader );
+            parser.nextToken();
+
+            return true;
+        }
+        catch ( Exception e )
+        {
+            return false;
+        }
+        finally
+        {
+            IOUtil.close( reader );
+        }
+    }
+
+    /**
+     * Pretty format the input reader. For instance, the following input:
+     * <pre>
+     * &lt;div&gt;&lt;b&gt;content&lt;/b&gt;&lt;/div&gt;
+     * </pre>
+     * becomes
+     * <pre>
+     * &lt;div&gt;
+     *   &lt;b&gt;content&lt;/b&gt;
+     * &lt;/div&gt;
+     * </pre>
+     *
+     * @param reader not null
+     * @param writer not null
+     * @throws IOException if any or invalid xml content
+     * @see #prettyFormat(Reader, Writer, int, String)
+     * @see ReaderFactory to read an xml content
+     * @see WriterFactory to write an xml content
+     */
+    public static void prettyFormat( Reader reader, Writer writer )
+        throws IOException
+    {
+        prettyFormat( reader, writer, DEFAULT_INDENTATION_SIZE, DEFAULT_LINE_SEPARATOR );
+    }
+
+    /**
+     * Pretty format the input reader. For instance, the following input:
+     * <pre>
+     * &lt;div&gt;&lt;b&gt;content&lt;/b&gt;&lt;/div&gt;
+     * </pre>
+     * becomes
+     * <pre>
+     * &lt;div&gt;
+     *   &lt;b&gt;content&lt;/b&gt;
+     * &lt;/div&gt;
+     * </pre>
+     *
+     * @param reader not null
+     * @param writer not null
+     * @param indentSize positive number for the indentation
+     * @param lineSeparator the wanted line separator
+     * @throws IOException if any or invalid xml content
+     * @see ReaderFactory to read an xml content
+     * @see WriterFactory to write an xml content
+     */
+    public static void prettyFormat( Reader reader, Writer writer, int indentSize, String lineSeparator )
+        throws IOException
+    {
+        if ( reader == null )
+        {
+            throw new IllegalArgumentException( "The reader is null" );
+        }
+        if ( writer == null )
+        {
+            throw new IllegalArgumentException( "The writer is null" );
+        }
+        if ( indentSize < 0 )
+        {
+            indentSize = 0;
+        }
+
+        PrettyPrintXMLWriter xmlWriter = new PrettyPrintXMLWriter( writer );
+        xmlWriter.setLineIndenter( StringUtils.repeat( " ", indentSize ) );
+        xmlWriter.setLineSeparator( lineSeparator );
+
+        XmlPullParser parser = new MXParser();
+        try
+        {
+            parser.setInput( reader );
+
+            prettyFormatInternal( parser, xmlWriter );
+        }
+        catch ( XmlPullParserException e )
+        {
+            throw new IOException( "Unable to parse the XML: " + e.getMessage() );
+        }
+    }
+
+    /**
+     * Pretty format the input stream. For instance, the following input:
+     * <pre>
+     * &lt;div&gt;&lt;b&gt;content&lt;/b&gt;&lt;/div&gt;
+     * </pre>
+     * becomes
+     * <pre>
+     * &lt;div&gt;
+     *   &lt;b&gt;content&lt;/b&gt;
+     * &lt;/div&gt;
+     * </pre>
+     *
+     * @param is not null
+     * @param os not null
+     * @throws IOException if any or invalid xml content
+     * @see #prettyFormat(InputStream, OutputStream, int, String)
+     */
+    public static void prettyFormat( InputStream is, OutputStream os )
+        throws IOException
+    {
+        prettyFormat( is, os, DEFAULT_INDENTATION_SIZE, DEFAULT_LINE_SEPARATOR );
+    }
+
+    /**
+     * Pretty format the input stream. For instance, the following input:
+     * <pre>
+     * &lt;div&gt;&lt;b&gt;content&lt;/b&gt;&lt;/div&gt;
+     * </pre>
+     * becomes
+     * <pre>
+     * &lt;div&gt;
+     *   &lt;b&gt;content&lt;/b&gt;
+     * &lt;/div&gt;
+     * </pre>
+     *
+     * @param is not null
+     * @param os not null
+     * @param indentSize positive number for the indentation
+     * @param lineSeparator the wanted line separator
+     * @throws IOException if any or invalid xml content
+     */
+    public static void prettyFormat( InputStream is, OutputStream os, int indentSize, String lineSeparator )
+        throws IOException
+    {
+        if ( is == null )
+        {
+            throw new IllegalArgumentException( "The is is null" );
+        }
+        if ( os == null )
+        {
+            throw new IllegalArgumentException( "The os is null" );
+        }
+        if ( indentSize < 0 )
+        {
+            indentSize = 0;
+        }
+
+        Reader reader = null;
+
+        Writer out = new OutputStreamWriter( os );
+        PrettyPrintXMLWriter xmlWriter = new PrettyPrintXMLWriter( out );
+        xmlWriter.setLineIndenter( StringUtils.repeat( " ", indentSize ) );
+        xmlWriter.setLineSeparator( lineSeparator );
+
+        XmlPullParser parser = new MXParser();
+        try
+        {
+            reader = ReaderFactory.newXmlReader( is );
+
+            parser.setInput( reader );
+
+            prettyFormatInternal( parser, xmlWriter );
+        }
+        catch ( XmlPullParserException e )
+        {
+            throw new IOException( "Unable to parse the XML: " + e.getMessage() );
+        }
+        finally
+        {
+            IOUtil.close( reader );
+            IOUtil.close( out );
+        }
+    }
+
+    /**
+     * @param parser not null
+     * @param writer not null
+     * @throws XmlPullParserException if any
+     * @throws IOException if any
+     */
+    private static void prettyFormatInternal( XmlPullParser parser, PrettyPrintXMLWriter writer )
+        throws XmlPullParserException, IOException
+    {
+        boolean hasTag = false;
+        boolean hasComment = false;
+        int eventType = parser.getEventType();
+        while ( eventType != XmlPullParser.END_DOCUMENT )
+        {
+            if ( eventType == XmlPullParser.START_TAG )
+            {
+                hasTag = true;
+                if ( hasComment )
+                {
+                    writer.writeText( writer.getLineIndenter() );
+                    hasComment = false;
+                }
+                writer.startElement( parser.getName() );
+                for ( int i = 0; i < parser.getAttributeCount(); i++ )
+                {
+                    String key = parser.getAttributeName( i );
+                    String value = parser.getAttributeValue( i );
+                    writer.addAttribute( key, value );
+                }
+            }
+            else if ( eventType == XmlPullParser.TEXT )
+            {
+                String text = parser.getText();
+                if ( !text.trim().equals( "" ) )
+                {
+                    text = StringUtils.removeDuplicateWhitespace( text );
+                    writer.writeText( text );
+                }
+            }
+            else if ( eventType == XmlPullParser.END_TAG )
+            {
+                hasTag = false;
+                writer.endElement();
+            }
+            else if ( eventType == XmlPullParser.COMMENT )
+            {
+                hasComment = true;
+                if ( !hasTag )
+                {
+                    writer.writeMarkup( writer.getLineSeparator() );
+                    for ( int i = 0; i < writer.getDepth(); i++ )
+                    {
+                        writer.writeMarkup( writer.getLineIndenter() );
+                    }
+                }
+                writer.writeMarkup( "<!--" + parser.getText().trim() + " -->" );
+                if ( !hasTag )
+                {
+                    writer.writeMarkup( writer.getLineSeparator() );
+                    for ( int i = 0; i < writer.getDepth() - 1; i++ )
+                    {
+                        writer.writeMarkup( writer.getLineIndenter() );
+                    }
+                }
+            }
+            else if ( eventType == XmlPullParser.DOCDECL )
+            {
+                writer.writeMarkup( "<!DOCTYPE" + parser.getText() + ">" );
+                writer.endOfLine();
+            }
+            else if ( eventType == XmlPullParser.PROCESSING_INSTRUCTION )
+            {
+                writer.writeMarkup( "<?" + parser.getText() + "?>" );
+                writer.endOfLine();
+            }
+            else if ( eventType == XmlPullParser.CDSECT )
+            {
+                writer.writeMarkup( "<![CDATA[" + parser.getText() + "]]>" );
+            }
+            else if ( eventType == XmlPullParser.ENTITY_REF )
+            {
+                writer.writeMarkup( "&" + parser.getName() + ";" );
+            }
+
+            eventType = parser.nextToken();
+        }
+    }
+}

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlUtil.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlUtil.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlWriterUtil.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlWriterUtil.java?rev=821961&view=auto
==============================================================================
--- geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlWriterUtil.java (added)
+++ geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlWriterUtil.java Mon Oct  5 18:54:50 2009
@@ -0,0 +1,340 @@
+package org.apache.geronimo.system.plugin.plexus.util.xml;
+
+/*
+ * Copyright 2008 The Codehaus 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.
+ */
+
+import org.apache.geronimo.system.plugin.plexus.util.StringUtils;
+
+/**
+ * Utility class for the <code>XmlWriter</code> class.
+ *
+ * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
+ * @version $Id: XmlWriterUtil.java 8003 2009-01-03 15:09:49Z vsiveton $
+ */
+public class XmlWriterUtil
+{
+    /** The vm line separator */
+    public static final String LS = System.getProperty( "line.separator" );
+
+    /** The default line indenter size i.e. 2. */
+    public static final int DEFAULT_INDENTATION_SIZE = 2;
+
+    /** The default column before line wrapping i.e. 80. */
+    public static final int DEFAULT_COLUMN_LINE = 80;
+
+    /**
+     * Convenience method to write one <code>CRLF</code>.
+     *
+     * @param writer not null writer
+     */
+    public static void writeLineBreak( XMLWriter writer )
+    {
+        writeLineBreak( writer, 1 );
+    }
+
+    /**
+     * Convenience method to repeat <code>CRLF</code>.
+     *
+     * @param writer not null
+     * @param repeat positive number
+     */
+    public static void writeLineBreak( XMLWriter writer, int repeat )
+    {
+        for ( int i = 0; i < repeat; i++ )
+        {
+            writer.writeMarkup( LS );
+        }
+    }
+
+    /**
+     * Convenience method to repeat <code>CRLF</code> and to indent the writer by <code>2</code>.
+     *
+     * @param writer not null
+     * @param repeat
+     * @param indent positive number
+     * @see #DEFAULT_INDENTATION_SIZE
+     * @see #writeLineBreak(XMLWriter, int, int, int)
+     */
+    public static void writeLineBreak( XMLWriter writer, int repeat, int indent )
+    {
+        writeLineBreak( writer, repeat, indent, DEFAULT_INDENTATION_SIZE );
+    }
+
+    /**
+     * Convenience method to repeat <code>CRLF</code> and to indent the writer by <code>indentSize</code>.
+     *
+     * @param writer not null
+     * @param repeat
+     * @param indent positive number
+     * @param indentSize positive number
+     */
+    public static void writeLineBreak( XMLWriter writer, int repeat, int indent, int indentSize )
+    {
+        writeLineBreak( writer, repeat );
+
+        if ( indent < 0 )
+        {
+            indent = 0;
+        }
+
+        if ( indentSize < 0 )
+        {
+            indentSize = 0;
+        }
+
+        writer.writeText( StringUtils.repeat( " ", indent * indentSize ) );
+    }
+
+    /**
+     * Convenience method to write XML comment line break. Its size is <code>80</code>.
+     *
+     * @param writer not null
+     * @see #DEFAULT_COLUMN_LINE
+     * @see #writeCommentLineBreak(XMLWriter, int)
+     */
+    public static void writeCommentLineBreak( XMLWriter writer )
+    {
+        writeCommentLineBreak( writer, DEFAULT_COLUMN_LINE );
+    }
+
+    /**
+     * Convenience method to write XML comment line break with <code>columnSize</code> as length.
+     *
+     * @param writer not null
+     * @param columnSize positive number
+     */
+    public static void writeCommentLineBreak( XMLWriter writer, int columnSize )
+    {
+        if ( columnSize < 10 )
+        {
+            columnSize = DEFAULT_COLUMN_LINE;
+        }
+
+        writer.writeMarkup( "<!-- " + StringUtils.repeat( "=", columnSize - 10 ) + " -->" + LS );
+    }
+
+    /**
+     * Convenience method to write XML comment line. The <code>comment</code> is splitted to have a size of <code>80</code>.
+     *
+     * @param writer not null
+     * @param comment
+     * @see #DEFAULT_INDENTATION_SIZE
+     * @see #writeComment(XMLWriter, String, int, int)
+     */
+    public static void writeComment( XMLWriter writer, String comment )
+    {
+        writeComment( writer, comment, 0, DEFAULT_INDENTATION_SIZE );
+    }
+
+    /**
+     * Convenience method to write XML comment line. The <code>comment</code> is splitted to have a size of <code>80</code>
+     * and is indented by <code>indent</code> using <code>2</code> as indentation size.
+     *
+     * @param writer not null
+     * @param comment
+     * @param indent positive number
+     * @see #DEFAULT_INDENTATION_SIZE
+     * @see #writeComment(XMLWriter, String, int, int)
+     */
+    public static void writeComment( XMLWriter writer, String comment, int indent )
+    {
+        writeComment( writer, comment, indent, DEFAULT_INDENTATION_SIZE );
+    }
+
+    /**
+     * Convenience method to write XML comment line. The <code>comment</code> is splitted to have a size of <code>80</code>
+     * and is indented by <code>indent</code> using <code>indentSize</code>.
+     *
+     * @param writer not null
+     * @param comment
+     * @param indent positive number
+     * @param indentSize positive number
+     * @see #DEFAULT_COLUMN_LINE
+     * @see #writeComment(XMLWriter, String, int, int, int)
+     */
+    public static void writeComment( XMLWriter writer, String comment, int indent, int indentSize )
+    {
+        writeComment( writer, comment, indent, indentSize, DEFAULT_COLUMN_LINE );
+    }
+    /**
+     * Convenience method to write XML comment line. The <code>comment</code> is splitted to have a size of <code>columnSize</code>
+     * and is indented by <code>indent</code> using <code>indentSize</code>.
+     *
+     * @param writer not null
+     * @param comment
+     * @param indent positive number
+     * @param indentSize positive number
+     * @param columnSize positive number
+     */
+    public static void writeComment( XMLWriter writer, String comment, int indent, int indentSize, int columnSize  )
+    {
+        if ( comment == null )
+        {
+            comment = "null";
+        }
+
+        if ( indent < 0 )
+        {
+            indent = 0;
+        }
+
+        if ( indentSize < 0 )
+        {
+            indentSize = 0;
+        }
+
+        if ( columnSize < 0 )
+        {
+            columnSize = DEFAULT_COLUMN_LINE;
+        }
+
+        String indentation = StringUtils.repeat( " ", indent * indentSize );
+        int magicNumber = indentation.length() + columnSize - "-->".length() - 1;
+        String[] sentences = StringUtils.split( comment, LS );
+
+        StringBuffer line = new StringBuffer( indentation + "<!-- " );
+        for ( int i = 0; i < sentences.length; i++ )
+        {
+            String sentence = sentences[i];
+            String[] words = StringUtils.split( sentence, " " );
+            for ( int j = 0; j < words.length; j++ )
+            {
+                StringBuffer sentenceTmp = new StringBuffer( line.toString() );
+                sentenceTmp.append( words[j] ).append( ' ' );
+                if ( sentenceTmp.length() > magicNumber )
+                {
+                    if ( line.length() != indentation.length() + "<!-- ".length())
+                    {
+                        if ( magicNumber - line.length() > 0 )
+                        {
+                            line.append( StringUtils.repeat( " ", magicNumber - line.length() ) );
+                        }
+
+                        line.append( "-->" ).append( LS );
+                        writer.writeMarkup( line.toString() );
+                    }
+                    line = new StringBuffer( indentation + "<!-- " );
+                    line.append( words[j] ).append( ' ' );
+                }
+                else
+                {
+                    line.append( words[j] ).append( ' ' );
+                }
+            }
+
+            if ( magicNumber - line.length() > 0 )
+            {
+                line.append( StringUtils.repeat( " ", magicNumber - line.length() ) );
+            }
+        }
+
+        if ( line.length() <= magicNumber )
+        {
+            line.append( StringUtils.repeat( " ", magicNumber - line.length() ) );
+        }
+
+        line.append( "-->" ).append( LS );
+
+        writer.writeMarkup( line.toString() );
+    }
+
+    /**
+     * Convenience method to write XML comments between two comments line break.
+     * The XML comment block is not indented.
+     *
+     * @param writer not null
+     * @param comment
+     * @see #DEFAULT_INDENTATION_SIZE
+     * @see #writeCommentText(XMLWriter, String, int, int)
+     */
+    public static void writeCommentText( XMLWriter writer, String comment )
+    {
+        writeCommentText( writer, comment, 0, DEFAULT_INDENTATION_SIZE );
+    }
+
+    /**
+     * Convenience method to write XML comments between two comments line break.
+     * The XML comment block is also indented by <code>indent</code> using
+     * <code>2</code> as indentation size.
+     *
+     * @param writer not null
+     * @param comment
+     * @param indent positive number
+     * @see #DEFAULT_INDENTATION_SIZE
+     * @see #writeCommentText(XMLWriter, String, int, int)
+     */
+    public static void writeCommentText( XMLWriter writer, String comment, int indent )
+    {
+        writeCommentText( writer, comment, indent, DEFAULT_INDENTATION_SIZE );
+    }
+
+    /**
+     * Convenience method to write XML comment between two comment line break.
+     * The XML comment block is also indented by <code>indent</code> using <code>indentSize</code>.
+     *
+     * @param writer not null
+     * @param comment
+     * @param indent positive number
+     * @param indentSize positive number
+     * @see #DEFAULT_COLUMN_LINE
+     * @see #writeCommentText(XMLWriter, String, int, int, int)
+     */
+    public static void writeCommentText( XMLWriter writer, String comment, int indent, int indentSize )
+    {
+        writeCommentText( writer, comment, indent, indentSize, DEFAULT_COLUMN_LINE );
+    }
+
+    /**
+     * Convenience method to write XML comments between two comments line break.
+     * The XML comment block is also indented by <code>indent</code> using <code>indentSize</code>.
+     * The column size could be also be specified.
+     *
+     * @param writer not null
+     * @param comment
+     * @param indent positive number
+     * @param indentSize positive number
+     * @param columnSize positive number
+     */
+    public static void writeCommentText( XMLWriter writer, String comment, int indent, int indentSize, int columnSize )
+    {
+        if ( indent < 0 )
+        {
+            indent = 0;
+        }
+
+        if ( indentSize < 0 )
+        {
+            indentSize = 0;
+        }
+
+        if ( columnSize < 0 )
+        {
+            columnSize = DEFAULT_COLUMN_LINE;
+        }
+
+        writeLineBreak( writer, 1 );
+
+        writer.writeMarkup( StringUtils.repeat( " ", indent * indentSize ) );
+        writeCommentLineBreak( writer, columnSize );
+
+        writeComment( writer, comment, indent, indentSize, columnSize );
+
+        writer.writeMarkup( StringUtils.repeat( " ", indent * indentSize ) );
+        writeCommentLineBreak( writer, columnSize );
+
+        writeLineBreak( writer, 1, indent, indentSize );
+    }
+}

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlWriterUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlWriterUtil.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/XmlWriterUtil.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/Xpp3Dom.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/Xpp3Dom.java?rev=821961&view=auto
==============================================================================
--- geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/Xpp3Dom.java (added)
+++ geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/Xpp3Dom.java Mon Oct  5 18:54:50 2009
@@ -0,0 +1,537 @@
+package org.apache.geronimo.system.plugin.plexus.util.xml;
+
+/*
+ * Copyright The Codehaus 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.
+ */
+
+import org.apache.geronimo.system.plugin.plexus.util.xml.pull.XmlSerializer;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @version $Id: Xpp3Dom.java 8333 2009-08-08 20:04:03Z bentmann $
+ * NOTE: remove all the util code in here when separated, this class should be pure data.
+ */
+public class Xpp3Dom
+{
+    protected String name;
+
+    protected String value;
+
+    protected Map attributes;
+
+    protected final List childList;
+
+    protected final Map childMap;
+
+    protected Xpp3Dom parent;
+
+    private static final String[] EMPTY_STRING_ARRAY = new String[0];
+
+    private static final Xpp3Dom[] EMPTY_DOM_ARRAY = new Xpp3Dom[0];
+
+    public static final String CHILDREN_COMBINATION_MODE_ATTRIBUTE = "combine.children";
+
+    public static final String CHILDREN_COMBINATION_MERGE = "merge";
+
+    public static final String CHILDREN_COMBINATION_APPEND = "append";
+
+    /**
+     * This default mode for combining children DOMs during merge means that where element names
+     * match, the process will try to merge the element data, rather than putting the dominant
+     * and recessive elements (which share the same element name) as siblings in the resulting
+     * DOM.
+     */
+    public static final String DEFAULT_CHILDREN_COMBINATION_MODE = CHILDREN_COMBINATION_MERGE;
+
+    public static final String SELF_COMBINATION_MODE_ATTRIBUTE = "combine.self";
+
+    public static final String SELF_COMBINATION_OVERRIDE = "override";
+
+    public static final String SELF_COMBINATION_MERGE = "merge";
+
+    /**
+     * This default mode for combining a DOM node during merge means that where element names
+     * match, the process will try to merge the element attributes and values, rather than
+     * overriding the recessive element completely with the dominant one. This means that
+     * wherever the dominant element doesn't provide the value or a particular attribute, that
+     * value or attribute will be set from the recessive DOM node.
+     */
+    public static final String DEFAULT_SELF_COMBINATION_MODE = SELF_COMBINATION_MERGE;
+
+    public Xpp3Dom( String name )
+    {
+        this.name = name;
+        childList = new ArrayList();
+        childMap = new HashMap();
+    }
+
+    /**
+     * Copy constructor.
+     */
+    public Xpp3Dom( Xpp3Dom src )
+    {
+        this( src, src.getName() );
+    }
+
+    /**
+     * Copy constructor with alternative name.
+     */
+    public Xpp3Dom( Xpp3Dom src, String name )
+    {
+        this.name = name;
+
+        int childCount = src.getChildCount();
+
+        childList = new ArrayList( childCount );
+        childMap = new HashMap( childCount << 1 );
+
+        setValue( src.getValue() );
+
+        String[] attributeNames = src.getAttributeNames();
+        for ( int i = 0; i < attributeNames.length; i++ )
+        {
+            String attributeName = attributeNames[i];
+            setAttribute( attributeName, src.getAttribute( attributeName ) );
+        }
+
+        for ( int i = 0; i < childCount; i++ )
+        {
+            addChild( new Xpp3Dom( src.getChild( i ) ) );
+        }
+    }
+
+    // ----------------------------------------------------------------------
+    // Name handling
+    // ----------------------------------------------------------------------
+
+    public String getName()
+    {
+        return name;
+    }
+
+    // ----------------------------------------------------------------------
+    // Value handling
+    // ----------------------------------------------------------------------
+
+    public String getValue()
+    {
+        return value;
+    }
+
+    public void setValue( String value )
+    {
+        this.value = value;
+    }
+
+    // ----------------------------------------------------------------------
+    // Attribute handling
+    // ----------------------------------------------------------------------
+
+    public String[] getAttributeNames()
+    {
+        if ( null == attributes || attributes.isEmpty() )
+        {
+            return EMPTY_STRING_ARRAY;
+        }
+        else
+        {
+            return (String[]) attributes.keySet().toArray( new String[attributes.size()] );
+        }
+    }
+
+    public String getAttribute( String name )
+    {
+        return ( null != attributes ) ? (String) attributes.get( name ) : null;
+    }
+
+    /**
+     * Set the attribute value
+     * @param name String not null
+     * @param value String not null
+     */
+    public void setAttribute( String name, String value )
+    {
+        if ( null == value ) {
+            throw new NullPointerException( "Attribute value can not be null" );
+        }
+        if ( null == name ) {
+            throw new NullPointerException( "Attribute name can not be null" );
+        }
+        if ( null == attributes )
+        {
+            attributes = new HashMap();
+        }
+
+        attributes.put( name, value );
+    }
+
+    // ----------------------------------------------------------------------
+    // Child handling
+    // ----------------------------------------------------------------------
+
+    public Xpp3Dom getChild( int i )
+    {
+        return (Xpp3Dom) childList.get( i );
+    }
+
+    public Xpp3Dom getChild( String name )
+    {
+        return (Xpp3Dom) childMap.get( name );
+    }
+
+    public void addChild( Xpp3Dom xpp3Dom )
+    {
+        xpp3Dom.setParent( this );
+        childList.add( xpp3Dom );
+        childMap.put( xpp3Dom.getName(), xpp3Dom );
+    }
+
+    public Xpp3Dom[] getChildren()
+    {
+        if ( null == childList || childList.isEmpty() )
+        {
+            return EMPTY_DOM_ARRAY;
+        }
+        else
+        {
+            return (Xpp3Dom[]) childList.toArray( new Xpp3Dom[childList.size()] );
+        }
+    }
+
+    public Xpp3Dom[] getChildren( String name )
+    {
+        if ( null == childList )
+        {
+            return EMPTY_DOM_ARRAY;
+        }
+        else
+        {
+            ArrayList children = new ArrayList();
+            int size = childList.size();
+
+            for ( int i = 0; i < size; i++ )
+            {
+                Xpp3Dom configuration = (Xpp3Dom) childList.get( i );
+                if ( name.equals( configuration.getName() ) )
+                {
+                    children.add( configuration );
+                }
+            }
+
+            return (Xpp3Dom[]) children.toArray( new Xpp3Dom[children.size()] );
+        }
+    }
+
+    public int getChildCount()
+    {
+        if ( null == childList )
+        {
+            return 0;
+        }
+
+        return childList.size();
+    }
+
+    public void removeChild( int i )
+    {
+        Xpp3Dom child = getChild( i );
+        childMap.values().remove( child );
+        childList.remove( i );
+        // In case of any dangling references
+        child.setParent( null );
+    }
+
+    // ----------------------------------------------------------------------
+    // Parent handling
+    // ----------------------------------------------------------------------
+
+    public Xpp3Dom getParent()
+    {
+        return parent;
+    }
+
+    public void setParent( Xpp3Dom parent )
+    {
+        this.parent = parent;
+    }
+
+    // ----------------------------------------------------------------------
+    // Helpers
+    // ----------------------------------------------------------------------
+
+    public void writeToSerializer( String namespace, XmlSerializer serializer )
+        throws IOException
+    {
+        // TODO: WARNING! Later versions of plexus-utils psit out an <?xml ?> header due to thinking this is a new document - not the desired behaviour!
+        SerializerXMLWriter xmlWriter = new SerializerXMLWriter( namespace, serializer );
+        Xpp3DomWriter.write( xmlWriter, this );
+        if ( xmlWriter.getExceptions().size() > 0 )
+        {
+            throw (IOException) xmlWriter.getExceptions().get( 0 );
+        }
+    }
+
+    /**
+     * Merges one DOM into another, given a specific algorithm and possible override points for that algorithm.
+     * The algorithm is as follows:
+     *
+     * 1. if the recessive DOM is null, there is nothing to do...return.
+     *
+     * 2. Determine whether the dominant node will suppress the recessive one (flag=mergeSelf).
+     *
+     *    A. retrieve the 'combine.self' attribute on the dominant node, and try to match against 'override'...
+     *       if it matches 'override', then set mergeSelf == false...the dominant node suppresses the recessive
+     *       one completely.
+     *
+     *    B. otherwise, use the default value for mergeSelf, which is true...this is the same as specifying
+     *       'combine.self' == 'merge' as an attribute of the dominant root node.
+     *
+     * 3. If mergeSelf == true
+     *
+     *    A. if the dominant root node's value is empty, set it to the recessive root node's value
+     *
+     *    B. For each attribute in the recessive root node which is not set in the dominant root node, set it.
+     *
+     *    C. Determine whether children from the recessive DOM will be merged or appended to the dominant
+     *       DOM as siblings (flag=mergeChildren).
+     *
+     *       i.   if childMergeOverride is set (non-null), use that value (true/false)
+     *
+     *       ii.  retrieve the 'combine.children' attribute on the dominant node, and try to match against
+     *            'append'...if it matches 'append', then set mergeChildren == false...the recessive children
+     *            will be appended as siblings of the dominant children.
+     *
+     *       iii. otherwise, use the default value for mergeChildren, which is true...this is the same as
+     *            specifying 'combine.children' == 'merge' as an attribute on the dominant root node.
+     *
+     *    D. Iterate through the recessive children, and:
+     *
+     *       i.   if mergeChildren == true and there is a corresponding dominant child (matched by element name),
+     *            merge the two.
+     *
+     *       ii.  otherwise, add the recessive child as a new child on the dominant root node.
+     */
+    private static void mergeIntoXpp3Dom( Xpp3Dom dominant, Xpp3Dom recessive, Boolean childMergeOverride )
+    {
+        // TODO: share this as some sort of assembler, implement a walk interface?
+        if ( recessive == null )
+        {
+            return;
+        }
+
+        boolean mergeSelf = true;
+
+        String selfMergeMode = dominant.getAttribute( SELF_COMBINATION_MODE_ATTRIBUTE );
+
+        if ( SELF_COMBINATION_OVERRIDE.equals( selfMergeMode ) )
+        {
+            mergeSelf = false;
+        }
+
+        if ( mergeSelf )
+        {
+            if ( isEmpty( dominant.getValue() ) )
+            {
+                dominant.setValue( recessive.getValue() );
+            }
+
+            String[] recessiveAttrs = recessive.getAttributeNames();
+            for ( int i = 0; i < recessiveAttrs.length; i++ )
+            {
+                String attr = recessiveAttrs[i];
+
+                if ( isEmpty( dominant.getAttribute( attr ) ) )
+                {
+                    dominant.setAttribute( attr, recessive.getAttribute( attr ) );
+                }
+            }
+
+            boolean mergeChildren = true;
+
+            if ( childMergeOverride != null )
+            {
+                mergeChildren = childMergeOverride.booleanValue();
+            }
+            else
+            {
+                String childMergeMode = dominant.getAttribute( CHILDREN_COMBINATION_MODE_ATTRIBUTE );
+
+                if ( CHILDREN_COMBINATION_APPEND.equals( childMergeMode ) )
+                {
+                    mergeChildren = false;
+                }
+            }
+
+            Xpp3Dom[] dominantChildren = null;
+            if ( !mergeChildren )
+            {
+                dominantChildren = dominant.getChildren();
+                // remove these now, so we can append them to the recessive list later.
+                dominant.childList.clear();
+            }
+
+            int recessiveChildCount = recessive.getChildCount();
+            for ( int i = 0; i < recessiveChildCount; i++ )
+            {
+                Xpp3Dom recessiveChild = recessive.getChild( i );
+                Xpp3Dom dominantChild = dominant.getChild( recessiveChild.getName() );
+                if ( mergeChildren && ( dominantChild != null ) )
+                {
+                    mergeIntoXpp3Dom( dominantChild, recessiveChild, childMergeOverride );
+                }
+                else
+                {
+                    dominant.addChild( new Xpp3Dom( recessiveChild ) );
+                }
+            }
+
+            if ( !mergeChildren )
+            {
+                // now, re-add these children so they'll be appended to the recessive list.
+                for ( int i = 0; i < dominantChildren.length; i++ )
+                {
+                    dominant.addChild( dominantChildren[i] );
+                }
+            }
+        }
+    }
+
+    /**
+     * Merge two DOMs, with one having dominance in the case of collision.
+     *
+     * @see #CHILDREN_COMBINATION_MODE_ATTRIBUTE
+     * @see #SELF_COMBINATION_MODE_ATTRIBUTE
+     *
+     * @param dominant The dominant DOM into which the recessive value/attributes/children will be merged
+     * @param recessive The recessive DOM, which will be merged into the dominant DOM
+     * @param childMergeOverride Overrides attribute flags to force merging or appending of child elements
+     *        into the dominant DOM
+     */
+    public static Xpp3Dom mergeXpp3Dom( Xpp3Dom dominant, Xpp3Dom recessive, Boolean childMergeOverride )
+    {
+        if ( dominant != null )
+        {
+            mergeIntoXpp3Dom( dominant, recessive, childMergeOverride );
+            return dominant;
+        }
+        return recessive;
+    }
+
+    /**
+     * Merge two DOMs, with one having dominance in the case of collision.
+     * Merge mechanisms (vs. override for nodes, or vs. append for children) is determined by
+     * attributes of the dominant root node.
+     *
+     * @see #CHILDREN_COMBINATION_MODE_ATTRIBUTE
+     * @see #SELF_COMBINATION_MODE_ATTRIBUTE
+     *
+     * @param dominant The dominant DOM into which the recessive value/attributes/children will be merged
+     * @param recessive The recessive DOM, which will be merged into the dominant DOM
+     */
+    public static Xpp3Dom mergeXpp3Dom( Xpp3Dom dominant, Xpp3Dom recessive )
+    {
+        if ( dominant != null )
+        {
+            mergeIntoXpp3Dom( dominant, recessive, null );
+            return dominant;
+        }
+        return recessive;
+    }
+
+    // ----------------------------------------------------------------------
+    // Standard object handling
+    // ----------------------------------------------------------------------
+
+    public boolean equals( Object obj )
+    {
+        if ( obj == this )
+        {
+            return true;
+        }
+
+        if ( !( obj instanceof Xpp3Dom ) )
+        {
+            return false;
+        }
+
+        Xpp3Dom dom = (Xpp3Dom) obj;
+
+        if ( name == null ? dom.name != null : !name.equals( dom.name ) )
+        {
+            return false;
+        }
+        else if ( value == null ? dom.value != null : !value.equals( dom.value ) )
+        {
+            return false;
+        }
+        else if ( attributes == null ? dom.attributes != null : !attributes.equals( dom.attributes ) )
+        {
+            return false;
+        }
+        else if ( childList == null ? dom.childList != null : !childList.equals( dom.childList ) )
+        {
+            return false;
+        }
+        else
+        {
+            return true;
+        }
+    }
+
+    public int hashCode()
+    {
+        int result = 17;
+        result = 37 * result + ( name != null ? name.hashCode() : 0 );
+        result = 37 * result + ( value != null ? value.hashCode() : 0 );
+        result = 37 * result + ( attributes != null ? attributes.hashCode() : 0 );
+        result = 37 * result + ( childList != null ? childList.hashCode() : 0 );
+        return result;
+    }
+
+    public String toString()
+    {
+        // TODO: WARNING! Later versions of plexus-utils psit out an <?xml ?> header due to thinking this is a new document - not the desired behaviour!
+        StringWriter writer = new StringWriter();
+        XMLWriter xmlWriter = new PrettyPrintXMLWriter( writer, "UTF-8", null );
+        Xpp3DomWriter.write( xmlWriter, this );
+        return writer.toString();
+    }
+
+    public String toUnescapedString()
+    {
+        // TODO: WARNING! Later versions of plexus-utils psit out an <?xml ?> header due to thinking this is a new document - not the desired behaviour!
+        StringWriter writer = new StringWriter();
+        XMLWriter xmlWriter = new PrettyPrintXMLWriter( writer, "UTF-8", null );
+        Xpp3DomWriter.write( xmlWriter, this, false );
+        return writer.toString();
+    }
+
+    public static boolean isNotEmpty( String str )
+    {
+        return ( ( str != null ) && ( str.length() > 0 ) );
+    }
+
+    public static boolean isEmpty( String str )
+    {
+        return ( ( str == null ) || ( str.trim().length() == 0 ) );
+    }
+
+}

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/Xpp3Dom.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/Xpp3Dom.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/Xpp3Dom.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/Xpp3DomBuilder.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/Xpp3DomBuilder.java?rev=821961&view=auto
==============================================================================
--- geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/Xpp3DomBuilder.java (added)
+++ geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/Xpp3DomBuilder.java Mon Oct  5 18:54:50 2009
@@ -0,0 +1,184 @@
+package org.apache.geronimo.system.plugin.plexus.util.xml;
+
+/*
+ * Copyright The Codehaus 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.
+ */
+
+import org.apache.geronimo.system.plugin.plexus.util.IOUtil;
+import org.apache.geronimo.system.plugin.plexus.util.xml.pull.MXParser;
+import org.apache.geronimo.system.plugin.plexus.util.xml.pull.XmlPullParser;
+import org.apache.geronimo.system.plugin.plexus.util.xml.pull.XmlPullParserException;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @version $Id: Xpp3DomBuilder.java 8010 2009-01-07 12:59:50Z vsiveton $
+ */
+public class Xpp3DomBuilder
+{
+    private static final boolean DEFAULT_TRIM = true;
+
+    public static Xpp3Dom build( Reader reader )
+        throws XmlPullParserException, IOException
+    {
+        return build( reader, DEFAULT_TRIM );
+    }
+
+    public static Xpp3Dom build( InputStream is, String encoding )
+        throws XmlPullParserException, IOException
+    {
+        return build( is, encoding, DEFAULT_TRIM );
+    }
+
+    public static Xpp3Dom build( InputStream is, String encoding, boolean trim )
+        throws XmlPullParserException, IOException
+    {
+        XmlPullParser parser = new MXParser();
+
+        parser.setInput( is, encoding );
+
+        try
+        {
+            return build( parser, trim );
+        }
+        finally
+        {
+            IOUtil.close( is );
+        }
+    }
+
+    public static Xpp3Dom build( Reader reader, boolean trim )
+        throws XmlPullParserException, IOException
+    {
+        XmlPullParser parser = new MXParser();
+
+        parser.setInput( reader );
+
+        try
+        {
+            return build( parser, trim );
+        }
+        finally
+        {
+            IOUtil.close( reader );
+        }
+    }
+
+    public static Xpp3Dom build( XmlPullParser parser )
+        throws XmlPullParserException, IOException
+    {
+        return build( parser, DEFAULT_TRIM );
+    }
+
+    public static Xpp3Dom build( XmlPullParser parser, boolean trim )
+        throws XmlPullParserException, IOException
+    {
+        List elements = new ArrayList();
+
+        List values = new ArrayList();
+
+        int eventType = parser.getEventType();
+
+        while ( eventType != XmlPullParser.END_DOCUMENT )
+        {
+            if ( eventType == XmlPullParser.START_TAG )
+            {
+                String rawName = parser.getName();
+
+                Xpp3Dom childConfiguration = new Xpp3Dom( rawName );
+
+                int depth = elements.size();
+
+                if ( depth > 0 )
+                {
+                    Xpp3Dom parent = (Xpp3Dom) elements.get( depth - 1 );
+
+                    parent.addChild( childConfiguration );
+                }
+
+                elements.add( childConfiguration );
+
+                if ( parser.isEmptyElementTag() )
+                {
+                    values.add( null );
+                }
+                else
+                {
+                    values.add( new StringBuffer() );
+                }
+
+                int attributesSize = parser.getAttributeCount();
+
+                for ( int i = 0; i < attributesSize; i++ )
+                {
+                    String name = parser.getAttributeName( i );
+
+                    String value = parser.getAttributeValue( i );
+
+                    childConfiguration.setAttribute( name, value );
+                }
+            }
+            else if ( eventType == XmlPullParser.TEXT )
+            {
+                int depth = values.size() - 1;
+
+                StringBuffer valueBuffer = (StringBuffer) values.get( depth );
+
+                String text = parser.getText();
+
+                if ( trim )
+                {
+                    text = text.trim();
+                }
+
+                valueBuffer.append( text );
+            }
+            else if ( eventType == XmlPullParser.END_TAG )
+            {
+                int depth = elements.size() - 1;
+
+                Xpp3Dom finishedConfiguration = (Xpp3Dom) elements.remove( depth );
+
+                /* this Object could be null if it is a singleton tag */
+                Object accumulatedValue = values.remove( depth );
+
+                if ( finishedConfiguration.getChildCount() == 0 )
+                {
+                    if ( accumulatedValue == null )
+                    {
+                        finishedConfiguration.setValue( null );
+                    }
+                    else
+                    {
+                        finishedConfiguration.setValue( accumulatedValue.toString() );
+                    }
+                }
+
+                if ( depth == 0 )
+                {
+                    return finishedConfiguration;
+                }
+            }
+
+            eventType = parser.next();
+        }
+
+        throw new IllegalStateException( "End of document found before returning to 0 depth" );
+    }
+}

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/Xpp3DomBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/Xpp3DomBuilder.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/Xpp3DomBuilder.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/Xpp3DomUtils.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/Xpp3DomUtils.java?rev=821961&view=auto
==============================================================================
--- geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/Xpp3DomUtils.java (added)
+++ geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/Xpp3DomUtils.java Mon Oct  5 18:54:50 2009
@@ -0,0 +1,226 @@
+package org.apache.geronimo.system.plugin.plexus.util.xml;
+
+/*
+ * Copyright The Codehaus 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.
+ */
+
+import org.apache.geronimo.system.plugin.plexus.util.xml.pull.XmlSerializer;
+
+import java.io.IOException;
+
+/** @author Jason van Zyl */
+public class Xpp3DomUtils
+{
+    public static final String CHILDREN_COMBINATION_MODE_ATTRIBUTE = "combine.children";
+
+    public static final String CHILDREN_COMBINATION_MERGE = "merge";
+
+    public static final String CHILDREN_COMBINATION_APPEND = "append";
+
+    /**
+     * This default mode for combining children DOMs during merge means that where element names
+     * match, the process will try to merge the element data, rather than putting the dominant
+     * and recessive elements (which share the same element name) as siblings in the resulting
+     * DOM.
+     */
+    public static final String DEFAULT_CHILDREN_COMBINATION_MODE = CHILDREN_COMBINATION_MERGE;
+
+    public static final String SELF_COMBINATION_MODE_ATTRIBUTE = "combine.self";
+
+    public static final String SELF_COMBINATION_OVERRIDE = "override";
+
+    public static final String SELF_COMBINATION_MERGE = "merge";
+
+    /**
+     * This default mode for combining a DOM node during merge means that where element names
+     * match, the process will try to merge the element attributes and values, rather than
+     * overriding the recessive element completely with the dominant one. This means that
+     * wherever the dominant element doesn't provide the value or a particular attribute, that
+     * value or attribute will be set from the recessive DOM node.
+     */
+    public static final String DEFAULT_SELF_COMBINATION_MODE = SELF_COMBINATION_MERGE;
+
+    public void writeToSerializer( String namespace, XmlSerializer serializer, Xpp3Dom dom )
+        throws IOException
+    {
+        // TODO: WARNING! Later versions of plexus-utils psit out an <?xml ?> header due to thinking this is a new document - not the desired behaviour!
+        SerializerXMLWriter xmlWriter = new SerializerXMLWriter( namespace, serializer );
+        Xpp3DomWriter.write( xmlWriter, dom );
+        if ( xmlWriter.getExceptions().size() > 0 )
+        {
+            throw (IOException) xmlWriter.getExceptions().get( 0 );
+        }
+    }
+
+    /**
+     * Merges one DOM into another, given a specific algorithm and possible override points for that algorithm.
+     * The algorithm is as follows:
+     *
+     * 1. if the recessive DOM is null, there is nothing to do...return.
+     *
+     * 2. Determine whether the dominant node will suppress the recessive one (flag=mergeSelf).
+     *
+     *    A. retrieve the 'combine.self' attribute on the dominant node, and try to match against 'override'...
+     *       if it matches 'override', then set mergeSelf == false...the dominant node suppresses the recessive
+     *       one completely.
+     *
+     *    B. otherwise, use the default value for mergeSelf, which is true...this is the same as specifying
+     *       'combine.self' == 'merge' as an attribute of the dominant root node.
+     *
+     * 3. If mergeSelf == true
+     *
+     *    A. if the dominant root node's value is empty, set it to the recessive root node's value
+     *
+     *    B. For each attribute in the recessive root node which is not set in the dominant root node, set it.
+     *
+     *    C. Determine whether children from the recessive DOM will be merged or appended to the dominant
+     *       DOM as siblings (flag=mergeChildren).
+     *
+     *       i.   if childMergeOverride is set (non-null), use that value (true/false)
+     *
+     *       ii.  retrieve the 'combine.children' attribute on the dominant node, and try to match against
+     *            'append'...if it matches 'append', then set mergeChildren == false...the recessive children
+     *            will be appended as siblings of the dominant children.
+     *
+     *       iii. otherwise, use the default value for mergeChildren, which is true...this is the same as
+     *            specifying 'combine.children' == 'merge' as an attribute on the dominant root node.
+     *
+     *    D. Iterate through the recessive children, and:
+     *
+     *       i.   if mergeChildren == true and there is a corresponding dominant child (matched by element name),
+     *            merge the two.
+     *
+     *       ii.  otherwise, add the recessive child as a new child on the dominant root node.
+     */
+    private static void mergeIntoXpp3Dom( Xpp3Dom dominant, Xpp3Dom recessive, Boolean childMergeOverride )
+    {
+        // TODO: share this as some sort of assembler, implement a walk interface?
+        if ( recessive == null )
+        {
+            return;
+        }
+
+        boolean mergeSelf = true;
+
+        String selfMergeMode = dominant.getAttribute( SELF_COMBINATION_MODE_ATTRIBUTE );
+
+        if ( isNotEmpty( selfMergeMode ) && SELF_COMBINATION_OVERRIDE.equals( selfMergeMode ) )
+        {
+            mergeSelf = false;
+        }
+
+        if ( mergeSelf )
+        {
+            if ( isEmpty( dominant.getValue() ) )
+            {
+                dominant.setValue( recessive.getValue() );
+            }
+
+            String[] recessiveAttrs = recessive.getAttributeNames();
+            for ( int i = 0; i < recessiveAttrs.length; i++ )
+            {
+                String attr = recessiveAttrs[i];
+
+                if ( isEmpty( dominant.getAttribute( attr ) ) )
+                {
+                    dominant.setAttribute( attr, recessive.getAttribute( attr ) );
+                }
+            }
+
+            boolean mergeChildren = true;
+
+            if ( childMergeOverride != null )
+            {
+                mergeChildren = childMergeOverride.booleanValue();
+            }
+            else
+            {
+                String childMergeMode = dominant.getAttribute( CHILDREN_COMBINATION_MODE_ATTRIBUTE );
+
+                if ( isNotEmpty( childMergeMode ) && CHILDREN_COMBINATION_APPEND.equals( childMergeMode ) )
+                {
+                    mergeChildren = false;
+                }
+            }
+
+            Xpp3Dom[] children = recessive.getChildren();
+            for ( int i = 0; i < children.length; i++ )
+            {
+                Xpp3Dom child = children[i];
+                Xpp3Dom childDom = dominant.getChild( child.getName() );
+                if ( mergeChildren && childDom != null )
+                {
+                    mergeIntoXpp3Dom( childDom, child, childMergeOverride );
+                }
+                else
+                {
+                    dominant.addChild( new Xpp3Dom( child ) );
+                }
+            }
+        }
+    }
+
+    /**
+     * Merge two DOMs, with one having dominance in the case of collision.
+     *
+     * @see #CHILDREN_COMBINATION_MODE_ATTRIBUTE
+     * @see #SELF_COMBINATION_MODE_ATTRIBUTE
+     *
+     * @param dominant The dominant DOM into which the recessive value/attributes/children will be merged
+     * @param recessive The recessive DOM, which will be merged into the dominant DOM
+     * @param childMergeOverride Overrides attribute flags to force merging or appending of child elements
+     *        into the dominant DOM
+     */
+    public static Xpp3Dom mergeXpp3Dom( Xpp3Dom dominant, Xpp3Dom recessive, Boolean childMergeOverride )
+    {
+        if ( dominant != null )
+        {
+            mergeIntoXpp3Dom( dominant, recessive, childMergeOverride );
+            return dominant;
+        }
+        return recessive;
+    }
+
+    /**
+     * Merge two DOMs, with one having dominance in the case of collision.
+     * Merge mechanisms (vs. override for nodes, or vs. append for children) is determined by
+     * attributes of the dominant root node.
+     *
+     * @see #CHILDREN_COMBINATION_MODE_ATTRIBUTE
+     * @see #SELF_COMBINATION_MODE_ATTRIBUTE
+     *
+     * @param dominant The dominant DOM into which the recessive value/attributes/children will be merged
+     * @param recessive The recessive DOM, which will be merged into the dominant DOM
+     */
+    public static Xpp3Dom mergeXpp3Dom( Xpp3Dom dominant, Xpp3Dom recessive )
+    {
+        if ( dominant != null )
+        {
+            mergeIntoXpp3Dom( dominant, recessive, null );
+            return dominant;
+        }
+        return recessive;
+    }
+
+    public static boolean isNotEmpty( String str )
+    {
+        return ( str != null && str.length() > 0 );
+    }
+
+    public static boolean isEmpty( String str )
+    {
+        return ( str == null || str.trim().length() == 0 );
+    }
+}

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/Xpp3DomUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/Xpp3DomUtils.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/Xpp3DomUtils.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain



Mime
View raw message