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/02/27 00:47:46 UTC
svn commit: r1732585 - in /webservices/axiom/trunk/aspects:
core-aspects/src/main/java/org/apache/axiom/core/
om-aspects/src/main/java/org/apache/axiom/om/impl/common/builder/
om-aspects/src/main/java/org/apache/axiom/om/impl/mixin/
Author: veithen
Date: Fri Feb 26 23:47:46 2016
New Revision: 1732585
URL: http://svn.apache.org/viewvc?rev=1732585&view=rev
Log:
Use a smarter way to implement serializeAndConsume.
Modified:
webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/InputContext.java
webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/builder/BuilderHandler.java
webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/builder/Context.java
webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/mixin/AxiomContainerSupport.aj
Modified: webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/InputContext.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/InputContext.java?rev=1732585&r1=1732584&r2=1732585&view=diff
==============================================================================
--- webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/InputContext.java (original)
+++ webservices/axiom/trunk/aspects/core-aspects/src/main/java/org/apache/axiom/core/InputContext.java Fri Feb 26 23:47:46 2016
@@ -18,6 +18,20 @@
*/
package org.apache.axiom.core;
+import org.apache.axiom.core.stream.XmlHandler;
+
public interface InputContext {
Builder getBuilder();
+
+ /**
+ * Enables pass-through mode for this context. In this mode, events for the parent information
+ * item linked to this context (and its descendants) are passed directly to the specified
+ * handler instead of building nodes for them.
+ *
+ * @param handler
+ * the handler to send events to
+ * @throws IllegalStateException
+ * if a pass-through handler has already been set for this context
+ */
+ void setPassThroughHandler(XmlHandler passThroughHandler);
}
Modified: webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/builder/BuilderHandler.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/builder/BuilderHandler.java?rev=1732585&r1=1732584&r2=1732585&view=diff
==============================================================================
--- webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/builder/BuilderHandler.java (original)
+++ webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/builder/BuilderHandler.java Fri Feb 26 23:47:46 2016
@@ -30,6 +30,7 @@ import org.apache.axiom.core.Builder;
import org.apache.axiom.core.CoreNode;
import org.apache.axiom.core.CoreParentNode;
import org.apache.axiom.core.NodeFactory;
+import org.apache.axiom.core.stream.StreamException;
import org.apache.axiom.core.stream.XmlHandler;
import org.apache.axiom.om.impl.intf.AxiomDocument;
import org.apache.axiom.om.impl.intf.AxiomSourcedElement;
@@ -131,58 +132,58 @@ public final class BuilderHandler implem
}
public void processDocumentTypeDeclaration(String rootName, String publicId, String systemId,
- String internalSubset) {
+ String internalSubset) throws StreamException {
model.validateEventType(XMLStreamConstants.DTD);
context.processDocumentTypeDeclaration(rootName, publicId, systemId, internalSubset);
}
- public void startElement(String namespaceURI, String localName, String prefix) {
+ public void startElement(String namespaceURI, String localName, String prefix) throws StreamException {
depth++;
context = context.startElement(namespaceURI, localName, prefix);
}
- public void endElement() {
+ public void endElement() throws StreamException {
context = context.endElement();
depth--;
}
- public void processAttribute(String namespaceURI, String localName, String prefix, String value, String type, boolean specified) {
+ public void processAttribute(String namespaceURI, String localName, String prefix, String value, String type, boolean specified) throws StreamException {
context.processAttribute(namespaceURI, localName, prefix, value, type, specified);
}
- public void processNamespaceDeclaration(String prefix, String namespaceURI) {
+ public void processNamespaceDeclaration(String prefix, String namespaceURI) throws StreamException {
context.processNamespaceDeclaration(prefix, namespaceURI);
}
- public void attributesCompleted() {
+ public void attributesCompleted() throws StreamException {
context.attributesCompleted();
}
- public void processCharacterData(Object data, boolean ignorable) {
+ public void processCharacterData(Object data, boolean ignorable) throws StreamException {
context.processCharacterData(data, ignorable);
}
- public void processProcessingInstruction(String piTarget, String piData) {
+ public void processProcessingInstruction(String piTarget, String piData) throws StreamException {
model.validateEventType(XMLStreamConstants.PROCESSING_INSTRUCTION);
context.processProcessingInstruction(piTarget, piData);
}
- public void processComment(String content) {
+ public void processComment(String content) throws StreamException {
model.validateEventType(XMLStreamConstants.COMMENT);
context.processComment(content);
}
- public void processCDATASection(String content) {
+ public void processCDATASection(String content) throws StreamException {
model.validateEventType(XMLStreamConstants.CDATA);
context.processCDATASection(content);
}
- public void processEntityReference(String name, String replacementText) {
+ public void processEntityReference(String name, String replacementText) throws StreamException {
model.validateEventType(XMLStreamConstants.ENTITY_REFERENCE);
context.processEntityReference(name, replacementText);
}
- public void endDocument() {
+ public void endDocument() throws StreamException {
if (depth != 0) {
throw new IllegalStateException();
}
Modified: webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/builder/Context.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/builder/Context.java?rev=1732585&r1=1732584&r2=1732585&view=diff
==============================================================================
--- webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/builder/Context.java (original)
+++ webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/common/builder/Context.java Fri Feb 26 23:47:46 2016
@@ -22,6 +22,8 @@ import org.apache.axiom.core.Builder;
import org.apache.axiom.core.CoreCharacterDataNode;
import org.apache.axiom.core.CoreParentNode;
import org.apache.axiom.core.InputContext;
+import org.apache.axiom.core.stream.StreamException;
+import org.apache.axiom.core.stream.XmlHandler;
import org.apache.axiom.om.OMNamespace;
import org.apache.axiom.om.impl.common.AxiomSemantics;
import org.apache.axiom.om.impl.common.OMNamespaceImpl;
@@ -49,6 +51,17 @@ public final class Context implements In
private Object pendingCharacterData;
+ /**
+ * The {@link XmlHandler} object to send events to if pass-through is enabled. See
+ * {@link InputContext#setPassThroughHandler(XmlHandler)} for more details.
+ */
+ private XmlHandler passThroughHandler;
+
+ /**
+ * Tracks the nesting depth when pass-through is enabled.
+ */
+ private int passThroughDepth;
+
public Context(BuilderHandler builderHandler, Context parentContext, int depth) {
this.builderHandler = builderHandler;
this.parentContext = parentContext;
@@ -60,14 +73,36 @@ public final class Context implements In
return builderHandler.builder;
}
+ public void setPassThroughHandler(XmlHandler passThroughHandler) {
+ if (this.passThroughHandler != null) {
+ throw new IllegalStateException("A pass-through handler has already been set for this context");
+ }
+ target.coreSetState(CoreParentNode.DISCARDED);
+ this.passThroughHandler = passThroughHandler;
+ }
+
private Context newContext(AxiomContainer target) {
if (nestedContext == null) {
nestedContext = new Context(builderHandler, this, depth+1);
}
nestedContext.target = target;
+ target.coreSetInputContext(nestedContext);
return nestedContext;
}
+ private Context decrementPassThroughDepth() {
+ if (passThroughDepth == 0) {
+ target.coreSetInputContext(null);
+ target.coreSetState(CoreParentNode.DISCARDED);
+ passThroughHandler = null;
+ target = null;
+ return parentContext;
+ } else {
+ passThroughDepth--;
+ return this;
+ }
+ }
+
private void addChild(AxiomChildNode node) {
if (pendingCharacterData != null) {
AxiomCharacterDataNode cdataNode = builderHandler.nodeFactory.createNode(AxiomCharacterDataNode.class);
@@ -82,73 +117,104 @@ public final class Context implements In
}
public void processDocumentTypeDeclaration(String rootName, String publicId, String systemId,
- String internalSubset) {
- AxiomDocType node = builderHandler.nodeFactory.createNode(AxiomDocType.class);
- node.coreSetRootName(rootName);
- node.coreSetPublicId(publicId);
- node.coreSetSystemId(systemId);
- node.coreSetInternalSubset(internalSubset);
- addChild(node);
- }
-
- public Context startElement(String namespaceURI, String localName, String prefix) {
- AxiomElement element;
- OMNamespace ns = builderHandler.nsCache.getOMNamespace(namespaceURI, prefix);
- if (depth == 0 && builderHandler.root != null) {
- builderHandler.root.validateName(prefix, localName, namespaceURI);
- builderHandler.root.initName(localName, ns, false);
- builderHandler.root.coreSetInputContext(this);
- builderHandler.root.coreSetState(CoreParentNode.ATTRIBUTES_PENDING);
- element = builderHandler.root;
- } else {
- element = builderHandler.nodeFactory.createNode(builderHandler.model.determineElementType(
- target, depth+1, namespaceURI, localName));
- element.coreSetInputContext(this);
- element.coreSetState(CoreParentNode.ATTRIBUTES_PENDING);
- element.initName(localName, ns, false);
- addChild(element);
- }
- return newContext(element);
- }
-
- public Context endElement() {
- target.setComplete(true);
- target.coreSetInputContext(null);
- if (pendingCharacterData != null) {
- target.coreSetCharacterData(pendingCharacterData, null);
- pendingCharacterData = null;
+ String internalSubset) throws StreamException {
+ if (passThroughHandler != null) {
+ passThroughHandler.processDocumentTypeDeclaration(rootName, publicId, systemId, internalSubset);
+ } else {
+ AxiomDocType node = builderHandler.nodeFactory.createNode(AxiomDocType.class);
+ node.coreSetRootName(rootName);
+ node.coreSetPublicId(publicId);
+ node.coreSetSystemId(systemId);
+ node.coreSetInternalSubset(internalSubset);
+ addChild(node);
+ }
+ }
+
+ public Context startElement(String namespaceURI, String localName, String prefix) throws StreamException {
+ if (passThroughHandler != null) {
+ passThroughDepth++;
+ passThroughHandler.startElement(namespaceURI, localName, prefix);
+ return this;
+ } else {
+ AxiomElement element;
+ OMNamespace ns = builderHandler.nsCache.getOMNamespace(namespaceURI, prefix);
+ if (depth == 0 && builderHandler.root != null) {
+ builderHandler.root.validateName(prefix, localName, namespaceURI);
+ builderHandler.root.initName(localName, ns, false);
+ builderHandler.root.coreSetInputContext(this);
+ builderHandler.root.coreSetState(CoreParentNode.ATTRIBUTES_PENDING);
+ element = builderHandler.root;
+ } else {
+ element = builderHandler.nodeFactory.createNode(builderHandler.model.determineElementType(
+ target, depth+1, namespaceURI, localName));
+ element.coreSetState(CoreParentNode.ATTRIBUTES_PENDING);
+ element.initName(localName, ns, false);
+ addChild(element);
+ }
+ return newContext(element);
+ }
+ }
+
+ public Context endElement() throws StreamException {
+ if (passThroughHandler != null) {
+ // TODO: hack
+ if (passThroughDepth > 0) {
+ passThroughHandler.endElement();
+ }
+ return decrementPassThroughDepth();
+ } else {
+ target.setComplete(true);
+ target.coreSetInputContext(null);
+ if (pendingCharacterData != null) {
+ target.coreSetCharacterData(pendingCharacterData, null);
+ pendingCharacterData = null;
+ }
+ target = null;
+ return parentContext;
}
- target = null;
- return parentContext;
}
- public void processAttribute(String namespaceURI, String localName, String prefix, String value, String type, boolean specified) {
- OMNamespace ns = builderHandler.nsCache.getOMNamespace(namespaceURI, prefix);
- AxiomAttribute attr = builderHandler.nodeFactory.createNode(AxiomAttribute.class);
- attr.internalSetLocalName(localName);
- attr.coreSetCharacterData(value, AxiomSemantics.INSTANCE);
- attr.internalSetNamespace(ns);
- attr.coreSetType(type);
- attr.coreSetSpecified(specified);
- ((AxiomElement)target).coreAppendAttribute(attr);
+ public void processAttribute(String namespaceURI, String localName, String prefix, String value, String type, boolean specified) throws StreamException {
+ if (passThroughHandler != null) {
+ passThroughHandler.processAttribute(namespaceURI, localName, prefix, value, type, specified);
+ } else {
+ OMNamespace ns = builderHandler.nsCache.getOMNamespace(namespaceURI, prefix);
+ AxiomAttribute attr = builderHandler.nodeFactory.createNode(AxiomAttribute.class);
+ attr.internalSetLocalName(localName);
+ attr.coreSetCharacterData(value, AxiomSemantics.INSTANCE);
+ attr.internalSetNamespace(ns);
+ attr.coreSetType(type);
+ attr.coreSetSpecified(specified);
+ ((AxiomElement)target).coreAppendAttribute(attr);
+ }
}
- public void processNamespaceDeclaration(String prefix, String namespaceURI) {
- OMNamespace ns = builderHandler.nsCache.getOMNamespace(namespaceURI, prefix);
- if (ns == null) {
- ns = DEFAULT_NS;
+ public void processNamespaceDeclaration(String prefix, String namespaceURI) throws StreamException {
+ if (passThroughHandler != null) {
+ passThroughHandler.processNamespaceDeclaration(prefix, namespaceURI);
+ } else {
+ OMNamespace ns = builderHandler.nsCache.getOMNamespace(namespaceURI, prefix);
+ if (ns == null) {
+ ns = DEFAULT_NS;
+ }
+ AxiomNamespaceDeclaration decl = builderHandler.nodeFactory.createNode(AxiomNamespaceDeclaration.class);
+ decl.setDeclaredNamespace(ns);
+ ((AxiomElement)target).coreAppendAttribute(decl);
}
- AxiomNamespaceDeclaration decl = builderHandler.nodeFactory.createNode(AxiomNamespaceDeclaration.class);
- decl.setDeclaredNamespace(ns);
- ((AxiomElement)target).coreAppendAttribute(decl);
}
- public void attributesCompleted() {
- target.coreSetState(CoreParentNode.INCOMPLETE);
+ public void attributesCompleted() throws StreamException {
+ if (passThroughHandler != null) {
+ passThroughHandler.attributesCompleted();
+ } else {
+ target.coreSetState(CoreParentNode.INCOMPLETE);
+ }
}
- public void processCharacterData(Object data, boolean ignorable) {
- if (!ignorable && pendingCharacterData == null && target.coreGetFirstChildIfAvailable() == null) {
+ public void processCharacterData(Object data, boolean ignorable) throws StreamException {
+ if (passThroughHandler != null) {
+ passThroughHandler.processCharacterData(data, ignorable);
+ } else if (!ignorable && pendingCharacterData == null && target.coreGetFirstChildIfAvailable() == null) {
pendingCharacterData = data;
} else {
AxiomCharacterDataNode node = builderHandler.nodeFactory.createNode(AxiomCharacterDataNode.class);
@@ -158,40 +224,64 @@ public final class Context implements In
}
}
- public void processProcessingInstruction(String piTarget, String piData) {
- AxiomProcessingInstruction node = builderHandler.nodeFactory.createNode(AxiomProcessingInstruction.class);
- node.coreSetTarget(piTarget);
- node.coreSetCharacterData(piData, AxiomSemantics.INSTANCE);
- addChild(node);
+ public void processProcessingInstruction(String piTarget, String piData) throws StreamException {
+ if (passThroughHandler != null) {
+ passThroughHandler.processProcessingInstruction(piTarget, piData);
+ } else {
+ AxiomProcessingInstruction node = builderHandler.nodeFactory.createNode(AxiomProcessingInstruction.class);
+ node.coreSetTarget(piTarget);
+ node.coreSetCharacterData(piData, AxiomSemantics.INSTANCE);
+ addChild(node);
+ }
}
- public void processComment(String content) {
- AxiomComment node = builderHandler.nodeFactory.createNode(AxiomComment.class);
- node.coreSetCharacterData(content, AxiomSemantics.INSTANCE);
- addChild(node);
+ public void processComment(String content) throws StreamException {
+ if (passThroughHandler != null) {
+ passThroughHandler.processComment(content);
+ } else {
+ AxiomComment node = builderHandler.nodeFactory.createNode(AxiomComment.class);
+ node.coreSetCharacterData(content, AxiomSemantics.INSTANCE);
+ addChild(node);
+ }
}
- public void processCDATASection(String content) {
- AxiomCDATASection node = builderHandler.nodeFactory.createNode(AxiomCDATASection.class);
- node.coreSetCharacterData(content, AxiomSemantics.INSTANCE);
- addChild(node);
+ public void processCDATASection(String content) throws StreamException {
+ if (passThroughHandler != null) {
+ passThroughHandler.processCDATASection(content);
+ } else {
+ AxiomCDATASection node = builderHandler.nodeFactory.createNode(AxiomCDATASection.class);
+ node.coreSetCharacterData(content, AxiomSemantics.INSTANCE);
+ addChild(node);
+ }
}
- public void processEntityReference(String name, String replacementText) {
- AxiomEntityReference node = builderHandler.nodeFactory.createNode(AxiomEntityReference.class);
- node.coreSetName(name);
- node.coreSetReplacementText(replacementText);
- addChild(node);
+ public void processEntityReference(String name, String replacementText) throws StreamException {
+ if (passThroughHandler != null) {
+ passThroughHandler.processEntityReference(name, replacementText);
+ } else {
+ AxiomEntityReference node = builderHandler.nodeFactory.createNode(AxiomEntityReference.class);
+ node.coreSetName(name);
+ node.coreSetReplacementText(replacementText);
+ addChild(node);
+ }
}
- public void endDocument() {
- if (depth != 0) {
- throw new IllegalStateException();
- }
- if (target != null) {
- target.setComplete(true);
- target.coreSetInputContext(null);
+ public void endDocument() throws StreamException {
+ if (passThroughHandler != null) {
+ // TODO: hack
+ if (passThroughDepth > 0) {
+ passThroughHandler.endDocument();
+ }
+ decrementPassThroughDepth();
+ } else {
+ if (depth != 0) {
+ throw new IllegalStateException();
+ }
+ if (target != null) {
+ target.setComplete(true);
+ target.coreSetInputContext(null);
+ }
+ target = null;
}
- target = null;
}
}
Modified: webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/mixin/AxiomContainerSupport.aj
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/mixin/AxiomContainerSupport.aj?rev=1732585&r1=1732584&r2=1732585&view=diff
==============================================================================
--- webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/mixin/AxiomContainerSupport.aj (original)
+++ webservices/axiom/trunk/aspects/om-aspects/src/main/java/org/apache/axiom/om/impl/mixin/AxiomContainerSupport.aj Fri Feb 26 23:47:46 2016
@@ -36,6 +36,7 @@ import org.apache.axiom.core.CoreModelEx
import org.apache.axiom.core.CoreNSAwareElement;
import org.apache.axiom.core.CoreNode;
import org.apache.axiom.core.ElementMatcher;
+import org.apache.axiom.core.InputContext;
import org.apache.axiom.core.Mapper;
import org.apache.axiom.core.stream.NamespaceRepairingFilterHandler;
import org.apache.axiom.core.stream.StreamException;
@@ -58,7 +59,6 @@ import org.apache.axiom.om.impl.common.A
import org.apache.axiom.om.impl.common.NamespaceURIInterningXMLStreamReaderWrapper;
import org.apache.axiom.om.impl.common.OMChildrenQNameIterator;
import org.apache.axiom.om.impl.common.SAXResultContentHandler;
-import org.apache.axiom.om.impl.common.builder.StAXHelper;
import org.apache.axiom.om.impl.common.serializer.pull.OMXMLStreamReaderExAdapter;
import org.apache.axiom.om.impl.common.serializer.pull.PullSerializer;
import org.apache.axiom.om.impl.common.serializer.push.XmlDeclarationRewriterHandler;
@@ -372,44 +372,13 @@ public aspect AxiomContainerSupport {
child.internalSerialize(handler, cache);
child = (AxiomChildNode)child.coreGetNextSiblingIfAvailable();
}
- // Next, if the container is incomplete, disable caching (temporarily)
- // and serialize the nodes that have not been built yet by copying the
- // events from the underlying XMLStreamReader.
- if (!isComplete() && coreGetBuilder() != null) {
- Builder builder = coreGetBuilder();
- XMLStreamReader reader = builder.disableCaching();
- // The reader is null in the very special case where this is an OMDocument and
- // the current event is END_DOCUMENT (which means that auto-close is triggered
- // and the parser is released, resulting in a null value).
- if (reader != null) {
- StAXHelper helper = new StAXHelper(reader, handler);
- int depth = 0;
- loop: while (true) {
- switch (helper.lookahead()) {
- case XMLStreamReader.START_ELEMENT:
- depth++;
- break;
- case XMLStreamReader.END_ELEMENT:
- if (depth == 0) {
- break loop;
- } else {
- depth--;
- }
- break;
- case XMLStreamReader.END_DOCUMENT:
- if (depth != 0) {
- // If we get here, then we have seen a START_ELEMENT event without
- // a matching END_ELEMENT
- throw new IllegalStateException();
- }
- break loop;
- }
- // Note that we don't copy the final END_ELEMENT/END_DOCUMENT event for
- // the container. This is the responsibility of the caller.
- helper.next();
- }
- }
- builder.reenableCaching(this);
+ InputContext context = coreGetInputContext();
+ if (context != null) {
+ context.setPassThroughHandler(handler);
+ Builder builder = context.getBuilder();
+ do {
+ builder.next();
+ } while (coreGetInputContext() != null);
}
}
}