You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ws.apache.org by ve...@apache.org on 2013/07/20 18:51:17 UTC

svn commit: r1505170 - in /webservices/axiom/trunk/modules: axiom-api/src/main/java/org/apache/axiom/om/ axiom-api/src/main/java/org/apache/axiom/om/impl/builder/ axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/ axiom-dom/src/main/java/...

Author: veithen
Date: Sat Jul 20 16:51:16 2013
New Revision: 1505170

URL: http://svn.apache.org/r1505170
Log:
Added a getSAXResult method to OMContainer. That method allows to append child nodes to an OMContainer using a SAXResult and is required for AXIOM-447.

Added:
    webservices/axiom/trunk/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/OMContentHandler.java
      - copied, changed from r1504786, webservices/axiom/trunk/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/SAXOMBuilder.java
    webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/SAXResultContentHandler.java   (with props)
    webservices/axiom/trunk/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/document/TestGetSAXResult.java
      - copied, changed from r1503989, webservices/axiom/trunk/modules/axiom-api/src/test/java/org/apache/axiom/om/impl/jaxp/StreamSourceToOMResultTestCase.java
    webservices/axiom/trunk/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestGetSAXResultWithDTD.java   (with props)
Modified:
    webservices/axiom/trunk/modules/axiom-api/src/main/java/org/apache/axiom/om/OMContainer.java
    webservices/axiom/trunk/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/SAXOMBuilder.java
    webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/OMContainerHelper.java
    webservices/axiom/trunk/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/ParentNode.java
    webservices/axiom/trunk/modules/axiom-dom/src/test/java/org/apache/axiom/om/impl/dom/OMImplementationTest.java
    webservices/axiom/trunk/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMDocumentImpl.java
    webservices/axiom/trunk/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMElementImpl.java
    webservices/axiom/trunk/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMSourcedElementImpl.java
    webservices/axiom/trunk/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/OMTestSuiteBuilder.java
    webservices/axiom/trunk/modules/axiom-testutils/src/main/java/org/apache/axiom/testutils/suite/XSLTImplementation.java

Modified: webservices/axiom/trunk/modules/axiom-api/src/main/java/org/apache/axiom/om/OMContainer.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/modules/axiom-api/src/main/java/org/apache/axiom/om/OMContainer.java?rev=1505170&r1=1505169&r2=1505170&view=diff
==============================================================================
--- webservices/axiom/trunk/modules/axiom-api/src/main/java/org/apache/axiom/om/OMContainer.java (original)
+++ webservices/axiom/trunk/modules/axiom-api/src/main/java/org/apache/axiom/om/OMContainer.java Sat Jul 20 16:51:16 2013
@@ -23,6 +23,7 @@ import javax.xml.namespace.QName;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
 import javax.xml.transform.Transformer;
+import javax.xml.transform.sax.SAXResult;
 import javax.xml.transform.sax.SAXSource;
 
 import org.apache.axiom.ext.stax.datahandler.DataHandlerReader;
@@ -411,4 +412,31 @@ public interface OMContainer extends OMS
      * @return a {@link SAXSource} representation of this element
      */
     SAXSource getSAXSource(boolean cache);
+    
+    /**
+     * Get a {@link SAXResult} object that can be used to append child nodes to this container. Note
+     * that existing child nodes will not be removed. In order to replace the content of the
+     * container, call {@link #removeChildren()} first.
+     * <p>
+     * The SAX content handler linked to the returned {@link SAXResult} supports
+     * {@link ContentHandler}, {@link LexicalHandler} and {@link DeclHandler}. DTD related events
+     * are processed in the following way:
+     * <ul>
+     * <li>A {@link LexicalHandler#startDTD(String, String, String)} events will create an
+     * {@link OMDocType} if the container is an {@link OMDocument}. If the container is an
+     * {@link OMElement}, the event will be ignored silently.
+     * <li>Entity references are always replaced, i.e. no {@link OMEntityReference} objects are
+     * created for {@link LexicalHandler#startEntity(String)} events.
+     * </ul>
+     * <p>
+     * Nodes created by the {@link ContentHandler} linked to the returned {@link SAXResult} will
+     * have the same characteristics as programmatically created nodes; in particular they will have
+     * no associated builder.
+     * 
+     * @return the {@link SAXResult} object
+     * 
+     * @see OMXMLBuilderFactory#createOMBuilder(SAXSource, boolean)
+     * @see OMXMLBuilderFactory#createOMBuilder(OMFactory, SAXSource, boolean)
+     */
+    SAXResult getSAXResult();
 }

Copied: webservices/axiom/trunk/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/OMContentHandler.java (from r1504786, webservices/axiom/trunk/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/SAXOMBuilder.java)
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/OMContentHandler.java?p2=webservices/axiom/trunk/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/OMContentHandler.java&p1=webservices/axiom/trunk/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/SAXOMBuilder.java&r1=1504786&r2=1505170&rev=1505170&view=diff
==============================================================================
--- webservices/axiom/trunk/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/SAXOMBuilder.java (original)
+++ webservices/axiom/trunk/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/OMContentHandler.java Sat Jul 20 16:51:16 2013
@@ -16,41 +16,32 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
 package org.apache.axiom.om.impl.builder;
 
-import org.apache.axiom.om.OMAbstractFactory;
 import org.apache.axiom.om.OMAttribute;
-import org.apache.axiom.om.OMDocument;
+import org.apache.axiom.om.OMContainer;
 import org.apache.axiom.om.OMElement;
-import org.apache.axiom.om.OMException;
-import org.apache.axiom.om.OMFactory;
 import org.apache.axiom.om.OMNamespace;
 import org.apache.axiom.om.OMNode;
-import org.apache.axiom.om.OMXMLBuilderFactory;
-import org.apache.axiom.om.OMXMLParserWrapper;
-import org.apache.axiom.om.impl.OMContainerEx;
-import org.apache.axiom.om.impl.OMElementEx;
 import org.xml.sax.Attributes;
 import org.xml.sax.Locator;
 import org.xml.sax.SAXException;
-import org.xml.sax.XMLReader;
 import org.xml.sax.ext.DeclHandler;
 import org.xml.sax.ext.LexicalHandler;
 import org.xml.sax.helpers.DefaultHandler;
 
-import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
 
 import javax.xml.XMLConstants;
-import javax.xml.transform.sax.SAXSource;
 
-public class SAXOMBuilder extends DefaultHandler implements LexicalHandler, DeclHandler, OMXMLParserWrapper {
-    private final SAXSource source;
+/**
+ * For internal use only.
+ */
+public abstract class OMContentHandler extends DefaultHandler implements LexicalHandler, DeclHandler {
     private final boolean expandEntityReferences;
     
-    private OMDocument document;
+    private OMContainer root;
     
     /**
      * Stores the root name if there is a DTD.
@@ -82,7 +73,7 @@ public class SAXOMBuilder extends Defaul
      */
     private boolean inExternalSubset;
     
-    private OMContainerEx target;
+    private OMContainer target;
 
     /**
      * Stores namespace declarations reported to {@link #startPrefixMapping(String, String)}. These
@@ -97,68 +88,38 @@ public class SAXOMBuilder extends Defaul
      */
     private int namespaceCount;
 
-    private final OMFactoryEx factory;
-
     private int textNodeType = OMNode.TEXT_NODE;
     
     private boolean inEntityReference;
     private int entityReferenceDepth;
 
-    /**
-     * For internal use only.
-     * 
-     * @param factory
-     * @param source
-     * @param expandEntityReferences
-     */
-    public SAXOMBuilder(OMFactory factory, SAXSource source, boolean expandEntityReferences) {
-        this.factory = (OMFactoryEx)factory;
-        this.source = source;
+    public OMContentHandler(boolean expandEntityReferences) {
         this.expandEntityReferences = expandEntityReferences;
     }
     
-    /**
-     * @deprecated Instead of creating an instance of this class directly, create a
-     *             {@link SAXSource} and use
-     *             {@link OMXMLBuilderFactory#createOMBuilder(OMFactory, SAXSource, boolean)}.
-     */
-    public SAXOMBuilder(OMFactory factory) {
-        this(factory, null, true);
-    }
-    
-    /**
-     * @deprecated Instead of creating an instance of this class directly, create a
-     *             {@link SAXSource} and use
-     *             {@link OMXMLBuilderFactory#createOMBuilder(SAXSource, boolean)}.
-     */
-    public SAXOMBuilder() {
-        this(OMAbstractFactory.getOMFactory());
-    }
-    
-    public void setDocumentLocator(Locator locator) {
+    public final void setDocumentLocator(Locator locator) {
     }
 
-    public void startDocument() throws SAXException {
-        document = factory.createOMDocument(this);
-        target = (OMContainerEx)document;
+    public final void startDocument() throws SAXException {
+        target = root = doStartDocument();
     }
 
-    public void endDocument() throws SAXException {
-        if (target != document) {
+    public final void endDocument() throws SAXException {
+        if (target != root) {
             throw new IllegalStateException();
         }
-        target.setComplete(true);
+        doEndDocument();
         target = null;
     }
 
-    public void startDTD(String name, String publicId, String systemId) throws SAXException {
+    public final void startDTD(String name, String publicId, String systemId) throws SAXException {
         dtdName = name;
         dtdPublicId = publicId;
         dtdSystemId = systemId;
         internalSubset = new StringBuilder();
     }
 
-    public void elementDecl(String name, String model) throws SAXException {
+    public final void elementDecl(String name, String model) throws SAXException {
         if (!inExternalSubset) {
             internalSubset.append("<!ELEMENT ");
             internalSubset.append(name);
@@ -168,7 +129,7 @@ public class SAXOMBuilder extends Defaul
         }
     }
 
-    public void attributeDecl(String eName, String aName, String type, String mode, String value)
+    public final void attributeDecl(String eName, String aName, String type, String mode, String value)
             throws SAXException {
         if (!inExternalSubset) {
             internalSubset.append("<!ATTLIST ");
@@ -185,7 +146,7 @@ public class SAXOMBuilder extends Defaul
         }
     }
 
-    public void externalEntityDecl(String name, String publicId, String systemId) throws SAXException {
+    public final void externalEntityDecl(String name, String publicId, String systemId) throws SAXException {
         if (!inExternalSubset) {
             internalSubset.append("<!ENTITY ");            
             internalSubset.append(name);
@@ -200,7 +161,7 @@ public class SAXOMBuilder extends Defaul
         }
     }
 
-    public void internalEntityDecl(String name, String value) throws SAXException {
+    public final void internalEntityDecl(String name, String value) throws SAXException {
         if (entities == null) {
             entities = new HashMap();
         }
@@ -214,7 +175,7 @@ public class SAXOMBuilder extends Defaul
         }
     }
 
-    public void notationDecl(String name, String publicId, String systemId) throws SAXException {
+    public final void notationDecl(String name, String publicId, String systemId) throws SAXException {
         if (!inExternalSubset) {
             internalSubset.append("<!NOTATION ");            
             internalSubset.append(name);
@@ -229,7 +190,7 @@ public class SAXOMBuilder extends Defaul
         }
     }
 
-    public void unparsedEntityDecl(String name, String publicId, String systemId, String notationName)
+    public final void unparsedEntityDecl(String name, String publicId, String systemId, String notationName)
             throws SAXException {
         if (!inExternalSubset) {
             internalSubset.append("<!ENTITY ");
@@ -247,9 +208,9 @@ public class SAXOMBuilder extends Defaul
         }
     }
 
-    public void endDTD() throws SAXException {
-        factory.createOMDocType(target, dtdName, dtdPublicId, dtdSystemId,
-                internalSubset.length() == 0 ? null : internalSubset.toString(), true);
+    public final void endDTD() throws SAXException {
+        createOMDocType(target, dtdName, dtdPublicId, dtdSystemId,
+                internalSubset.length() == 0 ? null : internalSubset.toString());
         internalSubset = null;
     }
 
@@ -259,7 +220,7 @@ public class SAXOMBuilder extends Defaul
      * @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String,
      *      java.lang.String)
      */
-    public void startPrefixMapping(String prefix, String uri)
+    public final void startPrefixMapping(String prefix, String uri)
             throws SAXException {
         if (!inEntityReference) {
             int index = namespaceCount*2;
@@ -274,7 +235,7 @@ public class SAXOMBuilder extends Defaul
         }
     }
 
-    public void endPrefixMapping(String prefix) throws SAXException {
+    public final void endPrefixMapping(String prefix) throws SAXException {
     }
 
     /*
@@ -283,22 +244,16 @@ public class SAXOMBuilder extends Defaul
      * @see org.xml.sax.ContentHandler#startElement(java.lang.String,
      *      java.lang.String, java.lang.String, org.xml.sax.Attributes)
      */
-    public void startElement(String namespaceURI, String localName,
+    public final void startElement(String namespaceURI, String localName,
                              String qName, Attributes atts) throws SAXException {
         if (!inEntityReference) {
             if (localName == null || localName.trim().equals(""))
                 localName = qName.substring(qName.indexOf(':') + 1);
-            OMElement element = factory.createOMElement(localName, target, this);
-            
-            for (int i = 0; i < namespaceCount; i++) {
-                ((OMElementEx)element).addNamespaceDeclaration(namespaces[2*i+1], namespaces[2*i]);
-            }
-            namespaceCount = 0;
-    
             int idx = qName.indexOf(':');
             String prefix = idx == -1 ? "" : qName.substring(0, idx);
-            BuilderUtil.setNamespace(element, namespaceURI, prefix, false);
-            
+            OMElement element = createOMElement(target, localName, namespaceURI, prefix, namespaces, namespaceCount);
+            namespaceCount = 0;
+    
             int j = atts.getLength();
             for (int i = 0; i < j; i++) {
                 // Note that some SAX parsers report namespace declarations as attributes in addition
@@ -316,7 +271,7 @@ public class SAXOMBuilder extends Defaul
                             // The "xml" prefix is not necessarily declared explicitly; in this case,
                             // create a new OMNamespace instance.
                             if (attrNamespaceURI.equals(XMLConstants.XML_NS_URI)) {
-                                ns = factory.createOMNamespace(XMLConstants.XML_NS_URI, XMLConstants.XML_NS_PREFIX);
+                                ns = element.getOMFactory().createOMNamespace(XMLConstants.XML_NS_URI, XMLConstants.XML_NS_PREFIX);
                             } else {
                                 throw new SAXException("Unbound namespace " + attrNamespaceURI);
                             }
@@ -329,7 +284,7 @@ public class SAXOMBuilder extends Defaul
                 }
             }
             
-            target = (OMContainerEx)element;
+            target = element;
         }
     }
 
@@ -339,77 +294,77 @@ public class SAXOMBuilder extends Defaul
      * @see org.xml.sax.ContentHandler#endElement(java.lang.String,
      *      java.lang.String, java.lang.String)
      */
-    public void endElement(String uri, String localName, String qName)
+    public final void endElement(String uri, String localName, String qName)
             throws SAXException {
         if (!inEntityReference) {
-            target.setComplete(true);
-            target = (OMContainerEx)((OMNode)target).getParent();
+            completed((OMElement)target);
+            target = ((OMNode)target).getParent();
         }
     }
 
-    public void startCDATA() throws SAXException {
+    public final void startCDATA() throws SAXException {
         if (!inEntityReference) {
             textNodeType = OMNode.CDATA_SECTION_NODE;
         }
     }
 
-    public void endCDATA() throws SAXException {
+    public final void endCDATA() throws SAXException {
         if (!inEntityReference) {
             textNodeType = OMNode.TEXT_NODE;
         }
     }
 
-    public void characterData(char[] ch, int start, int length, int nodeType)
+    private void characterData(char[] ch, int start, int length, int nodeType)
             throws SAXException {
         if (!inEntityReference) {
-            factory.createOMText(target, new String(ch, start, length), nodeType, true);
+            createOMText(target, new String(ch, start, length), nodeType);
         }
     }
 
-    public void characters(char[] ch, int start, int length)
+    public final void characters(char[] ch, int start, int length)
             throws SAXException {
         if (!inEntityReference) {
             characterData(ch, start, length, textNodeType);
         }
     }
     
-    public void ignorableWhitespace(char[] ch, int start, int length)
+    public final void ignorableWhitespace(char[] ch, int start, int length)
             throws SAXException {
         if (!inEntityReference) {
             characterData(ch, start, length, OMNode.SPACE_NODE);
         }
     }
 
-    public void processingInstruction(String piTarget, String data)
+    public final void processingInstruction(String piTarget, String data)
             throws SAXException {
         if (!inEntityReference) {
-            factory.createOMProcessingInstruction(target, piTarget, data, true);
+            createOMProcessingInstruction(target, piTarget, data);
         }
     }
 
-    public void comment(char[] ch, int start, int length) throws SAXException {
+    public final void comment(char[] ch, int start, int length) throws SAXException {
         if (!inEntityReference) {
-            factory.createOMComment(target, new String(ch, start, length), true);
+            createOMComment(target, new String(ch, start, length));
         }
     }
 
-    public void skippedEntity(String name) throws SAXException {
-        factory.createOMEntityReference(target, name, null, true);
+    public final void skippedEntity(String name) throws SAXException {
+        createOMEntityReference(target, name, null);
     }
 
-    public void startEntity(String name) throws SAXException {
+    public final void startEntity(String name) throws SAXException {
         if (inEntityReference) {
             entityReferenceDepth++;
         } else if (name.equals("[dtd]")) {
             inExternalSubset = true;
         } else if (!expandEntityReferences) {
-            factory.createOMEntityReference(target, name, entities == null ? null : (String)entities.get(name), true);
+            createOMEntityReference(target, name, entities == null ? null : (String)entities.get(name));
             inEntityReference = true;
             entityReferenceDepth = 1;
         }
     }
 
-    public void endEntity(String name) throws SAXException {
+    public final void endEntity(String name) throws SAXException {
         if (inEntityReference) {
             entityReferenceDepth--;
             if (entityReferenceDepth == 0) {
@@ -420,105 +375,24 @@ public class SAXOMBuilder extends Defaul
         }
     }
 
-    public OMDocument getDocument() {
-        if (document == null && source != null) {
-            XMLReader reader = source.getXMLReader();
-            reader.setContentHandler(this);
-            reader.setDTDHandler(this);
-            try {
-                reader.setProperty("http://xml.org/sax/properties/lexical-handler", this);
-            } catch (SAXException ex) {
-                // Ignore
-            }
-            try {
-                reader.setProperty("http://xml.org/sax/properties/declaration-handler", this);
-            } catch (SAXException ex) {
-                // Ignore
-            }
-            try {
-                reader.parse(source.getInputSource());
-            } catch (IOException ex) {
-                throw new OMException(ex);
-            } catch (SAXException ex) {
-                throw new OMException(ex);
-            }
-        }
-        if (document != null && document.isComplete()) {
-            return document;
-        } else {
-            throw new OMException("Tree not complete");
-        }
-    }
+    protected abstract OMContainer doStartDocument();
     
-    /**
-     * Get the root element of the Axiom tree built by this content handler.
-     * 
-     * @deprecated
-     * @return the root element of the tree
-     * @throws OMException if the tree is not complete
-     */
-    public OMElement getRootElement() {
-        OMElement root = getDocumentElement();
-        if (root != null && root.isComplete()) {
-            return root;
-        } else {
-            throw new OMException("Tree not complete");
-        }
-    }
-
-    public int next() throws OMException {
-        throw new UnsupportedOperationException();
-    }
-
-    public void discard(OMElement el) throws OMException {
-        throw new UnsupportedOperationException();
-    }
-
-    public void setCache(boolean b) throws OMException {
-        throw new UnsupportedOperationException();
-    }
-
-    public boolean isCache() {
-        throw new UnsupportedOperationException();
-    }
-
-    public Object getParser() {
-        throw new UnsupportedOperationException();
-    }
-
-    public boolean isCompleted() {
-        return document != null && document.isComplete();
-    }
-
-    public OMElement getDocumentElement() {
-        return getDocument().getOMDocumentElement();
-    }
-
-    public OMElement getDocumentElement(boolean discardDocument) {
-        OMElement documentElement = getDocument().getOMDocumentElement();
-        if (discardDocument) {
-            documentElement.detach();
-        }
-        return documentElement;
-    }
-
-    public short getBuilderType() {
-        throw new UnsupportedOperationException();
-    }
-
-    public void registerExternalContentHandler(Object obj) {
-        throw new UnsupportedOperationException();
-    }
-
-    public Object getRegisteredContentHandler() {
-        throw new UnsupportedOperationException();
-    }
-
-    public String getCharacterEncoding() {
-        throw new UnsupportedOperationException();
-    }
+    protected abstract void doEndDocument();
+    
+    protected abstract void createOMDocType(OMContainer parent, String rootName, String publicId,
+            String systemId, String internalSubset);
 
-    public void close() {
-        // This is a no-op
-    }
+    protected abstract OMElement createOMElement(OMContainer parent, String localName,
+            String namespaceURI, String prefix, String[] namespaces, int namespaceCount);
+    
+    protected abstract void completed(OMElement element);
+    
+    protected abstract void createOMText(OMContainer parent, String text, int type);
+    
+    protected abstract void createOMProcessingInstruction(OMContainer parent, String piTarget,
+            String piData);
+    
+    protected abstract void createOMComment(OMContainer parent, String content);
+    
+    protected abstract void createOMEntityReference(OMContainer parent, String name, String replacementText);
 }

Modified: webservices/axiom/trunk/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/SAXOMBuilder.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/SAXOMBuilder.java?rev=1505170&r1=1505169&r2=1505170&view=diff
==============================================================================
--- webservices/axiom/trunk/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/SAXOMBuilder.java (original)
+++ webservices/axiom/trunk/modules/axiom-api/src/main/java/org/apache/axiom/om/impl/builder/SAXOMBuilder.java Sat Jul 20 16:51:16 2013
@@ -20,90 +20,29 @@
 package org.apache.axiom.om.impl.builder;
 
 import org.apache.axiom.om.OMAbstractFactory;
-import org.apache.axiom.om.OMAttribute;
+import org.apache.axiom.om.OMContainer;
 import org.apache.axiom.om.OMDocument;
 import org.apache.axiom.om.OMElement;
 import org.apache.axiom.om.OMException;
 import org.apache.axiom.om.OMFactory;
-import org.apache.axiom.om.OMNamespace;
-import org.apache.axiom.om.OMNode;
 import org.apache.axiom.om.OMXMLBuilderFactory;
 import org.apache.axiom.om.OMXMLParserWrapper;
 import org.apache.axiom.om.impl.OMContainerEx;
 import org.apache.axiom.om.impl.OMElementEx;
-import org.xml.sax.Attributes;
-import org.xml.sax.Locator;
 import org.xml.sax.SAXException;
 import org.xml.sax.XMLReader;
-import org.xml.sax.ext.DeclHandler;
-import org.xml.sax.ext.LexicalHandler;
-import org.xml.sax.helpers.DefaultHandler;
 
 import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
 
-import javax.xml.XMLConstants;
 import javax.xml.transform.sax.SAXSource;
 
-public class SAXOMBuilder extends DefaultHandler implements LexicalHandler, DeclHandler, OMXMLParserWrapper {
+public class SAXOMBuilder extends OMContentHandler implements OMXMLParserWrapper {
     private final SAXSource source;
-    private final boolean expandEntityReferences;
     
     private OMDocument document;
     
-    /**
-     * Stores the root name if there is a DTD.
-     */
-    private String dtdName;
-    
-    /**
-     * Stores the public ID if there is a DTD.
-     */
-    private String dtdPublicId;
-    
-    /**
-     * Stores the system ID if there is a DTD.
-     */
-    private String dtdSystemId;
-    
-    /**
-     * Stores the internal subset if there is a DTD.
-     */
-    private StringBuilder internalSubset;
-
-    /**
-     * Stores the replacement values for entities.
-     */
-    private Map entities;
-    
-    /**
-     * Flag indicating that the parser is processing the external subset.
-     */
-    private boolean inExternalSubset;
-    
-    private OMContainerEx target;
-
-    /**
-     * Stores namespace declarations reported to {@link #startPrefixMapping(String, String)}. These
-     * declarations will be added to the {@link OMElement} by
-     * {@link #startElement(String, String, String, Attributes)}. Each declaration is stored as
-     * (prefix, uri) pair using two array elements.
-     */
-    private String[] namespaces = new String[16];
-
-    /**
-     * The number of namespace declarations stored in {@link #namespaces}.
-     */
-    private int namespaceCount;
-
     private final OMFactoryEx factory;
 
-    private int textNodeType = OMNode.TEXT_NODE;
-    
-    private boolean inEntityReference;
-    private int entityReferenceDepth;
-
     /**
      * For internal use only.
      * 
@@ -112,9 +51,9 @@ public class SAXOMBuilder extends Defaul
      * @param expandEntityReferences
      */
     public SAXOMBuilder(OMFactory factory, SAXSource source, boolean expandEntityReferences) {
+        super(expandEntityReferences);
         this.factory = (OMFactoryEx)factory;
         this.source = source;
-        this.expandEntityReferences = expandEntityReferences;
     }
     
     /**
@@ -135,289 +74,13 @@ public class SAXOMBuilder extends Defaul
         this(OMAbstractFactory.getOMFactory());
     }
     
-    public void setDocumentLocator(Locator locator) {
-    }
-
-    public void startDocument() throws SAXException {
+    protected OMContainer doStartDocument() {
         document = factory.createOMDocument(this);
-        target = (OMContainerEx)document;
-    }
-
-    public void endDocument() throws SAXException {
-        if (target != document) {
-            throw new IllegalStateException();
-        }
-        target.setComplete(true);
-        target = null;
-    }
-
-    public void startDTD(String name, String publicId, String systemId) throws SAXException {
-        dtdName = name;
-        dtdPublicId = publicId;
-        dtdSystemId = systemId;
-        internalSubset = new StringBuilder();
-    }
-
-    public void elementDecl(String name, String model) throws SAXException {
-        if (!inExternalSubset) {
-            internalSubset.append("<!ELEMENT ");
-            internalSubset.append(name);
-            internalSubset.append(' ');
-            internalSubset.append(model);
-            internalSubset.append(">\n");
-        }
-    }
-
-    public void attributeDecl(String eName, String aName, String type, String mode, String value)
-            throws SAXException {
-        if (!inExternalSubset) {
-            internalSubset.append("<!ATTLIST ");
-            internalSubset.append(eName);
-            internalSubset.append(' ');
-            internalSubset.append(aName);
-            internalSubset.append(' ');
-            internalSubset.append(type);
-            if (value != null) {
-                internalSubset.append(' ');
-                internalSubset.append(value);
-            }
-            internalSubset.append(">\n");
-        }
-    }
-
-    public void externalEntityDecl(String name, String publicId, String systemId) throws SAXException {
-        if (!inExternalSubset) {
-            internalSubset.append("<!ENTITY ");            
-            internalSubset.append(name);
-            if (publicId != null) {
-                internalSubset.append(" PUBLIC \"");
-                internalSubset.append(publicId);
-            } else {
-                internalSubset.append(" SYSTEM \"");
-                internalSubset.append(systemId);
-            }
-            internalSubset.append("\">\n");
-        }
-    }
-
-    public void internalEntityDecl(String name, String value) throws SAXException {
-        if (entities == null) {
-            entities = new HashMap();
-        }
-        entities.put(name, value);
-        if (!inExternalSubset) {
-            internalSubset.append("<!ENTITY ");
-            internalSubset.append(name);
-            internalSubset.append(" \"");
-            internalSubset.append(value);
-            internalSubset.append("\">\n");
-        }
-    }
-
-    public void notationDecl(String name, String publicId, String systemId) throws SAXException {
-        if (!inExternalSubset) {
-            internalSubset.append("<!NOTATION ");            
-            internalSubset.append(name);
-            if (publicId != null) {
-                internalSubset.append(" PUBLIC \"");
-                internalSubset.append(publicId);
-            } else {
-                internalSubset.append(" SYSTEM \"");
-                internalSubset.append(systemId);
-            }
-            internalSubset.append("\">\n");
-        }
-    }
-
-    public void unparsedEntityDecl(String name, String publicId, String systemId, String notationName)
-            throws SAXException {
-        if (!inExternalSubset) {
-            internalSubset.append("<!ENTITY ");
-            internalSubset.append(name);
-            if (publicId != null) {
-                internalSubset.append(" PUBLIC \"");
-                internalSubset.append(publicId);
-            } else {
-                internalSubset.append(" SYSTEM \"");
-                internalSubset.append(systemId);
-            }
-            internalSubset.append("\" NDATA ");
-            internalSubset.append(notationName);
-            internalSubset.append(">\n");
-        }
-    }
-
-    public void endDTD() throws SAXException {
-        factory.createOMDocType(target, dtdName, dtdPublicId, dtdSystemId,
-                internalSubset.length() == 0 ? null : internalSubset.toString(), true);
-        internalSubset = null;
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String,
-     *      java.lang.String)
-     */
-    public void startPrefixMapping(String prefix, String uri)
-            throws SAXException {
-        if (!inEntityReference) {
-            int index = namespaceCount*2;
-            if (index == namespaces.length) {
-                String[] newNamespaces = new String[namespaces.length*2];
-                System.arraycopy(namespaces, 0, newNamespaces, 0, namespaces.length);
-                namespaces = newNamespaces;
-            }
-            namespaces[index] = prefix;
-            namespaces[index+1] = uri;
-            namespaceCount++;
-        }
-    }
-
-    public void endPrefixMapping(String prefix) throws SAXException {
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see org.xml.sax.ContentHandler#startElement(java.lang.String,
-     *      java.lang.String, java.lang.String, org.xml.sax.Attributes)
-     */
-    public void startElement(String namespaceURI, String localName,
-                             String qName, Attributes atts) throws SAXException {
-        if (!inEntityReference) {
-            if (localName == null || localName.trim().equals(""))
-                localName = qName.substring(qName.indexOf(':') + 1);
-            OMElement element = factory.createOMElement(localName, target, this);
-            
-            for (int i = 0; i < namespaceCount; i++) {
-                ((OMElementEx)element).addNamespaceDeclaration(namespaces[2*i+1], namespaces[2*i]);
-            }
-            namespaceCount = 0;
-    
-            int idx = qName.indexOf(':');
-            String prefix = idx == -1 ? "" : qName.substring(0, idx);
-            BuilderUtil.setNamespace(element, namespaceURI, prefix, false);
-            
-            int j = atts.getLength();
-            for (int i = 0; i < j; i++) {
-                // Note that some SAX parsers report namespace declarations as attributes in addition
-                // to calling start/endPrefixMapping.
-                // NOTE: This filter was introduced to make SAXOMBuilder work with some versions of
-                //       XMLBeans (2.3.0). It is not clear whether this is a bug in XMLBeans or not.
-                //       See http://forum.springframework.org/showthread.php?t=43958 for a discussion.
-                //       If this test causes problems with other parsers, don't hesitate to remove it.
-                if (!atts.getQName(i).startsWith("xmlns")) {
-                    String attrNamespaceURI = atts.getURI(i);
-                    OMNamespace ns;
-                    if (attrNamespaceURI.length() > 0) {
-                        ns = element.findNamespace(atts.getURI(i), null);
-                        if (ns == null) {
-                            // The "xml" prefix is not necessarily declared explicitly; in this case,
-                            // create a new OMNamespace instance.
-                            if (attrNamespaceURI.equals(XMLConstants.XML_NS_URI)) {
-                                ns = factory.createOMNamespace(XMLConstants.XML_NS_URI, XMLConstants.XML_NS_PREFIX);
-                            } else {
-                                throw new SAXException("Unbound namespace " + attrNamespaceURI);
-                            }
-                        }
-                    } else {
-                        ns = null;
-                    }
-                    OMAttribute attr = element.addAttribute(atts.getLocalName(i), atts.getValue(i), ns);
-                    attr.setAttributeType(atts.getType(i));
-                }
-            }
-            
-            target = (OMContainerEx)element;
-        }
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see org.xml.sax.ContentHandler#endElement(java.lang.String,
-     *      java.lang.String, java.lang.String)
-     */
-    public void endElement(String uri, String localName, String qName)
-            throws SAXException {
-        if (!inEntityReference) {
-            target.setComplete(true);
-            target = (OMContainerEx)((OMNode)target).getParent();
-        }
-    }
-
-    public void startCDATA() throws SAXException {
-        if (!inEntityReference) {
-            textNodeType = OMNode.CDATA_SECTION_NODE;
-        }
+        return document;
     }
 
-    public void endCDATA() throws SAXException {
-        if (!inEntityReference) {
-            textNodeType = OMNode.TEXT_NODE;
-        }
-    }
-
-    public void characterData(char[] ch, int start, int length, int nodeType)
-            throws SAXException {
-        if (!inEntityReference) {
-            factory.createOMText(target, new String(ch, start, length), nodeType, true);
-        }
-    }
-
-    public void characters(char[] ch, int start, int length)
-            throws SAXException {
-        if (!inEntityReference) {
-            characterData(ch, start, length, textNodeType);
-        }
-    }
-    
-    public void ignorableWhitespace(char[] ch, int start, int length)
-            throws SAXException {
-        if (!inEntityReference) {
-            characterData(ch, start, length, OMNode.SPACE_NODE);
-        }
-    }
-
-    public void processingInstruction(String piTarget, String data)
-            throws SAXException {
-        if (!inEntityReference) {
-            factory.createOMProcessingInstruction(target, piTarget, data, true);
-        }
-    }
-
-    public void comment(char[] ch, int start, int length) throws SAXException {
-        if (!inEntityReference) {
-            factory.createOMComment(target, new String(ch, start, length), true);
-        }
-    }
-
-    public void skippedEntity(String name) throws SAXException {
-        factory.createOMEntityReference(target, name, null, true);
-    }
-
-    public void startEntity(String name) throws SAXException {
-        if (inEntityReference) {
-            entityReferenceDepth++;
-        } else if (name.equals("[dtd]")) {
-            inExternalSubset = true;
-        } else if (!expandEntityReferences) {
-            factory.createOMEntityReference(target, name, entities == null ? null : (String)entities.get(name), true);
-            inEntityReference = true;
-            entityReferenceDepth = 1;
-        }
-    }
-
-    public void endEntity(String name) throws SAXException {
-        if (inEntityReference) {
-            entityReferenceDepth--;
-            if (entityReferenceDepth == 0) {
-                inEntityReference = false;
-            }
-        } else if (name.equals("[dtd]")) {
-            inExternalSubset = false;
-        }
+    protected void doEndDocument() {
+        ((OMContainerEx)document).setComplete(true);
     }
 
     public OMDocument getDocument() {
@@ -521,4 +184,41 @@ public class SAXOMBuilder extends Defaul
     public void close() {
         // This is a no-op
     }
+
+    protected void createOMDocType(OMContainer parent, String rootName, String publicId,
+            String systemId, String internalSubset) {
+        factory.createOMDocType(parent, rootName, publicId, systemId, internalSubset, true);
+    }
+
+    protected OMElement createOMElement(OMContainer parent, String localName,
+            String namespaceURI, String prefix, String[] namespaces, int namespaceCount) {
+        OMElement element = factory.createOMElement(localName, parent, this);
+        for (int i = 0; i < namespaceCount; i++) {
+            ((OMElementEx)element).addNamespaceDeclaration(namespaces[2*i+1], namespaces[2*i]);
+        }
+        BuilderUtil.setNamespace(element, namespaceURI, prefix, false);
+        return element;
+    }
+
+    protected void completed(OMElement element) {
+        ((OMElementEx)element).setComplete(true);
+    }
+
+    protected void createOMText(OMContainer parent, String text, int type) {
+        factory.createOMText(parent, text, type, true);
+    }
+
+    protected void createOMProcessingInstruction(OMContainer parent,
+            String piTarget, String piData) {
+        factory.createOMProcessingInstruction(parent, piTarget, piData, true);
+    }
+
+    protected void createOMComment(OMContainer parent, String content) {
+        factory.createOMComment(parent, content, true);
+    }
+
+    protected void createOMEntityReference(OMContainer parent, String name,
+            String replacementText) {
+        factory.createOMEntityReference(parent, name, replacementText, true);
+    }
 }

Modified: webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/OMContainerHelper.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/OMContainerHelper.java?rev=1505170&r1=1505169&r2=1505170&view=diff
==============================================================================
--- webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/OMContainerHelper.java (original)
+++ webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/OMContainerHelper.java Sat Jul 20 16:51:16 2013
@@ -19,6 +19,7 @@
 package org.apache.axiom.om.impl.common;
 
 import javax.xml.stream.XMLStreamReader;
+import javax.xml.transform.sax.SAXResult;
 
 import org.apache.axiom.om.NodeUnavailableException;
 import org.apache.axiom.om.OMException;
@@ -202,4 +203,12 @@ public final class OMContainerHelper {
             that.setComplete(true);
         }
     }
+    
+    public static SAXResult getSAXResult(IContainer that) {
+        SAXResultContentHandler handler = new SAXResultContentHandler(that);
+        SAXResult result = new SAXResult();
+        result.setHandler(handler);
+        result.setLexicalHandler(handler);
+        return result;
+    }
 }

Added: webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/SAXResultContentHandler.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/SAXResultContentHandler.java?rev=1505170&view=auto
==============================================================================
--- webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/SAXResultContentHandler.java (added)
+++ webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/SAXResultContentHandler.java Sat Jul 20 16:51:16 2013
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.axiom.om.impl.common;
+
+import org.apache.axiom.om.OMContainer;
+import org.apache.axiom.om.OMDocument;
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMFactory;
+import org.apache.axiom.om.impl.builder.OMContentHandler;
+
+public class SAXResultContentHandler extends OMContentHandler {
+    private final OMContainer root;
+    private final OMFactory factory;
+
+    public SAXResultContentHandler(OMContainer root) {
+        super(true);
+        this.root = root;
+        factory = root.getOMFactory();
+    }
+    
+    protected OMContainer doStartDocument() {
+        return root;
+    }
+
+    protected void doEndDocument() {
+    }
+
+    protected void createOMDocType(OMContainer parent, String rootName, String publicId,
+            String systemId, String internalSubset) {
+        if (parent instanceof OMDocument) {
+            factory.createOMDocType(parent, rootName, publicId, systemId, internalSubset);
+        }
+    }
+
+    protected OMElement createOMElement(OMContainer parent, String localName, String namespaceURI,
+            String prefix, String[] namespaces, int namespaceCount) {
+        // TODO: inefficient: we should not create a new OMNamespace instance every time
+        OMElement element = factory.createOMElement(localName, factory.createOMNamespace(namespaceURI, prefix), parent);
+        for (int i=0; i<namespaceCount; i++) {
+            String nsPrefix = namespaces[2*i];
+            String nsURI = namespaces[2*i+1];
+            if (nsPrefix.length() == 0) {
+                element.declareDefaultNamespace(nsURI);
+            } else {
+                element.declareNamespace(nsURI, nsPrefix);
+            }
+        }
+        return element;
+    }
+
+    protected void completed(OMElement element) {
+    }
+
+    protected void createOMText(OMContainer parent, String text, int type) {
+        factory.createOMText(parent, text, type);
+    }
+
+    protected void createOMProcessingInstruction(OMContainer parent, String piTarget, String piData) {
+        factory.createOMProcessingInstruction(parent, piTarget, piData);
+    }
+
+    protected void createOMComment(OMContainer parent, String content) {
+        factory.createOMComment(parent, content);
+    }
+
+    protected void createOMEntityReference(OMContainer parent, String name, String replacementText) {
+        if (replacementText == null) {
+            factory.createOMEntityReference(parent, name);
+        } else {
+            // Since we set expandEntityReferences=true, we should never get here
+            throw new UnsupportedOperationException();
+        }
+    }
+}

Propchange: webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/SAXResultContentHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: webservices/axiom/trunk/modules/axiom-common-impl/src/main/java/org/apache/axiom/om/impl/common/SAXResultContentHandler.java
------------------------------------------------------------------------------
    svn:executable = *

Modified: webservices/axiom/trunk/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/ParentNode.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/ParentNode.java?rev=1505170&r1=1505169&r2=1505170&view=diff
==============================================================================
--- webservices/axiom/trunk/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/ParentNode.java (original)
+++ webservices/axiom/trunk/modules/axiom-dom/src/main/java/org/apache/axiom/om/impl/dom/ParentNode.java Sat Jul 20 16:51:16 2013
@@ -45,6 +45,7 @@ import org.xml.sax.InputSource;
 
 import javax.xml.namespace.QName;
 import javax.xml.stream.XMLStreamReader;
+import javax.xml.transform.sax.SAXResult;
 import javax.xml.transform.sax.SAXSource;
 
 import java.util.Iterator;
@@ -542,6 +543,10 @@ public abstract class ParentNode extends
         return new SAXSource(new XMLReaderImpl((IContainer)this, cache), new InputSource());
     }
 
+    public SAXResult getSAXResult() {
+        return OMContainerHelper.getSAXResult((IContainer)this);
+    }
+    
     void notifyChildComplete() {
         if (!this.isComplete() && getBuilder() == null) {
             Iterator iterator = getChildren();

Modified: webservices/axiom/trunk/modules/axiom-dom/src/test/java/org/apache/axiom/om/impl/dom/OMImplementationTest.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/modules/axiom-dom/src/test/java/org/apache/axiom/om/impl/dom/OMImplementationTest.java?rev=1505170&r1=1505169&r2=1505170&view=diff
==============================================================================
--- webservices/axiom/trunk/modules/axiom-dom/src/test/java/org/apache/axiom/om/impl/dom/OMImplementationTest.java (original)
+++ webservices/axiom/trunk/modules/axiom-dom/src/test/java/org/apache/axiom/om/impl/dom/OMImplementationTest.java Sat Jul 20 16:51:16 2013
@@ -27,6 +27,7 @@ import org.apache.axiom.ts.om.builder.Te
 import org.apache.axiom.ts.om.container.TestSerialize;
 import org.apache.axiom.ts.om.document.TestClone;
 import org.apache.axiom.ts.om.document.TestDigest;
+import org.apache.axiom.ts.om.document.TestGetSAXResult;
 import org.apache.axiom.ts.om.element.TestGetChildrenWithName4;
 import org.apache.axiom.ts.om.element.TestSerializationWithTwoNonBuiltOMElements;
 import org.apache.axiom.ts.om.element.sr.TestClose;
@@ -62,6 +63,9 @@ public class OMImplementationTest extend
         
         // TODO: test case needing review
         builder.exclude(TestClose.class);
+
+        // TODO: fails because of an issue elsewhere in DOOM
+        builder.exclude(TestGetSAXResult.class);
         
         return builder.build();
     }

Modified: webservices/axiom/trunk/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMDocumentImpl.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMDocumentImpl.java?rev=1505170&r1=1505169&r2=1505170&view=diff
==============================================================================
--- webservices/axiom/trunk/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMDocumentImpl.java (original)
+++ webservices/axiom/trunk/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMDocumentImpl.java Sat Jul 20 16:51:16 2013
@@ -44,6 +44,7 @@ import org.xml.sax.InputSource;
 
 import javax.xml.namespace.QName;
 import javax.xml.stream.XMLStreamReader;
+import javax.xml.transform.sax.SAXResult;
 import javax.xml.transform.sax.SAXSource;
 
 import java.util.Iterator;
@@ -332,6 +333,10 @@ public class OMDocumentImpl extends OMSe
         return new SAXSource(new XMLReaderImpl(this, cache), new InputSource());
     }
 
+    public SAXResult getSAXResult() {
+        return OMContainerHelper.getSAXResult(this);
+    }
+    
     public void build() {
         OMContainerHelper.build(this);
     }

Modified: webservices/axiom/trunk/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMElementImpl.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMElementImpl.java?rev=1505170&r1=1505169&r2=1505170&view=diff
==============================================================================
--- webservices/axiom/trunk/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMElementImpl.java (original)
+++ webservices/axiom/trunk/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMElementImpl.java Sat Jul 20 16:51:16 2013
@@ -44,6 +44,7 @@ import org.apache.axiom.om.impl.common.O
 import org.apache.axiom.om.impl.common.OMDescendantsIterator;
 import org.apache.axiom.om.impl.common.OMElementHelper;
 import org.apache.axiom.om.impl.common.OMNamespaceImpl;
+import org.apache.axiom.om.impl.common.SAXResultContentHandler;
 import org.apache.axiom.om.impl.common.serializer.push.OutputException;
 import org.apache.axiom.om.impl.common.serializer.push.Serializer;
 import org.apache.axiom.om.impl.common.serializer.push.sax.XMLReaderImpl;
@@ -60,6 +61,7 @@ import javax.xml.namespace.QName;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
 import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.sax.SAXResult;
 import javax.xml.transform.sax.SAXSource;
 
 import java.io.IOException;
@@ -1013,6 +1015,10 @@ public class OMElementImpl extends OMNod
     public SAXSource getSAXSource(boolean cache) {
         return new SAXSource(new XMLReaderImpl(this, cache), new InputSource());
     }
+
+    public SAXResult getSAXResult() {
+        return OMContainerHelper.getSAXResult(this);
+    }
     
     public void removeChildren() {
         OMContainerHelper.removeChildren(this);

Modified: webservices/axiom/trunk/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMSourcedElementImpl.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMSourcedElementImpl.java?rev=1505170&r1=1505169&r2=1505170&view=diff
==============================================================================
--- webservices/axiom/trunk/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMSourcedElementImpl.java (original)
+++ webservices/axiom/trunk/modules/axiom-impl/src/main/java/org/apache/axiom/om/impl/llom/OMSourcedElementImpl.java Sat Jul 20 16:51:16 2013
@@ -51,6 +51,7 @@ import javax.xml.stream.XMLStreamConstan
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
 import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.sax.SAXResult;
 import javax.xml.transform.sax.SAXSource;
 
 import java.io.IOException;
@@ -1040,6 +1041,10 @@ public class OMSourcedElementImpl extend
         return super.getSAXSource(cache);
     }
 
+    public SAXResult getSAXResult() {
+        return super.getSAXResult();
+    }
+
     class DeferredNamespace implements OMNamespace {
         
         final String uri;

Modified: webservices/axiom/trunk/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/OMTestSuiteBuilder.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/OMTestSuiteBuilder.java?rev=1505170&r1=1505169&r2=1505170&view=diff
==============================================================================
--- webservices/axiom/trunk/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/OMTestSuiteBuilder.java (original)
+++ webservices/axiom/trunk/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/OMTestSuiteBuilder.java Sat Jul 20 16:51:16 2013
@@ -149,6 +149,14 @@ public class OMTestSuiteBuilder extends 
         addTest(new org.apache.axiom.ts.om.document.TestGetOMDocumentElement(metaFactory));
         addTest(new org.apache.axiom.ts.om.document.TestGetOMDocumentElementAfterDetach(metaFactory));
         addTest(new org.apache.axiom.ts.om.document.TestGetOMDocumentElementWithParser(metaFactory));
+        for (int i=0; i<XSLTImplementation.INSTANCES.length; i++) {
+            XSLTImplementation xsltImplementation = XSLTImplementation.INSTANCES[i];
+            if (xsltImplementation.supportsLexicalHandlerWithStreamSource()) {
+                for (int j=0; j<conformanceFiles.length; j++) {
+                    addTest(new org.apache.axiom.ts.om.document.TestGetSAXResult(metaFactory, xsltImplementation, conformanceFiles[j]));
+                }
+            }
+        }
         addTest(new org.apache.axiom.ts.om.document.TestIsCompleteAfterAddingIncompleteChild(metaFactory));
         addTest(new org.apache.axiom.ts.om.document.TestRemoveChildren(metaFactory, true, false));
         addTest(new org.apache.axiom.ts.om.document.TestRemoveChildren(metaFactory, true, true));
@@ -266,6 +274,7 @@ public class OMTestSuiteBuilder extends 
         addTest(new org.apache.axiom.ts.om.element.TestGetPrefixWithoutNamespace(metaFactory));
         addTest(new org.apache.axiom.ts.om.element.TestGetQNameWithNamespace(metaFactory));
         addTest(new org.apache.axiom.ts.om.element.TestGetQNameWithoutNamespace(metaFactory));
+        addTest(new org.apache.axiom.ts.om.element.TestGetSAXResultWithDTD(metaFactory));
         for (int i=0; i<XSLTImplementation.INSTANCES.length; i++) {
             XSLTImplementation xsltImplementation = XSLTImplementation.INSTANCES[i];
             addTest(new org.apache.axiom.ts.om.element.TestGetSAXSourceIdentityTransform(metaFactory, xsltImplementation, true));

Copied: webservices/axiom/trunk/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/document/TestGetSAXResult.java (from r1503989, webservices/axiom/trunk/modules/axiom-api/src/test/java/org/apache/axiom/om/impl/jaxp/StreamSourceToOMResultTestCase.java)
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/document/TestGetSAXResult.java?p2=webservices/axiom/trunk/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/document/TestGetSAXResult.java&p1=webservices/axiom/trunk/modules/axiom-api/src/test/java/org/apache/axiom/om/impl/jaxp/StreamSourceToOMResultTestCase.java&r1=1503989&r2=1505170&rev=1505170&view=diff
==============================================================================
--- webservices/axiom/trunk/modules/axiom-api/src/test/java/org/apache/axiom/om/impl/jaxp/StreamSourceToOMResultTestCase.java (original)
+++ webservices/axiom/trunk/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/document/TestGetSAXResult.java Sat Jul 20 16:51:16 2013
@@ -16,53 +16,41 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.axiom.om.impl.jaxp;
+package org.apache.axiom.ts.om.document;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 
 import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.sax.SAXResult;
 import javax.xml.transform.stream.StreamSource;
 
-import junit.framework.TestSuite;
-
-import org.apache.axiom.om.AbstractTestCase;
+import org.apache.axiom.om.OMDocument;
 import org.apache.axiom.om.OMMetaFactory;
 import org.apache.axiom.testutils.XMLAssertEx;
 import org.apache.axiom.testutils.conformance.ConformanceTestFile;
+import org.apache.axiom.testutils.suite.XSLTImplementation;
+import org.apache.axiom.ts.ConformanceTestCase;
 
-public class StreamSourceToOMResultTestCase extends AbstractTestCase {
-    private final OMMetaFactory omMetaFactory;
-    private final TransformerFactory transformerFactory;
-    private final ConformanceTestFile file;
+public class TestGetSAXResult extends ConformanceTestCase {
+    private final XSLTImplementation xsltImplementation;
     
-    private StreamSourceToOMResultTestCase(OMMetaFactory omMetaFactory,
-            TransformerFactory transformerFactory, String name, ConformanceTestFile file) {
-        super(name);
-        this.omMetaFactory = omMetaFactory;
-        this.transformerFactory = transformerFactory;
-        this.file = file;
+    public TestGetSAXResult(OMMetaFactory metaFactory,
+            XSLTImplementation xsltImplementation, ConformanceTestFile file) {
+        super(metaFactory, file);
+        this.xsltImplementation = xsltImplementation;
+        xsltImplementation.addTestParameters(this);
     }
     
     protected void runTest() throws Throwable {
+        TransformerFactory transformerFactory = xsltImplementation.newTransformerFactory();
         StreamSource source = new StreamSource(file.getUrl().toString());
-        OMResult result = new OMResult(omMetaFactory.getOMFactory());
+        OMDocument document = metaFactory.getOMFactory().createOMDocument();
+        SAXResult result = document.getSAXResult();
         transformerFactory.newTransformer().transform(source, result);
         ByteArrayOutputStream out = new ByteArrayOutputStream();
-        result.getDocument().serialize(out);
+        document.serialize(out);
         XMLAssertEx.assertXMLIdentical(file.getUrl(),
                 new ByteArrayInputStream(out.toByteArray()), true);
     }
-
-    public static TestSuite suite(OMMetaFactory omMetaFactory,
-            TransformerFactory transformerFactory) throws Exception {
-        TestSuite suite = new TestSuite();
-        ConformanceTestFile[] files = ConformanceTestFile.getConformanceTestFiles();
-        for (int i=0; i<files.length; i++) {
-            ConformanceTestFile file = files[i];
-            suite.addTest(new StreamSourceToOMResultTestCase(omMetaFactory, transformerFactory,
-                    file.getShortName(), file));
-        }
-        return suite;
-    }
 }

Added: webservices/axiom/trunk/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestGetSAXResultWithDTD.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestGetSAXResultWithDTD.java?rev=1505170&view=auto
==============================================================================
--- webservices/axiom/trunk/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestGetSAXResultWithDTD.java (added)
+++ webservices/axiom/trunk/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestGetSAXResultWithDTD.java Sat Jul 20 16:51:16 2013
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.axiom.ts.om.element;
+
+import javax.xml.transform.sax.SAXResult;
+
+import org.apache.axiom.om.OMContainer;
+import org.apache.axiom.om.OMElement;
+import org.apache.axiom.om.OMMetaFactory;
+import org.apache.axiom.om.OMNode;
+import org.apache.axiom.ts.AxiomTestCase;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.ext.LexicalHandler;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * Tests that for an {@link OMElement}, a {@link LexicalHandler#startDTD(String, String, String)}
+ * event sent to the {@link LexicalHandler} linked to the {@link SAXResult} object returned by
+ * {@link OMContainer#getSAXResult()} is silently ignored.
+ */
+public class TestGetSAXResultWithDTD extends AxiomTestCase {
+    public TestGetSAXResultWithDTD(OMMetaFactory metaFactory) {
+        super(metaFactory);
+    }
+
+    protected void runTest() throws Throwable {
+        OMElement root = metaFactory.getOMFactory().createOMElement("root", null);
+        SAXResult result = root.getSAXResult();
+        LexicalHandler lexicalHandler = result.getLexicalHandler();
+        ContentHandler contentHandler = result.getHandler();
+        contentHandler.startDocument();
+        lexicalHandler.startDTD("test", null, "my.dtd");
+        lexicalHandler.endDTD();
+        contentHandler.startElement("", "test", "test", new AttributesImpl());
+        contentHandler.endElement("", "test", "test");
+        contentHandler.endDocument();
+        OMNode child = root.getFirstOMChild();
+        assertTrue(child instanceof OMElement);
+        assertEquals("test", ((OMElement)child).getLocalName());
+    }
+}

Propchange: webservices/axiom/trunk/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestGetSAXResultWithDTD.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: webservices/axiom/trunk/modules/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestGetSAXResultWithDTD.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: webservices/axiom/trunk/modules/axiom-testutils/src/main/java/org/apache/axiom/testutils/suite/XSLTImplementation.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/modules/axiom-testutils/src/main/java/org/apache/axiom/testutils/suite/XSLTImplementation.java?rev=1505170&r1=1505169&r2=1505170&view=diff
==============================================================================
--- webservices/axiom/trunk/modules/axiom-testutils/src/main/java/org/apache/axiom/testutils/suite/XSLTImplementation.java (original)
+++ webservices/axiom/trunk/modules/axiom-testutils/src/main/java/org/apache/axiom/testutils/suite/XSLTImplementation.java Sat Jul 20 16:51:16 2013
@@ -19,6 +19,7 @@
 package org.apache.axiom.testutils.suite;
 
 import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamSource;
 
 /**
  * Specifies an XSLT implementation for use in a {@link MatrixTestCase}.
@@ -33,6 +34,10 @@ public interface XSLTImplementation exte
             public TransformerFactory newTransformerFactory() {
                 return new org.apache.xalan.processor.TransformerFactoryImpl();
             }
+
+            public boolean supportsLexicalHandlerWithStreamSource() {
+                return true;
+            }
         },
         new XSLTImplementation() {
             public void addTestParameters(MatrixTestCase testCase) {
@@ -42,8 +47,21 @@ public interface XSLTImplementation exte
             public TransformerFactory newTransformerFactory() {
                 return new net.sf.saxon.TransformerFactoryImpl();
             }
+
+            public boolean supportsLexicalHandlerWithStreamSource() {
+                return false;
+            }
         },
     };
     
     TransformerFactory newTransformerFactory();
+    
+    /**
+     * Determine if an identity transformation from a {@link StreamSource} to a {@link SAXResult}
+     * will generate events defined by {@link LexicalHandler}.
+     * 
+     * @return <code>true</code> if the XSLT implementation will invoke the methods on the
+     *         {@link LexicalHandler} set on the {@link SAXResult}, <code>false</code> otherwise
+     */
+    boolean supportsLexicalHandlerWithStreamSource();
 }