You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by dj...@apache.org on 2009/10/05 20:54:56 UTC

svn commit: r821961 [28/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...

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/pull/MXParser.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/pull/MXParser.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/pull/MXParser.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/pull/MXSerializer.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/pull/MXSerializer.java?rev=821961&view=auto
==============================================================================
--- geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/pull/MXSerializer.java (added)
+++ geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/pull/MXSerializer.java Mon Oct  5 18:54:50 2009
@@ -0,0 +1,1121 @@
+/* -*-             c-basic-offset: 4; indent-tabs-mode: nil; -*-  //------100-columns-wide------>|*/
+// for license please see accompanying LICENSE.txt file (available also at http://www.xmlpull.org/)
+
+package org.apache.geronimo.system.plugin.plexus.util.xml.pull;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+
+/**
+ * Implementation of XmlSerializer interface from XmlPull V1 API.
+ * This implementation is optimized for performance and low memory footprint.
+ *
+ * <p>Implemented features:<ul>
+ *  <li> FEATURE_NAMES_INTERNED - when enabled all returned names
+ *    (namespaces, prefixes) will be interned and it is required that
+ *    all names passed as arguments MUST be interned
+ *  <li> FEATURE_SERIALIZER_ATTVALUE_USE_APOSTROPHE
+ *  </ul>
+ * <p>Implemented properties:<ul>
+ *  <li> PROPERTY_SERIALIZER_INDENTATION
+ *  <li> PROPERTY_SERIALIZER_LINE_SEPARATOR
+ *  </ul>
+ *
+ */
+public class MXSerializer implements XmlSerializer {
+    protected final static String XML_URI = "http://www.w3.org/XML/1998/namespace";
+    protected final static String XMLNS_URI = "http://www.w3.org/2000/xmlns/";
+    private static final boolean TRACE_SIZING = false;
+
+    protected final String FEATURE_SERIALIZER_ATTVALUE_USE_APOSTROPHE =
+        "http://xmlpull.org/v1/doc/features.html#serializer-attvalue-use-apostrophe";
+    protected final String FEATURE_NAMES_INTERNED =
+        "http://xmlpull.org/v1/doc/features.html#names-interned";
+    protected final String PROPERTY_SERIALIZER_INDENTATION =
+        "http://xmlpull.org/v1/doc/properties.html#serializer-indentation";
+    protected final String PROPERTY_SERIALIZER_LINE_SEPARATOR =
+        "http://xmlpull.org/v1/doc/properties.html#serializer-line-separator";
+    protected final static String PROPERTY_LOCATION =
+        "http://xmlpull.org/v1/doc/properties.html#location";
+
+    // properties/features
+    protected boolean namesInterned;
+    protected boolean attributeUseApostrophe;
+    protected String indentationString = null; //" ";
+    protected String lineSeparator = "\n";
+
+    protected String location;
+    protected Writer out;
+
+    protected int autoDeclaredPrefixes;
+
+    protected int depth = 0;
+
+    // element stack
+    protected String elNamespace[] = new String[ 2 ];
+    protected String elName[] = new String[ elNamespace.length ];
+    protected int elNamespaceCount[] = new int[ elNamespace.length ];
+
+    //namespace stack
+    protected int namespaceEnd = 0;
+    protected String namespacePrefix[] = new String[ 8 ];
+    protected String namespaceUri[] = new String[ namespacePrefix.length ];
+
+    protected boolean finished;
+    protected boolean pastRoot;
+    protected boolean setPrefixCalled;
+    protected boolean startTagIncomplete;
+
+    protected boolean doIndent;
+    protected boolean seenTag;
+
+    protected boolean seenBracket;
+    protected boolean seenBracketBracket;
+
+    // buffer output if needed to write escaped String see text(String)
+    private static final int BUF_LEN = Runtime.getRuntime().freeMemory() > 1000000L ? 8*1024 : 256;
+    protected char buf[] = new char[ BUF_LEN ];
+
+
+    protected static final String precomputedPrefixes[];
+
+    static {
+        precomputedPrefixes = new String[32]; //arbitrary number ...
+        for (int i = 0; i < precomputedPrefixes.length; i++)
+        {
+            precomputedPrefixes[i] = ("n"+i).intern();
+        }
+    }
+
+    private boolean checkNamesInterned = false;
+
+    private void checkInterning(String name) {
+        if(namesInterned && name != name.intern()) {
+            throw new IllegalArgumentException(
+                "all names passed as arguments must be interned"
+                    +"when NAMES INTERNED feature is enabled");
+        }
+    }
+
+    protected void reset() {
+        location = null;
+        out = null;
+        autoDeclaredPrefixes = 0;
+        depth = 0;
+
+        // nullify references on all levels to allow it to be GCed
+        for (int i = 0; i < elNamespaceCount.length; i++)
+        {
+            elName[ i ] = null;
+            elNamespace[ i ] = null;
+            elNamespaceCount[ i ] = 2;
+        }
+
+
+        namespaceEnd = 0;
+
+
+        //NOTE: no need to intern() as all literal strings and string-valued constant expressions
+        //are interned. String literals are defined in 3.10.5 of the Java Language Specification
+        // just checking ...
+        //assert "xmlns" == "xmlns".intern();
+        //assert XMLNS_URI == XMLNS_URI.intern();
+
+        //TODO: how to prevent from reporting this namespace?
+        // this is special namespace declared for consistency with XML infoset
+        namespacePrefix[ namespaceEnd ] = "xmlns";
+        namespaceUri[ namespaceEnd ] = XMLNS_URI;
+        ++namespaceEnd;
+
+        namespacePrefix[ namespaceEnd ] = "xml";
+        namespaceUri[ namespaceEnd ] = XML_URI;
+        ++namespaceEnd;
+
+        finished = false;
+        pastRoot = false;
+        setPrefixCalled = false;
+        startTagIncomplete = false;
+        //doIntent is not changed
+        seenTag = false;
+
+        seenBracket = false;
+        seenBracketBracket = false;
+    }
+
+
+    protected void ensureElementsCapacity() {
+        final int elStackSize = elName.length;
+        //assert (depth + 1) >= elName.length;
+        // we add at least one extra slot ...
+        final int newSize = (depth >= 7 ? 2 * depth : 8) + 2; // = lucky 7 + 1 //25
+        if(TRACE_SIZING) {
+            System.err.println(
+                getClass().getName()+" elStackSize "+elStackSize+" ==> "+newSize);
+        }
+        final boolean needsCopying = elStackSize > 0;
+        String[] arr = null;
+        // reuse arr local variable slot
+        arr = new String[newSize];
+        if(needsCopying) System.arraycopy(elName, 0, arr, 0, elStackSize);
+        elName = arr;
+        arr = new String[newSize];
+        if(needsCopying) System.arraycopy(elNamespace, 0, arr, 0, elStackSize);
+        elNamespace = arr;
+
+        final int[] iarr = new int[newSize];
+        if(needsCopying) {
+            System.arraycopy(elNamespaceCount, 0, iarr, 0, elStackSize);
+        } else {
+            // special initialization
+            iarr[0] = 0;
+        }
+        elNamespaceCount = iarr;
+    }
+
+    protected void ensureNamespacesCapacity() { //int size) {
+        //int namespaceSize = namespacePrefix != null ? namespacePrefix.length : 0;
+        //assert (namespaceEnd >= namespacePrefix.length);
+
+        //if(size >= namespaceSize) {
+        //int newSize = size > 7 ? 2 * size : 8; // = lucky 7 + 1 //25
+        final int newSize = namespaceEnd > 7 ? 2 * namespaceEnd : 8;
+        if(TRACE_SIZING) {
+            System.err.println(
+                getClass().getName()+" namespaceSize "+namespacePrefix.length+" ==> "+newSize);
+        }
+        final String[] newNamespacePrefix = new String[newSize];
+        final String[] newNamespaceUri = new String[newSize];
+        if(namespacePrefix != null) {
+            System.arraycopy(
+                namespacePrefix, 0, newNamespacePrefix, 0, namespaceEnd);
+            System.arraycopy(
+                namespaceUri, 0, newNamespaceUri, 0, namespaceEnd);
+        }
+        namespacePrefix = newNamespacePrefix;
+        namespaceUri = newNamespaceUri;
+
+        // TODO use hashes for quick namespace->prefix lookups
+        //            if( ! allStringsInterned ) {
+        //                int[] newNamespacePrefixHash = new int[newSize];
+        //                if(namespacePrefixHash != null) {
+        //                    System.arraycopy(
+        //                        namespacePrefixHash, 0, newNamespacePrefixHash, 0, namespaceEnd);
+        //                }
+        //                namespacePrefixHash = newNamespacePrefixHash;
+        //            }
+        //prefixesSize = newSize;
+        // ////assert nsPrefixes.length > size && nsPrefixes.length == newSize
+        //}
+    }
+
+
+    public void setFeature(String name,
+                           boolean state) throws IllegalArgumentException, IllegalStateException
+    {
+        if(name == null) {
+            throw new IllegalArgumentException("feature name can not be null");
+        }
+        if(FEATURE_NAMES_INTERNED.equals(name)) {
+            namesInterned = state;
+        } else if(FEATURE_SERIALIZER_ATTVALUE_USE_APOSTROPHE.equals(name)) {
+            attributeUseApostrophe = state;
+        } else {
+            throw new IllegalStateException("unsupported feature "+name);
+        }
+    }
+
+    public boolean getFeature(String name) throws IllegalArgumentException
+    {
+        if(name == null) {
+            throw new IllegalArgumentException("feature name can not be null");
+        }
+        if(FEATURE_NAMES_INTERNED.equals(name)) {
+            return namesInterned;
+        } else if(FEATURE_SERIALIZER_ATTVALUE_USE_APOSTROPHE.equals(name)) {
+            return attributeUseApostrophe;
+        } else {
+            return false;
+        }
+    }
+
+    // precomputed variables to simplify writing indentation
+    protected int offsetNewLine;
+    protected int indentationJump;
+    protected char[] indentationBuf;
+    protected int maxIndentLevel;
+    protected boolean writeLineSepartor; //should end-of-line be written
+    protected boolean writeIndentation; // is indentation used?
+
+    /**
+     * For maximum efficiency when writing indents the required output is pre-computed
+     * This is internal function that recomputes buffer after user requested chnages.
+     */
+    protected void rebuildIndentationBuf() {
+        if(doIndent == false) return;
+        final int maxIndent = 65; //hardcoded maximum indentation size in characters
+        int bufSize = 0;
+        offsetNewLine = 0;
+        if(writeLineSepartor) {
+            offsetNewLine = lineSeparator.length();
+            bufSize += offsetNewLine;
+        }
+        maxIndentLevel = 0;
+        if(writeIndentation) {
+            indentationJump = indentationString.length();
+            maxIndentLevel = maxIndent / indentationJump;
+            bufSize += maxIndentLevel * indentationJump;
+        }
+        if(indentationBuf == null || indentationBuf.length < bufSize) {
+            indentationBuf = new char[bufSize + 8];
+        }
+        int bufPos = 0;
+        if(writeLineSepartor) {
+            for (int i = 0; i < lineSeparator.length(); i++)
+            {
+                indentationBuf[ bufPos++ ] = lineSeparator.charAt(i);
+            }
+        }
+        if(writeIndentation) {
+            for (int i = 0; i < maxIndentLevel; i++)
+            {
+                for (int j = 0; j < indentationString.length(); j++)
+                {
+                    indentationBuf[ bufPos++ ] = indentationString.charAt(j);
+                }
+            }
+        }
+    }
+
+    // if(doIndent) writeIndent();
+    protected void writeIndent() throws IOException {
+        final int start = writeLineSepartor ? 0 : offsetNewLine;
+        final int level = (depth > maxIndentLevel) ? maxIndentLevel : depth;
+        out.write( indentationBuf, start, (level * indentationJump) + offsetNewLine);
+    }
+
+    public void setProperty(String name,
+                            Object value) throws IllegalArgumentException, IllegalStateException
+    {
+        if(name == null) {
+            throw new IllegalArgumentException("property name can not be null");
+        }
+        if(PROPERTY_SERIALIZER_INDENTATION.equals(name)) {
+            indentationString = (String)value;
+        } else if(PROPERTY_SERIALIZER_LINE_SEPARATOR.equals(name)) {
+            lineSeparator = (String)value;
+        } else if(PROPERTY_LOCATION.equals(name)) {
+            location = (String) value;
+        } else {
+            throw new IllegalStateException("unsupported property "+name);
+        }
+        writeLineSepartor = lineSeparator != null && lineSeparator.length() > 0;
+        writeIndentation = indentationString != null && indentationString.length() > 0;
+        // optimize - do not write when nothing to write ...
+        doIndent = indentationString != null && (writeLineSepartor || writeIndentation);
+        //NOTE: when indentationString == null there is no indentation
+        //      (even though writeLineSeparator may be true ...)
+        rebuildIndentationBuf();
+        seenTag = false; // for consistency
+    }
+
+    public Object getProperty(String name) throws IllegalArgumentException
+    {
+        if(name == null) {
+            throw new IllegalArgumentException("property name can not be null");
+        }
+        if(PROPERTY_SERIALIZER_INDENTATION.equals(name)) {
+            return indentationString;
+        } else if(PROPERTY_SERIALIZER_LINE_SEPARATOR.equals(name)) {
+            return lineSeparator;
+        } else if(PROPERTY_LOCATION.equals(name)) {
+            return location;
+        } else {
+            return null;
+        }
+    }
+
+    private String getLocation() {
+        return location != null ? " @"+location : "";
+    }
+
+    // this is special method that can be accessed directly to retrieve Writer serializer is using
+    public Writer getWriter()
+    {
+        return out;
+    }
+
+    public void setOutput(Writer writer)
+    {
+        reset();
+        out = writer;
+    }
+
+    public void setOutput(OutputStream os, String encoding) throws IOException
+    {
+        if(os == null) throw new IllegalArgumentException("output stream can not be null");
+        reset();
+        if(encoding != null) {
+            out = new OutputStreamWriter(os, encoding);
+        } else {
+            out = new OutputStreamWriter(os);
+        }
+    }
+
+    public void startDocument (String encoding, Boolean standalone) throws IOException
+    {
+        char apos = attributeUseApostrophe ? '\'' : '"';
+        if(attributeUseApostrophe) {
+            out.write("<?xml version='1.0'");
+        } else {
+            out.write("<?xml version=\"1.0\"");
+        }
+        if(encoding != null) {
+            out.write(" encoding=");
+            out.write(attributeUseApostrophe ? '\'' : '"');
+            out.write(encoding);
+            out.write(attributeUseApostrophe ? '\'' : '"');
+            //out.write('\'');
+        }
+        if(standalone != null) {
+            out.write(" standalone=");
+            out.write(attributeUseApostrophe ? '\'' : '"');
+            if(standalone.booleanValue()) {
+                out.write("yes");
+            } else {
+                out.write("no");
+            }
+            out.write(attributeUseApostrophe ? '\'' : '"');
+            //          if(standalone.booleanValue()) {
+            //              out.write(" standalone='yes'");
+            //          } else {
+            //              out.write(" standalone='no'");
+            //          }
+        }
+        out.write("?>");
+        if(writeLineSepartor) {
+            out.write(lineSeparator);
+        }
+    }
+
+    public void endDocument() throws IOException
+    {
+        // close all unclosed tag;
+        while(depth > 0) {
+            endTag(elNamespace[ depth ], elName[ depth ]);
+        }
+        if(writeLineSepartor) {
+            out.write(lineSeparator);
+        }
+        //assert depth == 0;
+        //assert startTagIncomplete == false;
+        finished = pastRoot = startTagIncomplete = true;
+        out.flush();
+    }
+
+    public void setPrefix(String prefix, String namespace) throws IOException
+    {
+        if(startTagIncomplete) closeStartTag();
+        //assert prefix != null;
+        //assert namespace != null;
+        if (prefix == null) {
+            prefix = "";
+        }
+        if(!namesInterned) {
+            prefix = prefix.intern(); //will throw NPE if prefix==null
+        } else if(checkNamesInterned) {
+            checkInterning(prefix);
+        } else if(prefix == null) {
+            throw new IllegalArgumentException("prefix must be not null"+getLocation());
+        }
+
+        //check that prefix is not duplicated ...
+        for (int i = elNamespaceCount[ depth ]; i < namespaceEnd; i++)
+        {
+            if(prefix == namespacePrefix[ i ]) {
+                throw new IllegalStateException("duplicated prefix "+printable(prefix)+getLocation());
+            }
+        }
+
+        if(!namesInterned) {
+            namespace = namespace.intern();
+        } else if(checkNamesInterned) {
+            checkInterning(namespace);
+        } else if(namespace == null) {
+            throw new IllegalArgumentException("namespace must be not null"+getLocation());
+        }
+
+        if(namespaceEnd >= namespacePrefix.length) {
+            ensureNamespacesCapacity();
+        }
+        namespacePrefix[ namespaceEnd ] = prefix;
+        namespaceUri[ namespaceEnd ] = namespace;
+        ++namespaceEnd;
+        setPrefixCalled = true;
+    }
+
+    protected String lookupOrDeclarePrefix( String namespace ) {
+        return getPrefix(namespace, true);
+    }
+
+    public String getPrefix(String namespace, boolean generatePrefix)
+    {
+        //assert namespace != null;
+        if(!namesInterned) {
+            // when String is interned we can do much faster namespace stack lookups ...
+            namespace = namespace.intern();
+        } else if(checkNamesInterned) {
+            checkInterning(namespace);
+            //assert namespace != namespace.intern();
+        }
+        if(namespace == null) {
+            throw new IllegalArgumentException("namespace must be not null"+getLocation());
+        } else if(namespace.length() == 0) {
+            throw new IllegalArgumentException("default namespace cannot have prefix"+getLocation());
+        }
+
+        // first check if namespace is already in scope
+        for (int i = namespaceEnd - 1; i >= 0 ; --i)
+        {
+            if(namespace == namespaceUri[ i ]) {
+                final String prefix = namespacePrefix[ i ];
+                // now check that prefix is still in scope
+                for (int p = namespaceEnd - 1; p > i ; --p)
+                {
+                    if(prefix == namespacePrefix[ p ])
+                        continue; // too bad - prefix is redeclared with different namespace
+                }
+                return prefix;
+            }
+        }
+
+        // so not found it ...
+        if(!generatePrefix) {
+            return null;
+        }
+        return generatePrefix(namespace);
+    }
+
+    private String generatePrefix(String namespace) {
+        //assert namespace == namespace.intern();
+        while(true) {
+            ++autoDeclaredPrefixes;
+            //fast lookup uses table that was pre-initialized in static{} ....
+            final String prefix = autoDeclaredPrefixes < precomputedPrefixes.length
+                ? precomputedPrefixes[autoDeclaredPrefixes] : ("n"+autoDeclaredPrefixes).intern();
+            // make sure this prefix is not declared in any scope (avoid hiding in-scope prefixes)!
+            for (int i = namespaceEnd - 1; i >= 0 ; --i)
+            {
+                if(prefix == namespacePrefix[ i ]) {
+                    continue; // prefix is already declared - generate new and try again
+                }
+            }
+            // declare prefix
+
+            if(namespaceEnd >= namespacePrefix.length) {
+                ensureNamespacesCapacity();
+            }
+            namespacePrefix[ namespaceEnd ] = prefix;
+            namespaceUri[ namespaceEnd ] = namespace;
+            ++namespaceEnd;
+
+            return prefix;
+        }
+    }
+
+    public int getDepth()
+    {
+        return depth;
+    }
+
+    public String getNamespace ()
+    {
+        return elNamespace[depth];
+    }
+
+    public String getName()
+    {
+        return elName[depth];
+    }
+
+    public XmlSerializer startTag (String namespace, String name) throws IOException
+    {
+
+        if(startTagIncomplete) {
+            closeStartTag();
+        }
+        seenBracket = seenBracketBracket = false;
+        if(doIndent && depth > 0 && seenTag) {
+            writeIndent();
+        }
+        seenTag = true;
+        setPrefixCalled = false;
+        startTagIncomplete = true;
+        ++depth;
+        if( (depth + 1) >= elName.length) {
+            ensureElementsCapacity();
+        }
+        ////assert namespace != null;
+
+        if(checkNamesInterned && namesInterned) checkInterning(namespace);
+        elNamespace[ depth ] = (namesInterned || namespace == null) ? namespace : namespace.intern();
+        //assert name != null;
+        //elName[ depth ] = name;
+        if(checkNamesInterned && namesInterned) checkInterning(name);
+        elName[ depth ] = (namesInterned || name == null) ? name : name.intern();
+        if(out == null) {
+            throw new IllegalStateException("setOutput() must called set before serialization can start");
+        }
+        out.write('<');
+        if(namespace != null)  {
+
+            if(namespace.length() > 0) {
+                //ALEK: in future make it as feature on serializer
+                String prefix = null;
+                if(depth > 0 && (namespaceEnd - elNamespaceCount[depth-1]) == 1) {
+                    // if only one prefix was declared un-declare it if prefix is already declared on parent el with the same URI
+                    String uri = namespaceUri[namespaceEnd-1];
+                    if(uri == namespace || uri.equals(namespace)) {
+                        String elPfx = namespacePrefix[namespaceEnd-1];
+                        // 2 == to skip predefined namespaces (xml and xmlns ...)
+                        for(int pos = elNamespaceCount[depth-1] - 1; pos >= 2; --pos ) {
+                            String pf = namespacePrefix[pos];
+                            if(pf == elPfx || pf.equals(elPfx)) {
+                                String n = namespaceUri[pos];
+                                if(n == uri || n.equals(uri)) {
+                                    --namespaceEnd; //un-declare namespace
+                                    prefix = elPfx;
+                                }
+                                break;
+                            }
+                        }
+                    }
+                }
+                if(prefix == null) {
+                    prefix = lookupOrDeclarePrefix( namespace );
+                }
+                //assert prefix != null;
+                // make sure that default ("") namespace to not print ":"
+                if(prefix.length() > 0) {
+                    out.write(prefix);
+                    out.write(':');
+                }
+            } else {
+                // make sure that default namespace can be declared
+                for (int i = namespaceEnd - 1; i >= 0 ; --i)
+                {
+                    if(namespacePrefix[ i ] == "") {
+                        final String uri = namespaceUri[ i ];
+                        if(uri == null) {
+                            // declare default namespace
+                            setPrefix("", "");
+                        } else if(uri.length() > 0) {
+                            throw new IllegalStateException(
+                                "start tag can not be written in empty default namespace "+
+                                    "as default namespace is currently bound to '"+uri+"'"+getLocation());
+                        }
+                        break;
+                    }
+                }
+            }
+
+        }
+        out.write(name);
+        return this;
+    }
+
+    public XmlSerializer attribute (String namespace, String name,
+                                    String value) throws IOException
+    {
+        if(!startTagIncomplete) {
+            throw new IllegalArgumentException("startTag() must be called before attribute()"+getLocation());
+        }
+        //assert setPrefixCalled == false;
+        out.write(' ');
+        ////assert namespace != null;
+        if(namespace != null && namespace.length() > 0) {
+            //namespace = namespace.intern();
+            if(!namesInterned) {
+                namespace = namespace.intern();
+            } else if(checkNamesInterned) {
+                checkInterning(namespace);
+            }
+            String prefix = lookupOrDeclarePrefix( namespace );
+            //assert( prefix != null);
+            if(prefix.length() == 0) {
+                // needs to declare prefix to hold default namespace
+                //NOTE: attributes such as a='b' are in NO namespace
+                prefix = generatePrefix(namespace);
+            }
+            out.write(prefix);
+            out.write(':');
+            //            if(prefix.length() > 0) {
+            //                out.write(prefix);
+            //                out.write(':');
+            //            }
+        }
+        //assert name != null;
+        out.write(name);
+        out.write('=');
+        //assert value != null;
+        out.write( attributeUseApostrophe ? '\'' : '"');
+        writeAttributeValue(value, out);
+        out.write( attributeUseApostrophe ? '\'' : '"');
+        return this;
+    }
+
+    protected void closeStartTag() throws IOException {
+        if(finished) {
+            throw new IllegalArgumentException("trying to write past already finished output"+getLocation());
+        }
+        if(seenBracket) {
+            seenBracket = seenBracketBracket = false;
+        }
+        if( startTagIncomplete || setPrefixCalled ) {
+            if(setPrefixCalled) {
+                throw new IllegalArgumentException(
+                    "startTag() must be called immediately after setPrefix()"+getLocation());
+            }
+            if(!startTagIncomplete) {
+                throw new IllegalArgumentException("trying to close start tag that is not opened"+getLocation());
+            }
+
+            // write all namespace declarations!
+            writeNamespaceDeclarations();
+            out.write('>');
+            elNamespaceCount[ depth ] = namespaceEnd;
+            startTagIncomplete = false;
+        }
+    }
+
+    private void writeNamespaceDeclarations() throws IOException
+    {
+        //int start = elNamespaceCount[ depth - 1 ];
+        for (int i = elNamespaceCount[ depth - 1 ]; i < namespaceEnd; i++)
+        {
+            if(doIndent && namespaceUri[ i ].length() > 40) {
+                writeIndent();
+                out.write(" ");
+            }
+            if(namespacePrefix[ i ] != "") {
+                out.write(" xmlns:");
+                out.write(namespacePrefix[ i ]);
+                out.write('=');
+            } else {
+                out.write(" xmlns=");
+            }
+            out.write( attributeUseApostrophe ? '\'' : '"');
+
+            //NOTE: escaping of namespace value the same way as attributes!!!!
+            writeAttributeValue(namespaceUri[ i ], out);
+
+            out.write( attributeUseApostrophe ? '\'' : '"');
+        }
+    }
+
+    public XmlSerializer endTag(String namespace, String name) throws IOException
+    {
+        // check that level is valid
+        ////assert namespace != null;
+        //if(namespace != null) {
+        //    namespace = namespace.intern();
+        //}
+        seenBracket = seenBracketBracket = false;
+        if(namespace != null) {
+            if(!namesInterned) {
+                namespace = namespace.intern();
+            } else if(checkNamesInterned) {
+                checkInterning(namespace);
+            }
+        }
+
+        if(namespace != elNamespace[ depth ])
+        {
+            throw new IllegalArgumentException(
+                "expected namespace "+printable(elNamespace[ depth ])
+                    +" and not "+printable(namespace)+getLocation());
+        }
+        if(name == null) {
+            throw new IllegalArgumentException("end tag name can not be null"+getLocation());
+        }
+        if(checkNamesInterned && namesInterned) {
+            checkInterning(name);
+        }
+
+        if((!namesInterned && !name.equals(elName[ depth ]))
+               || (namesInterned && name != elName[ depth ]))
+        {
+            throw new IllegalArgumentException(
+                "expected element name "+printable(elName[ depth ])+" and not "+printable(name)+getLocation());
+        }
+        if(startTagIncomplete) {
+            writeNamespaceDeclarations();
+            out.write(" />"); //space is added to make it easier to work in XHTML!!!
+            --depth;
+        } else {
+            --depth;
+            //assert startTagIncomplete == false;
+            if(doIndent && seenTag) { writeIndent(); }
+            out.write("</");
+            if(namespace != null && namespace.length() > 0) {
+                //TODO prefix should be alredy known from matching start tag ...
+                final String prefix = lookupOrDeclarePrefix( namespace );
+                //assert( prefix != null);
+                if(prefix.length() > 0) {
+                    out.write(prefix);
+                    out.write(':');
+                }
+            }
+            out.write(name);
+            out.write('>');
+
+        }
+        namespaceEnd = elNamespaceCount[ depth ];
+        startTagIncomplete = false;
+        seenTag = true;
+        return this;
+    }
+
+    public XmlSerializer text (String text) throws IOException
+    {
+        //assert text != null;
+        if(startTagIncomplete || setPrefixCalled) closeStartTag();
+        if(doIndent && seenTag) seenTag = false;
+        writeElementContent(text, out);
+        return this;
+    }
+
+    public XmlSerializer text (char [] buf, int start, int len) throws IOException
+    {
+        if(startTagIncomplete || setPrefixCalled) closeStartTag();
+        if(doIndent && seenTag) seenTag = false;
+        writeElementContent(buf, start, len, out);
+        return this;
+    }
+
+    public void cdsect (String text)  throws IOException
+    {
+        if(startTagIncomplete || setPrefixCalled || seenBracket) closeStartTag();
+        if(doIndent && seenTag) seenTag = false;
+        out.write("<![CDATA[");
+        out.write(text); //escape?
+        out.write("]]>");
+    }
+
+    public void entityRef (String text)  throws IOException
+    {
+        if(startTagIncomplete || setPrefixCalled || seenBracket) closeStartTag();
+        if(doIndent && seenTag) seenTag = false;
+        out.write('&');
+        out.write(text); //escape?
+        out.write(';');
+    }
+
+    public void processingInstruction (String text)  throws IOException
+    {
+        if(startTagIncomplete || setPrefixCalled || seenBracket) closeStartTag();
+        if(doIndent && seenTag) seenTag = false;
+        out.write("<?");
+        out.write(text); //escape?
+        out.write("?>");
+    }
+
+    public void comment (String text)  throws IOException
+    {
+        if(startTagIncomplete || setPrefixCalled || seenBracket) closeStartTag();
+        if(doIndent && seenTag) seenTag = false;
+        out.write("<!--");
+        out.write(text); //escape?
+        out.write("-->");
+    }
+
+    public void docdecl (String text)  throws IOException
+    {
+        if(startTagIncomplete || setPrefixCalled || seenBracket) closeStartTag();
+        if(doIndent && seenTag) seenTag = false;
+        out.write("<!DOCTYPE ");
+        out.write(text); //escape?
+        out.write(">");
+    }
+
+    public void ignorableWhitespace (String text)  throws IOException
+    {
+        if(startTagIncomplete || setPrefixCalled || seenBracket) closeStartTag();
+        if(doIndent && seenTag) seenTag = false;
+        if(text.length() == 0) {
+            throw new IllegalArgumentException(
+                "empty string is not allowed for ignorable whitespace"+getLocation());
+        }
+        out.write(text); //no escape?
+    }
+
+    public void flush () throws IOException
+    {
+        if(!finished && startTagIncomplete) closeStartTag();
+        out.flush();
+    }
+
+    // --- utility methods
+
+    protected void writeAttributeValue(String value, Writer out) throws IOException
+    {
+        //.[apostrophe and <, & escaped],
+        final char quot = attributeUseApostrophe ? '\'' : '"';
+        final String quotEntity = attributeUseApostrophe ? "&apos;" : "&quot;";
+
+        int pos = 0;
+        for (int i = 0; i < value.length(); i++)
+        {
+            char ch = value.charAt(i);
+            if(ch == '&') {
+                if(i > pos) out.write(value.substring(pos, i));
+                out.write("&amp;");
+                pos = i + 1;
+            } if(ch == '<') {
+                if(i > pos) out.write(value.substring(pos, i));
+                out.write("&lt;");
+                pos = i + 1;
+            }else if(ch == quot) {
+                if(i > pos) out.write(value.substring(pos, i));
+                out.write(quotEntity);
+                pos = i + 1;
+            } else if(ch < 32) {
+                //in XML 1.0 only legal character are #x9 | #xA | #xD
+                // and they must be escaped otherwise in attribute value they are normalized to spaces
+                if(ch == 13 || ch == 10 || ch == 9) {
+                    if(i > pos) out.write(value.substring(pos, i));
+                    out.write("&#");
+                    out.write(Integer.toString(ch));
+                    out.write(';');
+                    pos = i + 1;
+                } else {
+                    throw new IllegalStateException(
+                        "character "+Integer.toString(ch)+" is not allowed in output"+getLocation());
+                    // in XML 1.1 legal are [#x1-#xD7FF]
+                    //              if(ch > 0) {
+                    //                  if(i > pos) out.write(text.substring(pos, i));
+                    //                  out.write("&#");
+                    //                  out.write(Integer.toString(ch));
+                    //                  out.write(';');
+                    //                  pos = i + 1;
+                    //              } else {
+                    //              throw new IllegalStateException(
+                    //                  "character zero is not allowed in XML 1.1 output"+getLocation());
+                    //              }
+                }
+            }
+        }
+        if(pos > 0) {
+            out.write(value.substring(pos));
+        } else {
+            out.write(value);  // this is shortcut to the most common case
+        }
+
+    }
+
+    protected void writeElementContent(String text, Writer out) throws IOException
+    {
+        // escape '<', '&', ']]>', <32 if necessary
+        int pos = 0;
+        for (int i = 0; i < text.length(); i++)
+        {
+            //TODO: check if doing char[] text.getChars() would be faster than getCharAt(i) ...
+            char ch = text.charAt(i);
+            if(ch == ']') {
+                if(seenBracket) {
+                    seenBracketBracket = true;
+                } else {
+                    seenBracket = true;
+                }
+            } else {
+                if(ch == '&') {
+                    if(i > pos) out.write(text.substring(pos, i));
+                    out.write("&amp;");
+                    pos = i + 1;
+                } else if(ch == '<') {
+                    if(i > pos) out.write(text.substring(pos, i));
+                    out.write("&lt;");
+                    pos = i + 1;
+                } else if(seenBracketBracket && ch == '>') {
+                    if(i > pos) out.write(text.substring(pos, i));
+                    out.write("&gt;");
+                    pos = i + 1;
+                } else if(ch < 32) {
+                    //in XML 1.0 only legal character are #x9 | #xA | #xD
+                    if( ch == 9 || ch == 10 || ch == 13) {
+                        // pass through
+
+                        //                    } else if(ch == 13) { //escape
+                        //                        if(i > pos) out.write(text.substring(pos, i));
+                        //                        out.write("&#");
+                        //                        out.write(Integer.toString(ch));
+                        //                        out.write(';');
+                        //                        pos = i + 1;
+                    } else {
+                        throw new IllegalStateException(
+                            "character "+Integer.toString(ch)+" is not allowed in output"+getLocation());
+                        // in XML 1.1 legal are [#x1-#xD7FF]
+                        //              if(ch > 0) {
+                        //                  if(i > pos) out.write(text.substring(pos, i));
+                        //                  out.write("&#");
+                        //                  out.write(Integer.toString(ch));
+                        //                  out.write(';');
+                        //                  pos = i + 1;
+                        //              } else {
+                        //              throw new IllegalStateException(
+                        //                  "character zero is not allowed in XML 1.1 output"+getLocation());
+                        //              }
+                    }
+                }
+                if(seenBracket) {
+                    seenBracketBracket = seenBracket = false;
+                }
+
+            }
+        }
+        if(pos > 0) {
+            out.write(text.substring(pos));
+        } else {
+            out.write(text);  // this is shortcut to the most common case
+        }
+
+
+
+    }
+
+    protected void writeElementContent(char[] buf, int off, int len, Writer out) throws IOException
+    {
+        // escape '<', '&', ']]>'
+        final int end = off + len;
+        int pos = off;
+        for (int i = off; i < end; i++)
+        {
+            final char ch = buf[i];
+            if(ch == ']') {
+                if(seenBracket) {
+                    seenBracketBracket = true;
+                } else {
+                    seenBracket = true;
+                }
+            } else {
+                if(ch == '&') {
+                    if(i > pos) {
+                        out.write(buf, pos, i - pos);
+                    }
+                    out.write("&amp;");
+                    pos = i + 1;
+                } else if(ch == '<') {
+                    if(i > pos) {
+                        out.write(buf, pos, i - pos);
+                    }
+                    out.write("&lt;");
+                    pos = i + 1;
+
+                } else if(seenBracketBracket && ch == '>') {
+                    if(i > pos) {
+                        out.write(buf, pos, i - pos);
+                    }
+                    out.write("&gt;");
+                    pos = i + 1;
+                } else if(ch < 32) {
+                    //in XML 1.0 only legal character are #x9 | #xA | #xD
+                    if( ch == 9 || ch == 10 || ch == 13) {
+                        // pass through
+
+
+                        //                    } else if(ch == 13 ) { //if(ch == '\r') {
+                        //                        if(i > pos) {
+                        //                            out.write(buf, pos, i - pos);
+                        //                        }
+                        //                        out.write("&#");
+                        //                        out.write(Integer.toString(ch));
+                        //                        out.write(';');
+                        //                        pos = i + 1;
+                    } else {
+                        throw new IllegalStateException(
+                            "character "+Integer.toString(ch)+" is not allowed in output"+getLocation());
+                        // in XML 1.1 legal are [#x1-#xD7FF]
+                        //              if(ch > 0) {
+                        //                  if(i > pos) out.write(text.substring(pos, i));
+                        //                  out.write("&#");
+                        //                  out.write(Integer.toString(ch));
+                        //                  out.write(';');
+                        //                  pos = i + 1;
+                        //              } else {
+                        //              throw new IllegalStateException(
+                        //                  "character zero is not allowed in XML 1.1 output"+getLocation());
+                        //              }
+                    }
+                }
+                if(seenBracket) {
+                    seenBracketBracket = seenBracket = false;
+                }
+                // assert seenBracketBracket == seenBracket == false;
+            }
+        }
+        if(end > pos) {
+            out.write(buf, pos, end - pos);
+        }
+    }
+
+    /** simple utility method -- good for debugging */
+    protected static final String printable(String s) {
+        if(s == null) return "null";
+        StringBuffer retval = new StringBuffer(s.length() + 16);
+        retval.append("'");
+        char ch;
+        for (int i = 0; i < s.length(); i++) {
+            addPrintable(retval, s.charAt(i));
+        }
+        retval.append("'");
+        return retval.toString();
+    }
+
+    protected static final String printable(char ch) {
+        StringBuffer retval = new StringBuffer();
+        addPrintable(retval, ch);
+        return retval.toString();
+    }
+
+    private static void addPrintable(StringBuffer retval, char ch)
+    {
+        switch (ch)
+        {
+            case '\b':
+                retval.append("\\b");
+                break;
+            case '\t':
+                retval.append("\\t");
+                break;
+            case '\n':
+                retval.append("\\n");
+                break;
+            case '\f':
+                retval.append("\\f");
+                break;
+            case '\r':
+                retval.append("\\r");
+                break;
+            case '\"':
+                retval.append("\\\"");
+                break;
+            case '\'':
+                retval.append("\\\'");
+                break;
+            case '\\':
+                retval.append("\\\\");
+                break;
+            default:
+                if (ch  < 0x20 || ch > 0x7e) {
+                    final String ss = "0000" + Integer.toString(ch, 16);
+                    retval.append("\\u" + ss.substring(ss.length() - 4, ss.length()));
+                } else {
+                    retval.append(ch);
+                }
+        }
+    }
+
+}
+
+

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/xml/pull/MXSerializer.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/pull/MXSerializer.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/pull/MXSerializer.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain