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 2016/04/28 00:21:42 UTC

svn commit: r1741355 - in /webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/factory: AbstractOMMetaFactory.java BuilderFactory.java BuilderSpec.java

Author: veithen
Date: Wed Apr 27 22:21:42 2016
New Revision: 1741355

URL: http://svn.apache.org/viewvc?rev=1741355&view=rev
Log:
Reorganize the AbstractOMMetaFactory code.

Added:
    webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/factory/BuilderSpec.java
      - copied, changed from r1741349, webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/factory/BuilderFactory.java
Modified:
    webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/factory/AbstractOMMetaFactory.java
    webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/factory/BuilderFactory.java

Modified: webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/factory/AbstractOMMetaFactory.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/factory/AbstractOMMetaFactory.java?rev=1741355&r1=1741354&r2=1741355&view=diff
==============================================================================
--- webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/factory/AbstractOMMetaFactory.java (original)
+++ webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/factory/AbstractOMMetaFactory.java Wed Apr 27 22:21:42 2016
@@ -49,45 +49,45 @@ public abstract class AbstractOMMetaFact
     }
     
     public OMXMLParserWrapper createStAXOMBuilder(XMLStreamReader parser) {
-        return OM.createBuilder(nodeFactory, parser);
+        return OM.createBuilder(nodeFactory, BuilderSpec.from(parser));
     }
 
     public OMXMLParserWrapper createOMBuilder(StAXParserConfiguration configuration, InputSource is) {
-        return OM.createBuilder(nodeFactory, configuration, is);
+        return OM.createBuilder(nodeFactory, BuilderSpec.from(configuration, is));
     }
     
     public OMXMLParserWrapper createOMBuilder(Source source) {
-        return OM.createBuilder(nodeFactory, StAXParserConfiguration.DEFAULT, source);
+        return OM.createBuilder(nodeFactory, BuilderSpec.from(StAXParserConfiguration.DEFAULT, source));
     }
 
     public OMXMLParserWrapper createOMBuilder(Node node, boolean expandEntityReferences) {
-        return OM.createBuilder(nodeFactory, node, expandEntityReferences);
+        return OM.createBuilder(nodeFactory, BuilderSpec.from(node, expandEntityReferences));
     }
 
     public OMXMLParserWrapper createOMBuilder(SAXSource source, boolean expandEntityReferences) {
-        return OM.createBuilder(nodeFactory, source, expandEntityReferences);
+        return OM.createBuilder(nodeFactory, BuilderSpec.from(source, expandEntityReferences));
     }
 
     public OMXMLParserWrapper createOMBuilder(StAXParserConfiguration configuration,
             InputSource rootPart, MimePartProvider mimePartProvider) {
-        return OM.createBuilder(nodeFactory, configuration, rootPart, mimePartProvider);
+        return OM.createBuilder(nodeFactory, BuilderSpec.from(configuration, rootPart, mimePartProvider));
     }
 
     public SOAPModelBuilder createStAXSOAPModelBuilder(XMLStreamReader parser) {
-        return SOAP.createBuilder(nodeFactory, parser);
+        return SOAP.createBuilder(nodeFactory, BuilderSpec.from(parser));
     }
 
     public SOAPModelBuilder createSOAPModelBuilder(StAXParserConfiguration configuration, InputSource is) {
-        return SOAP.createBuilder(nodeFactory, configuration, is);
+        return SOAP.createBuilder(nodeFactory, BuilderSpec.from(configuration, is));
     }
 
     public SOAPModelBuilder createSOAPModelBuilder(Source source) {
-        return SOAP.createBuilder(nodeFactory, StAXParserConfiguration.SOAP, source);
+        return SOAP.createBuilder(nodeFactory, BuilderSpec.from(StAXParserConfiguration.SOAP, source));
     }
 
     public SOAPModelBuilder createSOAPModelBuilder(StAXParserConfiguration configuration,
             SOAPFactory soapFactory, InputSource rootPart, MimePartProvider mimePartProvider) {
-        SOAPModelBuilder builder = SOAP.createBuilder(nodeFactory, configuration, rootPart, mimePartProvider);
+        SOAPModelBuilder builder = SOAP.createBuilder(nodeFactory, BuilderSpec.from(configuration, rootPart, mimePartProvider));
         if (builder.getSOAPMessage().getOMFactory() != soapFactory) {
             throw new SOAPProcessingException("Invalid SOAP namespace URI. " +
                     "Expected " + soapFactory.getSoapVersionURI(), SOAP12Constants.FAULT_CODE_SENDER);

Modified: webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/factory/BuilderFactory.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/factory/BuilderFactory.java?rev=1741355&r1=1741354&r2=1741355&view=diff
==============================================================================
--- webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/factory/BuilderFactory.java (original)
+++ webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/factory/BuilderFactory.java Wed Apr 27 22:21:42 2016
@@ -18,38 +18,14 @@
  */
 package org.apache.axiom.om.impl.common.factory;
 
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-import java.net.URL;
-
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamReader;
-import javax.xml.transform.Source;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.sax.SAXSource;
-import javax.xml.transform.stream.StreamSource;
-
 import org.apache.axiom.core.CoreNode;
 import org.apache.axiom.core.NodeFactory;
 import org.apache.axiom.core.impl.builder.BuilderImpl;
 import org.apache.axiom.core.impl.builder.BuilderListener;
 import org.apache.axiom.core.impl.builder.PlainXMLModel;
 import org.apache.axiom.core.stream.FilteredXmlInput;
-import org.apache.axiom.core.stream.NamespaceRepairingFilter;
-import org.apache.axiom.core.stream.XmlInput;
-import org.apache.axiom.core.stream.dom.DOMInput;
-import org.apache.axiom.core.stream.sax.SAXInput;
-import org.apache.axiom.mime.MimePartProvider;
-import org.apache.axiom.om.OMException;
 import org.apache.axiom.om.OMXMLParserWrapper;
-import org.apache.axiom.om.impl.builder.Detachable;
 import org.apache.axiom.om.impl.common.builder.OMXMLParserWrapperImpl;
-import org.apache.axiom.om.impl.stream.stax.StAXPullInput;
-import org.apache.axiom.om.impl.stream.xop.XOPDecodingFilter;
-import org.apache.axiom.om.util.StAXParserConfiguration;
-import org.apache.axiom.om.util.StAXUtils;
 import org.apache.axiom.soap.SOAPFactory;
 import org.apache.axiom.soap.SOAPModelBuilder;
 import org.apache.axiom.soap.impl.common.builder.SOAPFilter;
@@ -57,44 +33,20 @@ import org.apache.axiom.soap.impl.common
 import org.apache.axiom.soap.impl.common.builder.SOAPModelBuilderImpl;
 import org.apache.axiom.soap.impl.intf.AxiomSOAPEnvelope;
 import org.apache.axiom.soap.impl.intf.AxiomSOAPMessage;
-import org.apache.axiom.util.stax.XMLEventUtils;
-import org.apache.axiom.util.stax.XMLFragmentStreamReader;
-import org.w3c.dom.Node;
-import org.xml.sax.InputSource;
 
 abstract class BuilderFactory<T extends OMXMLParserWrapper> {
-    private final static class SourceInfo {
-        private final XmlInput input;
-        private final Detachable detachable;
-        
-        SourceInfo(XmlInput input, Detachable detachable) {
-            this.input = input;
-            this.detachable = detachable;
-        }
-
-        XmlInput getInput() {
-            return input;
-        }
-
-        Detachable getDetachable() {
-            return detachable;
-        }
-    }
-    
     final static BuilderFactory<OMXMLParserWrapper> OM = new BuilderFactory<OMXMLParserWrapper>() {
         @Override
-        OMXMLParserWrapper createBuilder(NodeFactory nodeFactory, XmlInput input,
-                Detachable detachable) {
-            return new OMXMLParserWrapperImpl(new BuilderImpl(input, nodeFactory,
-                    PlainXMLModel.INSTANCE, null), detachable);
+        OMXMLParserWrapper createBuilder(NodeFactory nodeFactory, BuilderSpec spec) {
+            return new OMXMLParserWrapperImpl(new BuilderImpl(spec.getInput(), nodeFactory,
+                    PlainXMLModel.INSTANCE, null), spec.getDetachable());
         }
     };
 
     final static BuilderFactory<SOAPModelBuilder> SOAP = new BuilderFactory<SOAPModelBuilder>() {
         @Override
-        SOAPModelBuilder createBuilder(NodeFactory nodeFactory, XmlInput input,
-                Detachable detachable) {
-            BuilderImpl builder = new BuilderImpl(new FilteredXmlInput(input, SOAPFilter.INSTANCE), nodeFactory, new SOAPModel(), null);
+        SOAPModelBuilder createBuilder(NodeFactory nodeFactory, BuilderSpec spec) {
+            BuilderImpl builder = new BuilderImpl(new FilteredXmlInput(spec.getInput(), SOAPFilter.INSTANCE), nodeFactory, new SOAPModel(), null);
             // The SOAPFactory instance linked to the SOAPMessage is unknown until we reach the
             // SOAPEnvelope. Register a post-processor that does the necessary updates on the
             // SOAPMessage.
@@ -111,139 +63,9 @@ abstract class BuilderFactory<T extends
                     return null;
                 }
             });
-            return new SOAPModelBuilderImpl(builder, detachable);
+            return new SOAPModelBuilderImpl(builder, spec.getDetachable());
         }
     };
 
-    private static SourceInfo createSourceInfo(StAXParserConfiguration configuration,
-            InputSource is, boolean makeDetachable) {
-        XMLStreamReader reader;
-        Detachable detachable;
-        Closeable closeable;
-        try {
-            if (is.getByteStream() != null) {
-                String systemId = is.getSystemId();
-                String encoding = is.getEncoding();
-                InputStream in = is.getByteStream();
-                if (makeDetachable) {
-                    DetachableInputStream detachableInputStream = new DetachableInputStream(in, false);
-                    in = detachableInputStream;
-                    detachable = detachableInputStream;
-                } else {
-                    detachable = null;
-                }
-                if (systemId != null) {
-                    if (encoding == null) {
-                        reader = StAXUtils.createXMLStreamReader(configuration, systemId, in);
-                    } else {
-                        throw new UnsupportedOperationException();
-                    }
-                } else {
-                    if (encoding == null) {
-                        reader = StAXUtils.createXMLStreamReader(configuration, in);
-                    } else {
-                        reader = StAXUtils.createXMLStreamReader(configuration, in, encoding);
-                    }
-                }
-                closeable = null;
-            } else if (is.getCharacterStream() != null) {
-                Reader in = is.getCharacterStream();
-                if (makeDetachable) {
-                    DetachableReader detachableReader = new DetachableReader(in);
-                    in = detachableReader;
-                    detachable = detachableReader;
-                } else {
-                    detachable = null;
-                }
-                reader = StAXUtils.createXMLStreamReader(configuration, in);
-                closeable = null;
-            } else {
-                String systemId = is.getSystemId();
-                InputStream in = new URL(systemId).openConnection().getInputStream();
-                if (makeDetachable) {
-                    DetachableInputStream detachableInputStream = new DetachableInputStream(in, true);
-                    in = detachableInputStream;
-                    detachable = detachableInputStream;
-                } else {
-                    detachable = null;
-                }
-                reader = StAXUtils.createXMLStreamReader(configuration, systemId, in);
-                closeable = in;
-            }
-        } catch (XMLStreamException ex) {
-            throw new OMException(ex);
-        } catch (IOException ex) {
-            throw new OMException(ex);
-        }
-        return new SourceInfo(new StAXPullInput(reader, true, closeable), detachable);
-    }
-    
-    abstract T createBuilder(NodeFactory nodeFactory, XmlInput input, Detachable detachable);
-    
-    final T createBuilder(NodeFactory nodeFactory, XMLStreamReader reader) {
-        int eventType = reader.getEventType();
-        switch (eventType) {
-            case XMLStreamReader.START_DOCUMENT:
-                break;
-            case XMLStreamReader.START_ELEMENT:
-                reader = new XMLFragmentStreamReader(reader);
-                break;
-            default:
-                throw new OMException("The supplied XMLStreamReader is in an unexpected state ("
-                        + XMLEventUtils.getEventTypeString(eventType) + ")");
-        }
-        return createBuilder(nodeFactory, new FilteredXmlInput(new StAXPullInput(reader, false, null), NamespaceRepairingFilter.DEFAULT), null);
-    }
-
-    final T createBuilder(NodeFactory nodeFactory, StAXParserConfiguration configuration,
-            InputSource is) {
-        SourceInfo sourceInfo = createSourceInfo(configuration, is, true);
-        return createBuilder(nodeFactory,
-                sourceInfo.getInput(),
-                sourceInfo.getDetachable());
-    }
-
-    final T createBuilder(NodeFactory nodeFactory, StAXParserConfiguration configuration, Source source) {
-        if (source instanceof SAXSource) {
-            return createBuilder(nodeFactory, (SAXSource)source, true);
-        } else if (source instanceof DOMSource) {
-            return createBuilder(nodeFactory, ((DOMSource)source).getNode(), true);
-        } else if (source instanceof StreamSource) {
-            StreamSource streamSource = (StreamSource)source;
-            InputSource is = new InputSource();
-            is.setByteStream(streamSource.getInputStream());
-            is.setCharacterStream(streamSource.getReader());
-            is.setPublicId(streamSource.getPublicId());
-            is.setSystemId(streamSource.getSystemId());
-            return createBuilder(nodeFactory, configuration, is);
-        } else {
-            try {
-                return createBuilder(nodeFactory,
-                        new FilteredXmlInput(
-                                new StAXPullInput(StAXUtils.getXMLInputFactory().createXMLStreamReader(source), true, null),
-                                NamespaceRepairingFilter.DEFAULT),
-                        null);
-            } catch (XMLStreamException ex) {
-                throw new OMException(ex);
-            }
-        }
-    }
-
-    final T createBuilder(NodeFactory nodeFactory, Node node, boolean expandEntityReferences) {
-        return createBuilder(nodeFactory, new FilteredXmlInput(new DOMInput(node, expandEntityReferences), NamespaceRepairingFilter.DEFAULT), null);
-    }
-
-    final T createBuilder(NodeFactory nodeFactory, SAXSource source, boolean expandEntityReferences) {
-        return createBuilder(nodeFactory, new FilteredXmlInput(new SAXInput(source, expandEntityReferences), NamespaceRepairingFilter.DEFAULT), null);
-    }
-
-    final T createBuilder(NodeFactory nodeFactory, StAXParserConfiguration configuration,
-            InputSource rootPart, MimePartProvider mimePartProvider) {
-        SourceInfo sourceInfo = createSourceInfo(configuration, rootPart, false);
-        return createBuilder(nodeFactory,
-                new FilteredXmlInput(
-                        sourceInfo.getInput(),
-                        new XOPDecodingFilter(mimePartProvider)),
-                mimePartProvider instanceof Detachable ? (Detachable) mimePartProvider : null);
-    }
+    abstract T createBuilder(NodeFactory nodeFactory, BuilderSpec spec);
 }

Copied: webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/factory/BuilderSpec.java (from r1741349, webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/factory/BuilderFactory.java)
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/factory/BuilderSpec.java?p2=webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/factory/BuilderSpec.java&p1=webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/factory/BuilderFactory.java&r1=1741349&r2=1741355&rev=1741355&view=diff
==============================================================================
--- webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/factory/BuilderFactory.java (original)
+++ webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/factory/BuilderSpec.java Wed Apr 27 22:21:42 2016
@@ -31,11 +31,6 @@ import javax.xml.transform.dom.DOMSource
 import javax.xml.transform.sax.SAXSource;
 import javax.xml.transform.stream.StreamSource;
 
-import org.apache.axiom.core.CoreNode;
-import org.apache.axiom.core.NodeFactory;
-import org.apache.axiom.core.impl.builder.BuilderImpl;
-import org.apache.axiom.core.impl.builder.BuilderListener;
-import org.apache.axiom.core.impl.builder.PlainXMLModel;
 import org.apache.axiom.core.stream.FilteredXmlInput;
 import org.apache.axiom.core.stream.NamespaceRepairingFilter;
 import org.apache.axiom.core.stream.XmlInput;
@@ -43,79 +38,26 @@ import org.apache.axiom.core.stream.dom.
 import org.apache.axiom.core.stream.sax.SAXInput;
 import org.apache.axiom.mime.MimePartProvider;
 import org.apache.axiom.om.OMException;
-import org.apache.axiom.om.OMXMLParserWrapper;
 import org.apache.axiom.om.impl.builder.Detachable;
-import org.apache.axiom.om.impl.common.builder.OMXMLParserWrapperImpl;
 import org.apache.axiom.om.impl.stream.stax.StAXPullInput;
 import org.apache.axiom.om.impl.stream.xop.XOPDecodingFilter;
 import org.apache.axiom.om.util.StAXParserConfiguration;
 import org.apache.axiom.om.util.StAXUtils;
-import org.apache.axiom.soap.SOAPFactory;
-import org.apache.axiom.soap.SOAPModelBuilder;
-import org.apache.axiom.soap.impl.common.builder.SOAPFilter;
-import org.apache.axiom.soap.impl.common.builder.SOAPModel;
-import org.apache.axiom.soap.impl.common.builder.SOAPModelBuilderImpl;
-import org.apache.axiom.soap.impl.intf.AxiomSOAPEnvelope;
-import org.apache.axiom.soap.impl.intf.AxiomSOAPMessage;
 import org.apache.axiom.util.stax.XMLEventUtils;
 import org.apache.axiom.util.stax.XMLFragmentStreamReader;
 import org.w3c.dom.Node;
 import org.xml.sax.InputSource;
 
-abstract class BuilderFactory<T extends OMXMLParserWrapper> {
-    private final static class SourceInfo {
-        private final XmlInput input;
-        private final Detachable detachable;
-        
-        SourceInfo(XmlInput input, Detachable detachable) {
-            this.input = input;
-            this.detachable = detachable;
-        }
-
-        XmlInput getInput() {
-            return input;
-        }
+final class BuilderSpec {
+    private final XmlInput input;
+    private final Detachable detachable;
 
-        Detachable getDetachable() {
-            return detachable;
-        }
+    private BuilderSpec(XmlInput input, Detachable detachable) {
+        this.input = input;
+        this.detachable = detachable;
     }
-    
-    final static BuilderFactory<OMXMLParserWrapper> OM = new BuilderFactory<OMXMLParserWrapper>() {
-        @Override
-        OMXMLParserWrapper createBuilder(NodeFactory nodeFactory, XmlInput input,
-                Detachable detachable) {
-            return new OMXMLParserWrapperImpl(new BuilderImpl(input, nodeFactory,
-                    PlainXMLModel.INSTANCE, null), detachable);
-        }
-    };
 
-    final static BuilderFactory<SOAPModelBuilder> SOAP = new BuilderFactory<SOAPModelBuilder>() {
-        @Override
-        SOAPModelBuilder createBuilder(NodeFactory nodeFactory, XmlInput input,
-                Detachable detachable) {
-            BuilderImpl builder = new BuilderImpl(new FilteredXmlInput(input, SOAPFilter.INSTANCE), nodeFactory, new SOAPModel(), null);
-            // The SOAPFactory instance linked to the SOAPMessage is unknown until we reach the
-            // SOAPEnvelope. Register a post-processor that does the necessary updates on the
-            // SOAPMessage.
-            builder.addListener(new BuilderListener() {
-                private AxiomSOAPMessage message;
-                
-                @Override
-                public Runnable nodeAdded(CoreNode node, int depth) {
-                    if (node instanceof AxiomSOAPMessage) {
-                        message = (AxiomSOAPMessage)node;
-                    } else if (message != null && node instanceof AxiomSOAPEnvelope) {
-                        message.initSOAPFactory((SOAPFactory)((AxiomSOAPEnvelope)node).getOMFactory());
-                    }
-                    return null;
-                }
-            });
-            return new SOAPModelBuilderImpl(builder, detachable);
-        }
-    };
-
-    private static SourceInfo createSourceInfo(StAXParserConfiguration configuration,
+    private static BuilderSpec create(StAXParserConfiguration configuration,
             InputSource is, boolean makeDetachable) {
         XMLStreamReader reader;
         Detachable detachable;
@@ -175,12 +117,10 @@ abstract class BuilderFactory<T extends
         } catch (IOException ex) {
             throw new OMException(ex);
         }
-        return new SourceInfo(new StAXPullInput(reader, true, closeable), detachable);
+        return new BuilderSpec(new StAXPullInput(reader, true, closeable), detachable);
     }
     
-    abstract T createBuilder(NodeFactory nodeFactory, XmlInput input, Detachable detachable);
-    
-    final T createBuilder(NodeFactory nodeFactory, XMLStreamReader reader) {
+    static BuilderSpec from(XMLStreamReader reader) {
         int eventType = reader.getEventType();
         switch (eventType) {
             case XMLStreamReader.START_DOCUMENT:
@@ -192,22 +132,19 @@ abstract class BuilderFactory<T extends
                 throw new OMException("The supplied XMLStreamReader is in an unexpected state ("
                         + XMLEventUtils.getEventTypeString(eventType) + ")");
         }
-        return createBuilder(nodeFactory, new FilteredXmlInput(new StAXPullInput(reader, false, null), NamespaceRepairingFilter.DEFAULT), null);
+        return new BuilderSpec(new FilteredXmlInput(new StAXPullInput(reader, false, null), NamespaceRepairingFilter.DEFAULT), null);
     }
 
-    final T createBuilder(NodeFactory nodeFactory, StAXParserConfiguration configuration,
+    static BuilderSpec from(StAXParserConfiguration configuration,
             InputSource is) {
-        SourceInfo sourceInfo = createSourceInfo(configuration, is, true);
-        return createBuilder(nodeFactory,
-                sourceInfo.getInput(),
-                sourceInfo.getDetachable());
+        return create(configuration, is, true);
     }
 
-    final T createBuilder(NodeFactory nodeFactory, StAXParserConfiguration configuration, Source source) {
+    static BuilderSpec from(StAXParserConfiguration configuration, Source source) {
         if (source instanceof SAXSource) {
-            return createBuilder(nodeFactory, (SAXSource)source, true);
+            return from((SAXSource)source, true);
         } else if (source instanceof DOMSource) {
-            return createBuilder(nodeFactory, ((DOMSource)source).getNode(), true);
+            return from(((DOMSource)source).getNode(), true);
         } else if (source instanceof StreamSource) {
             StreamSource streamSource = (StreamSource)source;
             InputSource is = new InputSource();
@@ -215,10 +152,10 @@ abstract class BuilderFactory<T extends
             is.setCharacterStream(streamSource.getReader());
             is.setPublicId(streamSource.getPublicId());
             is.setSystemId(streamSource.getSystemId());
-            return createBuilder(nodeFactory, configuration, is);
+            return from(configuration, is);
         } else {
             try {
-                return createBuilder(nodeFactory,
+                return new BuilderSpec(
                         new FilteredXmlInput(
                                 new StAXPullInput(StAXUtils.getXMLInputFactory().createXMLStreamReader(source), true, null),
                                 NamespaceRepairingFilter.DEFAULT),
@@ -229,21 +166,29 @@ abstract class BuilderFactory<T extends
         }
     }
 
-    final T createBuilder(NodeFactory nodeFactory, Node node, boolean expandEntityReferences) {
-        return createBuilder(nodeFactory, new FilteredXmlInput(new DOMInput(node, expandEntityReferences), NamespaceRepairingFilter.DEFAULT), null);
+    static BuilderSpec from(Node node, boolean expandEntityReferences) {
+        return new BuilderSpec(new FilteredXmlInput(new DOMInput(node, expandEntityReferences), NamespaceRepairingFilter.DEFAULT), null);
     }
 
-    final T createBuilder(NodeFactory nodeFactory, SAXSource source, boolean expandEntityReferences) {
-        return createBuilder(nodeFactory, new FilteredXmlInput(new SAXInput(source, expandEntityReferences), NamespaceRepairingFilter.DEFAULT), null);
+    static BuilderSpec from(SAXSource source, boolean expandEntityReferences) {
+        return new BuilderSpec(new FilteredXmlInput(new SAXInput(source, expandEntityReferences), NamespaceRepairingFilter.DEFAULT), null);
     }
 
-    final T createBuilder(NodeFactory nodeFactory, StAXParserConfiguration configuration,
+    static BuilderSpec from(StAXParserConfiguration configuration,
             InputSource rootPart, MimePartProvider mimePartProvider) {
-        SourceInfo sourceInfo = createSourceInfo(configuration, rootPart, false);
-        return createBuilder(nodeFactory,
+        BuilderSpec spec = create(configuration, rootPart, false);
+        return new BuilderSpec(
                 new FilteredXmlInput(
-                        sourceInfo.getInput(),
+                        spec.getInput(),
                         new XOPDecodingFilter(mimePartProvider)),
                 mimePartProvider instanceof Detachable ? (Detachable) mimePartProvider : null);
     }
+
+    XmlInput getInput() {
+        return input;
+    }
+
+    Detachable getDetachable() {
+        return detachable;
+    }
 }