blob: 837332818af4d49371a870f66f15652abb0ba683 [file] [log] [blame]
/*
* 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.dom;
import org.apache.axiom.om.OMCloneOptions;
import org.apache.axiom.om.OMContainer;
import org.apache.axiom.om.OMException;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNode;
import org.apache.axiom.om.OMOutputFormat;
import org.apache.axiom.om.OMXMLParserWrapper;
import org.apache.axiom.om.impl.MTOMXMLStreamWriter;
import org.apache.axiom.om.impl.OMNodeEx;
import org.apache.axiom.om.impl.builder.StAXBuilder;
import org.apache.axiom.om.util.StAXUtils;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.UserDataHandler;
import java.io.OutputStream;
import java.io.Writer;
import java.util.Hashtable;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
public abstract class NodeImpl implements Node {
/** Holds the user data objects */
private Hashtable userData; // Will be initialized in setUserData()
/** Factory that created this node */
protected final OMFactory factory;
// data
protected short flags;
/**
* Used by {@link ChildNode} to determine the meaning of the <code>ownerNode</code> attribute.
* If the flag is set, then the attribute contains the reference to the parent node. If the flag
* is not set, then the node has no parent and the attribute stores a reference to the owner
* document (which may be <code>null</code> if the owner document has not been created yet).
*/
protected final static short HAS_PARENT = 0x1 << 1;
protected final static short FIRSTCHILD = 0x1 << 2;
protected final static short SPECIFIED = 0x1 << 4;
//
// Constructors
//
protected NodeImpl(OMFactory factory) {
this.factory = factory;
}
void normalize(DOMConfigurationImpl config) {
// Default: do nothing
}
public void normalize() {
//Parent node should override this
}
public boolean hasAttributes() {
return false; // overridden in ElementImpl
}
public boolean hasChildNodes() {
return false; // Override in ParentNode
}
public String getLocalName() {
return null; // Override in AttrImpl and ElementImpl
}
public String getNamespaceURI() {
return null; // Override in AttrImpl and ElementImpl
}
public String getNodeValue() throws DOMException {
return null;
}
/*
* Overidden in ElementImpl and AttrImpl.
*/
public String getPrefix() {
return null;
}
public void setNodeValue(String nodeValue) throws DOMException {
// Don't do anything, to be overridden in SOME Child classes
}
public void setPrefix(String prefix) throws DOMException {
throw new DOMException(DOMException.NAMESPACE_ERR, DOMMessageFormatter
.formatMessage(DOMMessageFormatter.DOM_DOMAIN, DOMException.NAMESPACE_ERR,
null));
}
/**
* Returns the collection of attributes associated with this node, or null if none. At this
* writing, Element is the only type of node which will ever have attributes.
*
* @see ElementImpl
*/
public NamedNodeMap getAttributes() {
return null; // overridden in ElementImpl
}
/**
* Gets the first child of this Node, or null if none.
* <p/>
* By default we do not have any children, ParentNode overrides this.
*
* @see ParentNode
*/
public Node getFirstChild() {
return null;
}
/**
* Gets the last child of this Node, or null if none.
* <p/>
* By default we do not have any children, ParentNode overrides this.
*
* @see ParentNode
*/
public Node getLastChild() {
return null;
}
public final Node cloneNode(boolean deep) {
OMCloneOptions options = new OMCloneOptions();
// This is not specified by the API, but it's compatible with versions before 1.2.14
options.setPreserveModel(true);
NodeImpl clone = clone(options, null, getNodeType() == Node.ATTRIBUTE_NODE ? true : deep);
if (!(clone instanceof DocumentImpl)) {
clone.setOwnerDocument(ownerDocument());
}
return clone;
}
public boolean isSupported(String feature, String version) {
throw new UnsupportedOperationException();
// TODO
}
/*
* Flags setters and getters
*/
final boolean hasParent() {
return (flags & HAS_PARENT) != 0;
}
final void hasParent(boolean value) {
flags = (short) (value ? flags | HAS_PARENT : flags & ~HAS_PARENT);
}
final boolean isFirstChild() {
return (flags & FIRSTCHILD) != 0;
}
final void isFirstChild(boolean value) {
flags = (short) (value ? flags | FIRSTCHILD : flags & ~FIRSTCHILD);
}
final boolean isSpecified() {
return (flags & SPECIFIED) != 0;
}
final void isSpecified(boolean value) {
flags = (short) (value ? flags | SPECIFIED : flags & ~SPECIFIED);
}
/*
* DOM-Level 3 methods
*/
public String getBaseURI() {
// TODO TODO
throw new UnsupportedOperationException("TODO");
}
public short compareDocumentPosition(Node other) throws DOMException {
// This is not yet implemented. In the meantime, we throw a DOMException
// and not an UnsupportedOperationException, since this works better with
// some other libraries (such as Saxon 8.9).
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, DOMMessageFormatter
.formatMessage(DOMMessageFormatter.DOM_DOMAIN, DOMException.NOT_SUPPORTED_ERR, null));
}
public String getTextContent() throws DOMException {
return getNodeValue(); // overriden in some subclasses
}
// internal method taking a StringBuffer in parameter
void getTextContent(StringBuffer buf) throws DOMException {
String content = getNodeValue();
if (content != null) {
buf.append(content);
}
}
public void setTextContent(String textContent) throws DOMException {
setNodeValue(textContent); // overriden in some subclasses
}
public boolean isSameNode(Node node) {
// TODO : check
return this == node;
}
public String lookupPrefix(String namespaceURI) {
// TODO TODO
throw new UnsupportedOperationException("TODO");
}
public boolean isDefaultNamespace(String namespaceURI) {
// TODO TODO
throw new UnsupportedOperationException("TODO");
}
public String lookupNamespaceURI(String prefix) {
// TODO TODO
throw new UnsupportedOperationException("TODO");
}
/**
* Tests whether two nodes are equal. <br>This method tests for equality of nodes, not sameness
* (i.e., whether the two nodes are references to the same object) which can be tested with
* <code>Node.isSameNode()</code>. All nodes that are the same will also be equal, though the
* reverse may not be true. <br>Two nodes are equal if and only if the following conditions are
* satisfied: <ul> <li>The two nodes are of the same type. </li> <li>The following string
* attributes are equal: <code>nodeName</code>, <code>localName</code>,
* <code>namespaceURI</code>, <code>prefix</code>, <code>nodeValue</code> . This is: they are
* both <code>null</code>, or they have the same length and are character for character
* identical. </li> <li>The <code>attributes</code> <code>NamedNodeMaps</code> are equal. This
* is: they are both <code>null</code>, or they have the same length and for each node that
* exists in one map there is a node that exists in the other map and is equal, although not
* necessarily at the same index. </li> <li>The <code>childNodes</code> <code>NodeLists</code>
* are equal. This is: they are both <code>null</code>, or they have the same length and contain
* equal nodes at the same index. Note that normalization can affect equality; to avoid this,
* nodes should be normalized before being compared. </li> </ul> <br>For two
* <code>DocumentType</code> nodes to be equal, the following conditions must also be satisfied:
* <ul> <li>The following string attributes are equal: <code>publicId</code>,
* <code>systemId</code>, <code>internalSubset</code>. </li> <li>The <code>entities</code>
* <code>NamedNodeMaps</code> are equal. </li> <li>The <code>notations</code>
* <code>NamedNodeMaps</code> are equal. </li> </ul> <br>On the other hand, the following do not
* affect equality: the <code>ownerDocument</code>, <code>baseURI</code>, and
* <code>parentNode</code> attributes, the <code>specified</code> attribute for
* <code>Attr</code> nodes, the <code>schemaTypeInfo</code> attribute for <code>Attr</code> and
* <code>Element</code> nodes, the <code>Text.isElementContentWhitespace</code> attribute for
* <code>Text</code> nodes, as well as any user data or event listeners registered on the nodes.
* <p ><b>Note:</b> As a general rule, anything not mentioned in the description above is not
* significant in consideration of equality checking. Note that future versions of this
* specification may take into account more attributes and implementations conform to this
* specification are expected to be updated accordingly.
*
* @param node The node to compare equality with.
* @return Returns <code>true</code> if the nodes are equal, <code>false</code> otherwise.
* @since DOM Level 3
*/
//TODO : sumedha, complete
public boolean isEqualNode(Node node) {
final boolean equal = true;
final boolean notEqual = false;
if (this.getNodeType() != node.getNodeType()) {
return notEqual;
}
if (checkStringAttributeEquality(node)) {
if (checkNamedNodeMapEquality(node)) {
} else {
return notEqual;
}
} else {
return notEqual;
}
return equal;
}
private boolean checkStringAttributeEquality(Node node) {
final boolean equal = true;
final boolean notEqual = false;
// null not-null -> true
// not-null null -> true
// null null -> false
// not-null not-null -> false
//NodeName
if (node.getNodeName() == null ^ this.getNodeName() == null) {
return notEqual;
} else {
if (node.getNodeName() == null) {
//This means both are null.do nothing
} else {
if (!(node.getNodeName().equals(this.getNodeName()))) {
return notEqual;
}
}
}
//localName
if (node.getLocalName() == null ^ this.getLocalName() == null) {
return notEqual;
} else {
if (node.getLocalName() == null) {
//This means both are null.do nothing
} else {
if (!(node.getLocalName().equals(this.getLocalName()))) {
return notEqual;
}
}
}
//namespaceURI
if (node.getNamespaceURI() == null ^ this.getNamespaceURI() == null) {
return notEqual;
} else {
if (node.getNamespaceURI() == null) {
//This means both are null.do nothing
} else {
if (!(node.getNamespaceURI().equals(this.getNamespaceURI()))) {
return notEqual;
}
}
}
//prefix
if (node.getPrefix() == null ^ this.getPrefix() == null) {
return notEqual;
} else {
if (node.getPrefix() == null) {
//This means both are null.do nothing
} else {
if (!(node.getPrefix().equals(this.getPrefix()))) {
return notEqual;
}
}
}
//nodeValue
if (node.getNodeValue() == null ^ this.getNodeValue() == null) {
return notEqual;
} else {
if (node.getNodeValue() == null) {
//This means both are null.do nothing
} else {
if (!(node.getNodeValue().equals(this.getNodeValue()))) {
return notEqual;
}
}
}
return equal;
}
private boolean checkNamedNodeMapEquality(Node node) {
final boolean equal = true;
final boolean notEqual = false;
if (node.getAttributes() == null ^ this.getAttributes() == null) {
return notEqual;
}
NamedNodeMap thisNamedNodeMap = this.getAttributes();
NamedNodeMap nodeNamedNodeMap = node.getAttributes();
// null not-null -> true
// not-null null -> true
// null null -> false
// not-null not-null -> false
if (thisNamedNodeMap == null ^ nodeNamedNodeMap == null) {
return notEqual;
} else {
if (thisNamedNodeMap == null) {
//This means both are null.do nothing
} else {
if (thisNamedNodeMap.getLength() != nodeNamedNodeMap.getLength()) {
return notEqual;
} else {
//they have the same length and for each node that exists in one map
//there is a node that exists in the other map and is equal, although
//not necessarily at the same index.
int itemCount = thisNamedNodeMap.getLength();
for (int a = 0; a < itemCount; a++) {
NodeImpl thisNode = (NodeImpl) thisNamedNodeMap.item(a);
NodeImpl tmpNode =
(NodeImpl) nodeNamedNodeMap.getNamedItem(thisNode.getNodeName());
if (tmpNode == null) {
//i.e. no corresponding node
return notEqual;
} else {
if (!(thisNode.isEqualNode(tmpNode))) {
return notEqual;
}
}
}
}
}
}
return equal;
}
public Object getFeature(String feature, String version) {
// TODO TODO
throw new UnsupportedOperationException("TODO");
}
/* *
* userData storage/hashtable will be called only when the user needs to set user data. Previously, it was done as,
* for every node a new Hashtable created making the excution very inefficient. According to profiles, no. of method
* invocations to setUserData() method is very low, so this implementation is better.
* Another option:
* TODO do a profile and check the times for hashtable initialization. If it's still higher, we have to go to second option
* Create a separate class(UserData) to store key and value pairs. Then put those objects to a array with a reasonable size.
* then grow it accordingly. @ Kasun Gajasinghe
* @param key userData key
* @param value userData value
* @param userDataHandler it seems all invocations sends null for this parameter.
* Kept it for the moment just for being on the safe side.
* @return previous Object if one is set before.
*/
public Object setUserData(String key, Object value, UserDataHandler userDataHandler) {
if (userData == null) {
userData = new Hashtable();
}
return userData.put(key, value);
}
public Object getUserData(String key) {
if (userData != null) {
return userData.get(key);
}
return null;
}
/** Returns the <code>OMFactory</code> that created this node */
public OMFactory getOMFactory() {
return this.factory;
}
/**
* Get the parent or the owner document of the node. The meaning of the return value depends on
* the {@link NodeImpl#HAS_PARENT} flag.
*/
abstract ParentNode internalGetOwnerNode();
abstract void internalSetOwnerNode(ParentNode ownerNode);
abstract NodeImpl internalGetPreviousSibling();
abstract NodeImpl internalGetNextSibling();
abstract void internalSetPreviousSibling(NodeImpl previousSibling);
abstract void internalSetNextSibling(NodeImpl nextSibling);
/**
* Get the owner document of this node. In contrast to {@link Node#getOwnerDocument()}, this
* method returns a non null value when invoked on a {@link Document} instance.
*
* @return the owner document
*/
final DocumentImpl ownerDocument() {
ParentNode ownerNode = internalGetOwnerNode();
if (ownerNode == null) {
// As specified by DOMMetaFactory, the OMFactory for an implicitly created owner
// document is always the OMFactory for plain XML.
DocumentImpl document = new DocumentImpl(factory.getMetaFactory().getOMFactory());
internalSetOwnerNode(document);
return document;
} else if (ownerNode instanceof DocumentImpl) {
// Note: the value of the HAS_PARENT flag doesn't matter here. If the ownerNode is of
// type Document, it must be the owner document.
return (DocumentImpl)ownerNode;
} else {
return ownerNode.ownerDocument();
}
}
void checkSameOwnerDocument(Node otherNode) {
if (ownerDocument() != (otherNode instanceof AttrImpl
? ((AttrImpl)otherNode).getOwnerDocument()
: ((NodeImpl)otherNode).ownerDocument())) {
throw new DOMException(DOMException.WRONG_DOCUMENT_ERR,
DOMMessageFormatter.formatMessage(
DOMMessageFormatter.DOM_DOMAIN,
DOMException.WRONG_DOCUMENT_ERR, null));
}
}
/**
* Sets the owner document.
*
* @param document
*/
void setOwnerDocument(DocumentImpl document) {
if (hasParent()) {
throw new IllegalStateException();
}
internalSetOwnerNode(document);
}
public Document getOwnerDocument() {
return ownerDocument();
}
ParentNode parentNode() {
return hasParent() ? internalGetOwnerNode() : null;
}
public OMNode getNextOMSibling() throws OMException {
ParentNode parentNode = parentNode();
while (internalGetNextSibling() == null && parentNode != null && !parentNode.isComplete() && parentNode.getBuilder() != null) {
parentNode.buildNext();
}
return (OMNode)internalGetNextSibling();
}
public final OMNode getNextOMSiblingIfAvailable() {
return (OMNode)internalGetNextSibling();
}
public final Node getNextSibling() {
return (Node) this.getNextOMSibling();
}
public final OMNode getPreviousOMSibling() {
return (OMNode)internalGetPreviousSibling();
}
public final Node getPreviousSibling() {
return internalGetPreviousSibling();
}
// /
// /OMNode methods
// /
public final void setNextOMSibling(OMNode node) {
if (node == null) {
internalSetNextSibling(null);
return;
}
if (node instanceof NodeImpl) {
internalSetNextSibling((NodeImpl)node);
} else {
throw new OMException("The node is not a " + NodeImpl.class);
}
}
public final void setPreviousOMSibling(OMNode node) {
if (node == null) {
internalSetPreviousSibling(null);
return;
}
if (node instanceof NodeImpl) {
internalSetPreviousSibling((NodeImpl)node);
} else {
throw new OMException("The node is not a " + NodeImpl.class);
}
}
public final OMContainer getParent() throws OMException {
return (OMContainer)parentNode();
}
public Node getParentNode() {
return parentNode();
}
public final void setParent(OMContainer element) {
setParent((ParentNode)element, false);
}
protected void setParent(ParentNode parent, boolean useDomSemantics) {
if (parent == null) {
internalSetOwnerNode(useDomSemantics ? ownerDocument() : null);
hasParent(false);
} else {
internalSetOwnerNode(parent);
hasParent(true);
}
}
public OMNode detach() throws OMException {
return detach(false);
}
OMNode detach(boolean useDomSemantics) {
ParentNode parentNode = parentNode();
if (parentNode == null) {
throw new OMException("Parent level elements cannot be detached");
} else {
if (!isComplete()) {
build();
}
getNextOMSibling(); // Make sure that nextSibling is set correctly
NodeImpl previousSibling = internalGetPreviousSibling();
NodeImpl nextSibling = internalGetNextSibling();
if (previousSibling == null) { // This is the first child
if (nextSibling != null) {
parentNode.setFirstChild((OMNode)nextSibling);
} else {
parentNode.firstChild = null;
parentNode.lastChild = null;
}
} else {
previousSibling.setNextOMSibling((OMNode)nextSibling);
if (nextSibling == null) {
previousSibling.parentNode().setComplete(true);
}
}
if (nextSibling != null) {
nextSibling.setPreviousOMSibling((OMNode)previousSibling);
internalSetNextSibling(null);
}
if (parentNode != null && parentNode.lastChild == this) {
parentNode.lastChild = previousSibling;
}
setParent(null, useDomSemantics);
internalSetPreviousSibling(null);
}
return (OMNode)this;
}
public void discard() throws OMException {
throw new UnsupportedOperationException("Cannot discard this node");
}
/** Inserts the given sibling next to this item. */
public void insertSiblingAfter(OMNode sibling) throws OMException {
ParentNode parentNode = parentNode();
if (parentNode == null) {
throw new OMException("Parent can not be null");
} else if (this == sibling) {
throw new OMException("Inserting self as the sibling is not allowed");
}
((OMNodeEx) sibling).setParent((OMContainer)parentNode);
if (sibling instanceof NodeImpl) {
NodeImpl domSibling = (NodeImpl) sibling;
domSibling.internalSetPreviousSibling(this);
NodeImpl nextSibling = internalGetNextSibling();
if (nextSibling == null) {
parentNode.setLastChild(sibling);
} else {
nextSibling.internalSetPreviousSibling(domSibling);
}
domSibling.internalSetNextSibling(nextSibling);
internalSetNextSibling(domSibling);
} else {
throw new OMException("The given child is not of type "
+ NodeImpl.class);
}
}
/** Inserts the given sibling before this item. */
public void insertSiblingBefore(OMNode sibling) throws OMException {
ParentNode parentNode = parentNode();
// ((OMNodeEx)sibling).setParent(this.parentNode);
if (parentNode == null) {
throw new OMException("Parent can not be null");
} else if (this == sibling) {
throw new OMException("Inserting self as the sibling is not allowed");
}
if (sibling instanceof NodeImpl) {
// ChildNode domSibling = (ChildNode)sibling;
// domSibling.nextSibling = this;
// if(this.previousSibling != null) {
// this.previousSibling.nextSibling = domSibling;
// }
// domSibling.previousSibling = this.previousSibling;
// this.previousSibling = domSibling;
NodeImpl siblingImpl = (NodeImpl) sibling;
siblingImpl.internalSetNextSibling(this);
NodeImpl previousSibling = internalGetPreviousSibling();
if (previousSibling == null) {
parentNode.setFirstChild((OMNode)siblingImpl);
siblingImpl.internalSetPreviousSibling(null);
} else {
siblingImpl.setParent(parentNode, false);
previousSibling.setNextOMSibling((OMNode)siblingImpl);
siblingImpl.setPreviousOMSibling((OMNode)previousSibling);
}
internalSetPreviousSibling(siblingImpl);
} else {
throw new OMException("The given child is not of type "
+ NodeImpl.class);
}
}
public abstract OMXMLParserWrapper getBuilder();
public abstract void setComplete(boolean state);
public abstract boolean isComplete();
/** Builds next element. */
public void build() {
while (!isComplete()) {
getBuilder().next();
}
}
/**
* Parses this node and builds the object structure in memory. AXIOM supports two levels of
* deffered building. First is deffered building of AXIOM using StAX. Second level is the deffered
* building of attachments. AXIOM reads in the attachements from the stream only when user asks by
* calling getDataHandler(). build() method builds the OM without the attachments. buildAll()
* builds the OM together with attachement data. This becomes handy when user wants to free the
* input stream.
*/
public void buildWithAttachments() {
if (!this.isComplete()) {
this.build();
}
}
public void close(boolean build) {
OMXMLParserWrapper builder = getBuilder();
if (build) {
this.build();
}
setComplete(true);
// If this is a StAXBuilder, close it.
if (builder instanceof StAXBuilder &&
!((StAXBuilder) builder).isClosed()) {
((StAXBuilder) builder).releaseParserOnClose(true);
((StAXBuilder) builder).close();
}
}
public void serialize(XMLStreamWriter xmlWriter) throws XMLStreamException {
serialize(xmlWriter, true);
}
public void serializeAndConsume(XMLStreamWriter xmlWriter) throws XMLStreamException {
serialize(xmlWriter, false);
}
public void serialize(XMLStreamWriter xmlWriter, boolean cache) throws XMLStreamException {
MTOMXMLStreamWriter writer = xmlWriter instanceof MTOMXMLStreamWriter ?
(MTOMXMLStreamWriter) xmlWriter :
new MTOMXMLStreamWriter(xmlWriter);
internalSerialize(writer, cache);
writer.flush();
}
public void serialize(OutputStream output) throws XMLStreamException {
XMLStreamWriter xmlStreamWriter = StAXUtils.createXMLStreamWriter(output);
try {
serialize(xmlStreamWriter);
} finally {
xmlStreamWriter.close();
}
}
public void serialize(Writer writer) throws XMLStreamException {
XMLStreamWriter xmlStreamWriter = StAXUtils.createXMLStreamWriter(writer);
try {
serialize(xmlStreamWriter);
} finally {
xmlStreamWriter.close();
}
}
public void serializeAndConsume(OutputStream output)
throws XMLStreamException {
XMLStreamWriter xmlStreamWriter = StAXUtils.createXMLStreamWriter(output);
try {
serializeAndConsume(xmlStreamWriter);
} finally {
xmlStreamWriter.close();
}
}
public void serializeAndConsume(Writer writer) throws XMLStreamException {
XMLStreamWriter xmlStreamWriter = StAXUtils.createXMLStreamWriter(writer);
try {
serializeAndConsume(xmlStreamWriter);
} finally {
xmlStreamWriter.close();
}
}
public void serialize(OutputStream output, OMOutputFormat format)
throws XMLStreamException {
MTOMXMLStreamWriter writer = new MTOMXMLStreamWriter(output, format, true);
try {
internalSerialize(writer, true);
// TODO: the flush is necessary because of an issue with the lifecycle of MTOMXMLStreamWriter
writer.flush();
} finally {
writer.close();
}
}
public void serialize(Writer writer2, OMOutputFormat format)
throws XMLStreamException {
MTOMXMLStreamWriter writer = new MTOMXMLStreamWriter(StAXUtils
.createXMLStreamWriter(writer2));
writer.setOutputFormat(format);
try {
internalSerialize(writer, true);
// TODO: the flush is necessary because of an issue with the lifecycle of MTOMXMLStreamWriter
writer.flush();
} finally {
writer.close();
}
}
public void serializeAndConsume(OutputStream output, OMOutputFormat format)
throws XMLStreamException {
MTOMXMLStreamWriter writer = new MTOMXMLStreamWriter(output, format, false);
try {
internalSerialize(writer, false);
// TODO: the flush is necessary because of an issue with the lifecycle of MTOMXMLStreamWriter
writer.flush();
} finally {
writer.close();
}
}
public void serializeAndConsume(Writer writer2, OMOutputFormat format)
throws XMLStreamException {
MTOMXMLStreamWriter writer = new MTOMXMLStreamWriter(StAXUtils
.createXMLStreamWriter(writer2));
try {
writer.setOutputFormat(format);
// TODO: the flush is necessary because of an issue with the lifecycle of MTOMXMLStreamWriter
internalSerialize(writer, false);
writer.flush();
} finally {
writer.close();
}
}
public void internalSerialize(XMLStreamWriter writer) throws XMLStreamException {
internalSerialize(writer, true);
}
public void internalSerializeAndConsume(XMLStreamWriter writer) throws XMLStreamException {
internalSerialize(writer, false);
}
// This method is actually defined by OMNodeEx, but OMNodeEx is only implemented
// by certain subclasses (for the reason, see AXIOM-385).
public abstract void internalSerialize(XMLStreamWriter writer, boolean cache) throws XMLStreamException;
abstract NodeImpl clone(OMCloneOptions options, ParentNode targetParent, boolean deep);
}