org.apache.axis2.saaj.SOAPPartImpl Maven / Gradle / Ivy
/*
* 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.axis2.saaj;
import org.apache.axiom.attachments.Attachments;
import org.apache.axiom.mime.ContentType;
import org.apache.axiom.mime.MediaType;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMMetaFactory;
import org.apache.axiom.om.OMXMLBuilderFactory;
import org.apache.axiom.soap.SOAPFactory;
import org.apache.axiom.soap.SOAPModelBuilder;
import org.apache.axis2.saaj.util.IDGenerator;
import org.apache.axis2.saaj.util.SAAJUtil;
import org.apache.axis2.transport.http.HTTPConstants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Attr;
import org.w3c.dom.CDATASection;
import org.w3c.dom.Comment;
import org.w3c.dom.DOMConfiguration;
import org.w3c.dom.DOMException;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.EntityReference;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.ProcessingInstruction;
import org.w3c.dom.Text;
import org.w3c.dom.UserDataHandler;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.text.ParseException;
import java.util.Iterator;
public class SOAPPartImpl extends SOAPPart {
private static final Log log = LogFactory.getLog(SOAPPartImpl.class);
private Document document;
private SOAPMessage soapMessage;
private SOAPEnvelopeImpl envelope;
private final MimeHeaders mimeHeaders;
public SOAPPartImpl(SOAPMessageImpl parentSoapMsg,
SOAPEnvelopeImpl soapEnvelope) {
//setMimeHeader(HTTPConstants.HEADER_CONTENT_ID, IDGenerator.generateID());
//setMimeHeader(HTTPConstants.HEADER_CONTENT_TYPE, "text/xml");
this.mimeHeaders = SAAJUtil.copyMimeHeaders(parentSoapMsg.getMimeHeaders());
soapMessage = parentSoapMsg;
envelope = soapEnvelope;
document = soapEnvelope.getOwnerDocument();
envelope.setSOAPPartParent(this);
}
/**
* Construct a SOAP part from the given input stream.
* The content type (as provided by the MIME headers) must be SOAP 1.1, SOAP 1.2
* or XOP (MTOM). MIME packages (multipart/related) are not supported and should be
* parsed using {@link SOAPMessageImpl#SOAPMessageImpl(InputStream, MimeHeaders).
*
* If the content type is XOP, xop:Include elements will only be replaced if
* the attachments
parameter is not null.
*
* @see MessageFactoryImpl#setProcessMTOM(boolean)
*
* @param parentSoapMsg the parent SOAP message
* @param inputStream the input stream with the content of the SOAP part
* @param mimeHeaders the MIME headers
* @param attachments the set of attachments to be used to substitute xop:Include elements
* @throws SOAPException
*/
public SOAPPartImpl(SOAPMessageImpl parentSoapMsg, InputStream inputStream,
MimeHeaders mimeHeaders, Attachments attachments) throws SOAPException {
ContentType contentType = null;
if (mimeHeaders == null) {
//TODO : read string from constants
this.mimeHeaders = new MimeHeaders();
this.mimeHeaders.addHeader("Content-ID", IDGenerator.generateID());
this.mimeHeaders.addHeader("content-type", HTTPConstants.MEDIA_TYPE_APPLICATION_SOAP_XML);
} else {
String contentTypes[] = mimeHeaders.getHeader(HTTPConstants.HEADER_CONTENT_TYPE);
if (contentTypes != null && contentTypes.length > 0) {
try {
contentType = new ContentType(contentTypes[0]);
} catch (ParseException ex) {
throw new SOAPException("Invalid content type '" + contentTypes[0] + "'");
}
}
this.mimeHeaders = SAAJUtil.copyMimeHeaders(mimeHeaders);
}
soapMessage = parentSoapMsg;
String charset;
boolean isMTOM;
OMMetaFactory metaFactory = OMAbstractFactory.getMetaFactory(OMAbstractFactory.FEATURE_DOM);
SOAPFactory soapFactory;
if (contentType == null) {
charset = null;
isMTOM = false;
soapFactory = null;
} else {
MediaType baseType = contentType.getMediaType();
MediaType soapContentType;
if (baseType.equals(MediaType.APPLICATION_XOP_XML)) {
isMTOM = true;
String typeParam = contentType.getParameter("type");
if (typeParam == null) {
throw new SOAPException("Missing 'type' parameter in XOP content type");
} else {
try {
soapContentType = new ContentType(typeParam).getMediaType();
} catch (ParseException ex) {
throw new SOAPException("Failed to parse the 'type' parameter", ex);
}
}
} else {
isMTOM = false;
soapContentType = baseType;
}
if (soapContentType.equals(MediaType.TEXT_XML)) {
soapFactory = metaFactory.getSOAP11Factory();
} else if (soapContentType.equals(MediaType.APPLICATION_SOAP_XML)) {
soapFactory = metaFactory.getSOAP12Factory();
} else {
throw new SOAPException("Unrecognized content type '" + soapContentType + "'");
}
charset = contentType.getParameter("charset");
}
SOAPModelBuilder builder;
if (isMTOM && attachments != null) {
builder = OMXMLBuilderFactory.createSOAPModelBuilder(metaFactory, attachments);
} else {
builder = OMXMLBuilderFactory.createSOAPModelBuilder(metaFactory, inputStream, charset);
}
try {
org.apache.axiom.soap.SOAPEnvelope soapEnvelope = builder.getSOAPEnvelope();
if (soapFactory != null && soapEnvelope.getOMFactory() != soapFactory) {
throw new SOAPException("SOAP version of message doesn't match Content-Type");
}
envelope = new SOAPEnvelopeImpl(soapEnvelope);
envelope.omTarget.build();
this.document = envelope.getOwnerDocument();
envelope.setSOAPPartParent(this);
} catch (Exception e) {
throw new SOAPException(e);
}
}
/**
* Obtain the SOAPMessage
*
* @return the related SOAPMessage
*/
public SOAPMessage getSoapMessage() {
return soapMessage;
}
/**
* Gets the SOAPEnvelope
object associated with this SOAPPart
object.
* Once the SOAP envelope is obtained, it can be used to get its contents.
*
* @return the SOAPEnvelope
object for this SOAPPart
object
* @throws SOAPException if there is a SOAP error
*/
public SOAPEnvelope getEnvelope() throws SOAPException {
return envelope;
}
/**
* Removes all MIME headers that match the given name.
*
* @param header a String
giving the name of the MIME header(s) to be removed
*/
public void removeMimeHeader(String header) {
mimeHeaders.removeHeader(header);
}
/** Removes all the MimeHeader
objects for this SOAPEnvelope
object. */
public void removeAllMimeHeaders() {
mimeHeaders.removeAllHeaders();
}
/**
* Gets all the values of the MimeHeader
object in this SOAPPart
* object that is identified by the given String
.
*
* @param name the name of the header; example: "Content-Type"
* @return a String
array giving all the values for the specified header
* @see #setMimeHeader(String, String) setMimeHeader(java.lang.String,
* java.lang.String)
*/
public String[] getMimeHeader(String name) {
return mimeHeaders.getHeader(name);
}
/**
* Changes the first header entry that matches the given header name so that its value is the
* given value, adding a new header with the given name and value if no existing header is a
* match. If there is a match, this method clears all existing values for the first header that
* matches and sets the given value instead. If more than one header has the given name, this
* method removes all of the matching headers after the first one.
*
* Note that RFC822 headers can contain only US-ASCII characters.
*
* @param name a String
giving the header name for which to search
* @param value a String
giving the value to be set. This value will be substituted
* for the current value(s) of the first header that is a match if there is one. If
* there is no match, this value will be the value for a new
* MimeHeader
object.
* @throws IllegalArgumentException
* if there was a problem with the specified mime header name or value
* @throws IllegalArgumentException
* if there was a problem with the specified mime header name or value
* @see #getMimeHeader(String) getMimeHeader(java.lang.String)
*/
public void setMimeHeader(String name, String value) {
mimeHeaders.setHeader(name, value);
}
/**
* Creates a MimeHeader
object with the specified name and value and adds it to
* this SOAPPart
object. If a MimeHeader
with the specified name
* already exists, this method adds the specified value to the already existing value(s).
*
* Note that RFC822 headers can contain only US-ASCII characters.
*
* @param header a String
giving the header name
* @param value a String
giving the value to be set or added
* @throws IllegalArgumentException if there was a problem with the specified mime header name
* or value
*/
public void addMimeHeader(String header, String value) {
mimeHeaders.addHeader(header, value);
}
/**
* Retrieves all the headers for this SOAPPart
object as an iterator over the
* MimeHeader
objects.
*
* @return an Iterator
object with all of the Mime headers for this
* SOAPPart
object
*/
public Iterator getAllMimeHeaders() {
return mimeHeaders.getAllHeaders();
}
/**
* Retrieves all MimeHeader
objects that match a name in the given array.
*
* @param names a String
array with the name(s) of the MIME headers to be returned
* @return all of the MIME headers that match one of the names in the given array, returned as
* an Iterator
object
*/
public Iterator getMatchingMimeHeaders(String[] names) {
return mimeHeaders.getMatchingHeaders(names);
}
/**
* Retrieves all MimeHeader
objects whose name does not match a name in the given
* array.
*
* @param names a String
array with the name(s) of the MIME headers not to be
* returned
* @return all of the MIME headers in this SOAPPart
object except those that match
* one of the names in the given array. The nonmatching MIME headers are returned as an
* Iterator
object.
*/
public Iterator getNonMatchingMimeHeaders(String[] names) {
return mimeHeaders.getNonMatchingHeaders(names);
}
public void setContent(Source source) throws SOAPException {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
XMLStreamReader reader;
if (source instanceof StreamSource) {
reader = inputFactory.createXMLStreamReader(source);
} else {
Result result = new StreamResult(baos);
Transformer xformer = TransformerFactory.newInstance().newTransformer();
xformer.transform(source, result);
InputStream is = new ByteArrayInputStream(baos.toByteArray());
reader = inputFactory.createXMLStreamReader(is);
}
SOAPModelBuilder builder1 = OMXMLBuilderFactory.createStAXSOAPModelBuilder(
envelope.omTarget.getOMFactory().getMetaFactory(), reader);
envelope = new SOAPEnvelopeImpl(builder1.getSOAPEnvelope());
envelope.omTarget.build();
this.document = envelope.getOwnerDocument();
envelope.setSOAPPartParent(this);
} catch (TransformerFactoryConfigurationError e) {
log.error(e);
throw new SOAPException(e);
} catch (Exception e) {
log.error(e);
throw new SOAPException(e);
}
}
/**
* Returns the content of the SOAPEnvelope as a JAXP Source
object.
*
* @return the content as a javax.xml.transform.Source
object
* @throws SOAPException if the implementation cannot convert the specified Source
* object
* @see #setContent(javax.xml.transform.Source) setContent(javax.xml.transform.Source)
*/
public Source getContent() throws SOAPException {
return new DOMSource(this.document);
}
/**
* The Document Type Declaration (see DocumentType
) associated with this document.
* For HTML documents as well as XML documents without a document type declaration this returns
* null
. The DOM Level 2 does not support editing the Document Type Declaration.
* docType
cannot be altered in any way, including through the use of methods
* inherited from the Node
interface, such as insertNode
or
* removeNode
.
*/
public DocumentType getDoctype() {
return document.getDoctype();
}
/**
* The DOMImplementation
object that handles this document. A DOM application may
* use objects from multiple implementations.
*/
public DOMImplementation getImplementation() {
return document.getImplementation();
}
/**
* This is a convenience attribute that allows direct access to the child node that is the root
* element of the document. For HTML documents, this is the element with the tagName "HTML".
*/
public Element getDocumentElement() {
return document.getDocumentElement();
}
/**
* Creates an element of the type specified. Note that the instance returned implements the
* Element
interface, so attributes can be specified directly on the returned
* object.
In addition, if there are known attributes with default values, Attr
* nodes representing them are automatically created and attached to the element.
To create
* an element with a qualified name and namespace URI, use the createElementNS
* method.
*
* @param tagName The name of the element type to instantiate. For XML, this is case-sensitive.
* For HTML, the tagName
parameter may be provided in any case, but
* it must be mapped to the canonical uppercase form by the DOM implementation.
* @return A new Element
object with the nodeName
attribute set to
* tagName
, and localName
, prefix
, and
* namespaceURI
set to null
.
* @throws DOMException INVALID_CHARACTER_ERR: Raised if the specified name contains an illegal
* character.
*/
public Element createElement(String tagName) throws DOMException {
return document.createElement(tagName);
}
/**
* Creates an empty DocumentFragment
object.
*
* @return A new DocumentFragment
.
*/
public DocumentFragment createDocumentFragment() {
return document.createDocumentFragment();
}
/**
* Creates a Text
node given the specified string.
*
* @param data The data for the node.
* @return The new Text
object.
*/
public Text createTextNode(String data) {
return document.createTextNode(data);
}
/**
* Creates a CDATASection
node whose value is the specified string.
*
* @param data The data for the CDATASection
contents.
* @return The new CDATASection
object.
* @throws DOMException NOT_SUPPORTED_ERR: Raised if this document is an HTML document.
*/
public Comment createComment(String data) {
return document.createComment(data);
}
/**
* Creates a CDATASection
node whose value is the specified string.
*
* @param data The data for the CDATASection
contents.
* @return The new CDATASection
object.
* @throws DOMException NOT_SUPPORTED_ERR: Raised if this document is an HTML document.
*/
public CDATASection createCDATASection(String data) throws DOMException {
return document.createCDATASection(data);
}
/**
* Creates a ProcessingInstruction
node given the specified name and data strings.
*
* @param target The target part of the processing instruction.
* @param data The data for the node.
* @return The new ProcessingInstruction
object.
* @throws DOMException INVALID_CHARACTER_ERR: Raised if the specified target contains an
* illegal character.
NOT_SUPPORTED_ERR: Raised if this document is an
* HTML document.
*/
public ProcessingInstruction createProcessingInstruction(String target, String data)
throws DOMException {
return document.createProcessingInstruction(target, data);
}
/**
* Creates an Attr
of the given name. Note that the Attr
instance can
* then be set on an Element
using the setAttributeNode
method.
To
* create an attribute with a qualified name and namespace URI, use the
* createAttributeNS
method.
*
* @param name The name of the attribute.
* @return A new Attr
object with the nodeName
attribute set to
* name
, and localName
, prefix
, and
* namespaceURI
set to null
. The value of the attribute is the
* empty string.
* @throws DOMException INVALID_CHARACTER_ERR: Raised if the specified name contains an illegal
* character.
*/
public Attr createAttribute(String name) throws DOMException {
return document.createAttribute(name);
}
/**
* Creates an EntityReference
object. In addition, if the referenced entity is
* known, the child list of the EntityReference
node is made the same as that of
* the corresponding Entity
node.If any descendant of the Entity
node
* has an unbound namespace prefix, the corresponding descendant of the created
* EntityReference
node is also unbound; (its namespaceURI
is
* null
). The DOM Level 2 does not support any mechanism to resolve namespace
* prefixes.
*
* @param name The name of the entity to reference.
* @return The new EntityReference
object.
* @throws DOMException INVALID_CHARACTER_ERR: Raised if the specified name contains an illegal
* character.
NOT_SUPPORTED_ERR: Raised if this document is an HTML
* document.
*/
public EntityReference createEntityReference(String name) throws DOMException {
return document.createEntityReference(name);
}
/**
* Returns a NodeList
of all the Elements
with a given tag name in the
* order in which they are encountered in a preorder traversal of the Document
* tree.
*
* @param tagname The name of the tag to match on. The special value "*" matches all tags.
* @return A new NodeList
object containing all the matched Elements
.
*/
public NodeList getElementsByTagName(String tagname) {
return document.getElementsByTagName(tagname);
}
/**
* Imports a node from another document to this document. The returned node has no parent;
* (parentNode
is null
). The source node is not altered or removed
* from the original document; this method creates a new copy of the source node.
For all
* nodes, importing a node creates a node object owned by the importing document, with attribute
* values identical to the source node's nodeName
and nodeType
, plus
* the attributes related to namespaces (prefix
, localName
, and
* namespaceURI
). As in the cloneNode
operation on a
* Node
, the source node is not altered.
Additional information is copied as
* appropriate to the nodeType
, attempting to mirror the behavior expected if a
* fragment of XML or HTML source was copied from one document to another, recognizing that the
* two documents may have different DTDs in the XML case. The following list describes the
* specifics for each type of node. - ATTRIBUTE_NODE
- The
*
ownerElement
attribute is set to null
and the
* specified
flag is set to true
on the generated Attr
.
* The descendants of the source Attr
are recursively imported and the resulting
* nodes reassembled to form the corresponding subtree. Note that the deep
* parameter has no effect on Attr
nodes; they always carry their children with
* them when imported. - DOCUMENT_FRAGMENT_NODE
- If the
deep
option
* was set to true
, the descendants of the source element are recursively imported
* and the resulting nodes reassembled to form the corresponding subtree. Otherwise, this simply
* generates an empty DocumentFragment
. - DOCUMENT_NODE
* Document
nodes cannot be imported. - DOCUMENT_TYPE_NODE
* DocumentType
nodes cannot be imported. - ELEMENT_NODE
* - Specified attribute nodes of the source element are imported, and the generated
*
Attr
nodes are attached to the generated Element
. Default
* attributes are not copied, though if the document being imported into defines default
* attributes for this element name, those are assigned. If the importNode
* deep
parameter was set to true
, the descendants of the source
* element are recursively imported and the resulting nodes reassembled to form the
* corresponding subtree. - ENTITY_NODE
Entity
nodes can be
* imported, however in the current release of the DOM the DocumentType
is
* readonly. Ability to add these imported nodes to a DocumentType
will be
* considered for addition to a future release of the DOM.On import, the publicId
,
* systemId
, and notationName
attributes are copied. If a
* deep
import is requested, the descendants of the the source Entity
* are recursively imported and the resulting nodes reassembled to form the corresponding
* subtree. - ENTITY_REFERENCE_NODE
- Only the
EntityReference
* itself is copied, even if a deep
import is requested, since the source and
* destination documents might have defined the entity differently. If the document being
* imported into provides a definition for this entity name, its value is assigned.
* - NOTATION_NODE
-
Notation
nodes can be imported, however in the
* current release of the DOM the DocumentType
is readonly. Ability to add these
* imported nodes to a DocumentType
will be considered for addition to a future
* release of the DOM.On import, the publicId
and systemId
attributes
* are copied. Note that the deep
parameter has no effect on Notation
* nodes since they never have any children. - PROCESSING_INSTRUCTION_NODE
- The
* imported node copies its
target
and data
values from those of the
* source node. - TEXT_NODE, CDATA_SECTION_NODE, COMMENT_NODE
- These three types
* of nodes inheriting from
CharacterData
copy their data
and
* length
attributes from those of the source node.
*
* @param importedNode The node to import.
* @param deep If true
, recursively import the subtree under the specified
* node; if false
, import only the node itself, as explained
* above. This has no effect on Attr
, EntityReference
,
* and Notation
nodes.
* @return The imported node that belongs to this Document
.
* @throws DOMException NOT_SUPPORTED_ERR: Raised if the type of node being imported is not
* supported.
* @since DOM Level 2
*/
public Node importNode(Node importedNode, boolean deep) throws DOMException {
return document.importNode(importedNode, deep);
}
/**
* Creates an element of the given qualified name and namespace URI.
*
* @param namespaceURI The namespace URI of the element to create.
* @param qualifiedName The qualified name of the element type to instantiate.
* @return A new Element
object with the following attributes:
* Attribute Value Node.nodeName
* qualifiedName
Node.namespaceURI
* namespaceURI
Node.prefix
* prefix, extracted from qualifiedName
, or
* null
if there is no prefix Node.localName
local name, extracted
* from qualifiedName
Element.tagName
* qualifiedName
* @throws DOMException INVALID_CHARACTER_ERR: Raised if the specified qualified name contains
* an illegal character, per the XML 1.0 specification .
NAMESPACE_ERR:
* Raised if the qualifiedName
is malformed per the Namespaces
* in XML specification, if the qualifiedName
has a prefix and
* the namespaceURI
is null
, or if the
* qualifiedName
has a prefix that is "xml" and the
* namespaceURI
is different from " http://www.w3.org/XML/1998/namespace"
* .
NOT_SUPPORTED_ERR: Always thrown if the current document does not
* support the "XML"
feature, since namespaces were defined by
* XML.
* @since DOM Level 2
*/
public Element createElementNS(String namespaceURI, String qualifiedName) throws DOMException {
return document.createElementNS(namespaceURI, qualifiedName);
}
/**
* Creates an attribute of the given qualified name and namespace URI.
*
* @param namespaceURI The namespace URI of the attribute to create.
* @param qualifiedName The qualified name of the attribute to instantiate.
* @return A new Attr
object with the following attributes:
* Attribute Value Node.nodeName
* qualifiedName
* Node.namespaceURI
namespaceURI
* Node.prefix
prefix,
* extracted from qualifiedName
, or null
if there is no
* prefix Node.localName
local name, extracted from qualifiedName
* Attr.name
* qualifiedName
Node.nodeValue
* the empty string
* @throws DOMException INVALID_CHARACTER_ERR: Raised if the specified qualified name contains
* an illegal character, per the XML 1.0 specification .
NAMESPACE_ERR:
* Raised if the qualifiedName
is malformed per the Namespaces
* in XML specification, if the qualifiedName
has a prefix and
* the namespaceURI
is null
, if the
* qualifiedName
has a prefix that is "xml" and the
* namespaceURI
is different from " http://www.w3.org/XML/1998/namespace",
* or if the qualifiedName
, or its prefix, is "xmlns" and the
* namespaceURI
is different from " http://www.w3.org/2000/xmlns/".
*
NOT_SUPPORTED_ERR: Always thrown if the current document does not
* support the "XML"
feature, since namespaces were defined by
* XML.
* @since DOM Level 2
*/
public Attr createAttributeNS(String namespaceURI, String qualifiedName) throws DOMException {
return document.createAttributeNS(namespaceURI, qualifiedName);
}
/**
* Returns a NodeList
of all the Elements
with a given local name and
* namespace URI in the order in which they are encountered in a preorder traversal of the
* Document
tree.
*
* @param namespaceURI The namespace URI of the elements to match on. The special value "*"
* matches all namespaces.
* @param localName The local name of the elements to match on. The special value "*" matches
* all local names.
* @return A new NodeList
object containing all the matched Elements
.
* @since DOM Level 2
*/
public NodeList getElementsByTagNameNS(String namespaceURI, String localName) {
return document.getElementsByTagNameNS(namespaceURI, localName);
}
/**
* Returns the Element
whose ID
is given by elementId
. If
* no such element exists, returns null
. Behavior is not defined if more than one
* element has this ID
. The DOM implementation must have information that says
* which attributes are of type ID. Attributes with the name "ID" are not of type ID unless so
* defined. Implementations that do not know whether attributes are of type ID or not are
* expected to return null
.
*
* @param elementId The unique id
value for an element.
* @return The matching element.
* @since DOM Level 2
*/
public Element getElementById(String elementId) {
return document.getElementById(elementId);
}
public String getInputEncoding() {
//return ((DeferredDocumentImpl)(((DOMSource)this.source).getNode())).getInputEncoding();
return this.envelope.getEncodingStyle();
}
public String getXmlEncoding() {
return document.getXmlEncoding();
}
public boolean getXmlStandalone() {
return document.getXmlStandalone();
}
public void setXmlStandalone(boolean xmlStandalone) throws DOMException {
document.setXmlStandalone(xmlStandalone);
}
public String getXmlVersion() {
return document.getXmlVersion();
}
public void setXmlVersion(String xmlVersion) throws DOMException {
document.setXmlVersion(xmlVersion);
}
public boolean getStrictErrorChecking() {
return document.getStrictErrorChecking();
}
public void setStrictErrorChecking(boolean strictErrorChecking) {
document.setStrictErrorChecking(strictErrorChecking);
}
public String getDocumentURI() {
return document.getDocumentURI();
}
public void setDocumentURI(String documentURI) {
document.setDocumentURI(documentURI);
}
public Node adoptNode(Node source) throws DOMException {
return document.adoptNode(source);
}
public DOMConfiguration getDomConfig() {
return document.getDomConfig();
}
public void normalizeDocument() {
document.normalizeDocument();
}
public Node renameNode(Node n, String namespaceURI, String qualifiedName) throws DOMException {
return document.renameNode(n, namespaceURI, qualifiedName);
}
/** The name of this node, depending on its type; see the table above. */
public String getNodeName() {
return document.getNodeName();
}
/**
* The value of this node, depending on its type; see the table above. When it is defined to be
* null
, setting it has no effect.
*
* @throws DOMException NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
* @throws DOMException DOMSTRING_SIZE_ERR: Raised when it would return more characters than fit
* in a DOMString
variable on the implementation platform.
*/
public String getNodeValue() throws DOMException {
return document.getNodeValue();
}
/**
* The value of this node, depending on its type; see the table above. When it is defined to be
* null
, setting it has no effect.
*
* @throws DOMException NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly.
* @throws DOMException DOMSTRING_SIZE_ERR: Raised when it would return more characters than fit
* in a DOMString
variable on the implementation platform.
*/
public void setNodeValue(String arg0) throws DOMException {
document.setNodeValue(arg0);
}
/** A code representing the type of the underlying object, as defined above. */
public short getNodeType() {
return document.getNodeType();
}
/**
* The parent of this node. All nodes, except Attr
, Document
,
* DocumentFragment
, Entity
, and Notation
may have a
* parent. However, if a node has just been created and not yet added to the tree, or if it has
* been removed from the tree, this is null
.
*/
public Node getParentNode() {
return toSAAJNode(document.getParentNode());
}
/**
* A NodeList
that contains all children of this node. If there are no children,
* this is a NodeList
containing no nodes.
*/
public NodeList getChildNodes() {
NodeList childNodes = document.getChildNodes();
NodeListImpl nodes = new NodeListImpl();
for (int i = 0; i < childNodes.getLength(); i++) {
nodes.addNode(toSAAJNode(childNodes.item(i)));
}
return nodes;
}
/** The first child of this node. If there is no such node, this returns null
. */
public Node getFirstChild() {
return toSAAJNode(document.getFirstChild());
}
/** The last child of this node. If there is no such node, this returns null
. */
public Node getLastChild() {
return toSAAJNode(document.getLastChild());
}
/**
* The node immediately preceding this node. If there is no such node, this returns
* null
.
*/
public Node getPreviousSibling() {
return toSAAJNode(document.getPreviousSibling());
}
/**
* The node immediately following this node. If there is no such node, this returns
* null
.
*/
public Node getNextSibling() {
return toSAAJNode(document.getNextSibling());
}
/**
* A NamedNodeMap
containing the attributes of this node (if it is an
* Element
) or null
otherwise.
*/
public NamedNodeMap getAttributes() {
return document.getAttributes();
}
/**
* The Document
object associated with this node. This is also the
* Document
object used to create new nodes. When this node is a
* Document
or a DocumentType
which is not used with any
* Document
yet, this is null
.
*/
public Document getOwnerDocument() {
return document.getOwnerDocument();
}
/**
* Inserts the node newChild
before the existing child node refChild
.
* If refChild
is null
, insert newChild
at the end of the
* list of children.
If newChild
is a DocumentFragment
object, all
* of its children are inserted, in the same order, before refChild
. If the
* newChild
is already in the tree, it is first removed.
*
* @param newChild The node to insert.
* @param refChild The reference node, i.e., the node before which the new node must be
* inserted.
* @return The node being inserted.
* @throws DOMException HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does not
* allow children of the type of the newChild
node, or if the
* node to insert is one of this node's ancestors or this node itself.
*
WRONG_DOCUMENT_ERR: Raised if newChild
was created from
* a different document than the one that created this node.
*
NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly or if
* the parent of the node being inserted is readonly.
NOT_FOUND_ERR:
* Raised if refChild
is not a child of this node.
*/
public Node insertBefore(Node newChild, Node refChild) throws DOMException {
return document.insertBefore(newChild, refChild);
}
/**
* Replaces the child node oldChild
with newChild
in the list of
* children, and returns the oldChild
node.
If newChild
is a
* DocumentFragment
object, oldChild
is replaced by all of the
* DocumentFragment
children, which are inserted in the same order. If the
* newChild
is already in the tree, it is first removed.
*
* @param newChild The new node to put in the child list.
* @param oldChild The node being replaced in the list.
* @return The node replaced.
* @throws DOMException HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does not
* allow children of the type of the newChild
node, or if the
* node to put in is one of this node's ancestors or this node itself.
*
WRONG_DOCUMENT_ERR: Raised if newChild
was created from
* a different document than the one that created this node.
*
NO_MODIFICATION_ALLOWED_ERR: Raised if this node or the parent of
* the new node is readonly.
NOT_FOUND_ERR: Raised if
* oldChild
is not a child of this node.
*/
public Node replaceChild(Node newChild, Node oldChild) throws DOMException {
return document.replaceChild(newChild, oldChild);
}
/**
* Removes the child node indicated by oldChild
from the list of children, and
* returns it.
*
* @param oldChild The node being removed.
* @return The node removed.
* @throws DOMException NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
*
NOT_FOUND_ERR: Raised if oldChild
is not a child of
* this node.
*/
public Node removeChild(Node oldChild) throws DOMException {
if (oldChild instanceof SOAPElementImpl) {
oldChild = ((SOAPElementImpl)oldChild).getTarget();
} else if (oldChild instanceof TextImplEx) {
// TODO: handle text nodes somehow
}
return document.removeChild(oldChild);
}
/**
* Adds the node newChild
to the end of the list of children of this node. If the
* newChild
is already in the tree, it is first removed.
*
* @param newChild The node to add.If it is a DocumentFragment
object, the entire
* contents of the document fragment are moved into the child list of this node
* @return The node added.
* @throws DOMException HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does not
* allow children of the type of the newChild
node, or if the
* node to append is one of this node's ancestors or this node itself.
*
WRONG_DOCUMENT_ERR: Raised if newChild
was created from
* a different document than the one that created this node.
*
NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly or if
* the previous parent of the node being inserted is readonly.
*/
public Node appendChild(Node newChild) throws DOMException {
return document.appendChild(newChild);
}
/**
* Returns whether this node has any children.
*
* @return true
if this node has any children, false
otherwise.
*/
public boolean hasChildNodes() {
return document.hasChildNodes();
}
/**
* Returns a duplicate of this node, i.e., serves as a generic copy constructor for nodes. The
* duplicate node has no parent; ( parentNode
is null
.).
Cloning
* an Element
copies all attributes and their values, including those generated by
* the XML processor to represent defaulted attributes, but this method does not copy any text
* it contains unless it is a deep clone, since the text is contained in a child
* Text
node. Cloning an Attribute
directly, as opposed to be cloned
* as part of an Element
cloning operation, returns a specified attribute (
* specified
is true
). Cloning any other type of node simply returns a
* copy of this node.
Note that cloning an immutable subtree results in a mutable copy, but
* the children of an EntityReference
clone are readonly . In addition, clones of
* unspecified Attr
nodes are specified. And, cloning Document
,
* DocumentType
, Entity
, and Notation
nodes is
* implementation dependent.
*
* @param deep If true
, recursively clone the subtree under the specified node; if
* false
, clone only the node itself (and its attributes, if it is an
* Element
).
* @return The duplicate node.
*/
public Node cloneNode(boolean deep) {
return document.cloneNode(deep);
}
/**
* Puts all Text
nodes in the full depth of the sub-tree underneath this
* Node
, including attribute nodes, into a "normal" form where only structure
* (e.g., elements, comments, processing instructions, CDATA sections, and entity references)
* separates Text
nodes, i.e., there are neither adjacent Text
nodes
* nor empty Text
nodes. This can be used to ensure that the DOM view of a document
* is the same as if it were saved and re-loaded, and is useful when operations (such as
* XPointer lookups) that depend on a particular document tree structure are to be used.In
* cases where the document contains CDATASections
, the normalize operation alone
* may not be sufficient, since XPointers do not differentiate between Text
nodes
* and CDATASection
nodes.
*/
public void normalize() {
document.normalize();
}
/**
* Tests whether the DOM implementation implements a specific feature and that feature is
* supported by this node.
*
* @param feature The name of the feature to test. This is the same name which can be passed to
* the method hasFeature
on DOMImplementation
.
* @param version This is the version number of the feature to test. In Level 2, version 1, this
* is the string "2.0". If the version is not specified, supporting any version
* of the feature will cause the method to return true
.
* @return Returns true
if the specified feature is supported on this node,
* false
otherwise.
* @since DOM Level 2
*/
public boolean isSupported(String feature, String version) {
return document.isSupported(feature, version);
}
/**
* The namespace URI of this node, or null
if it is unspecified.
This is not a
* computed value that is the result of a namespace lookup based on an examination of the
* namespace declarations in scope. It is merely the namespace URI given at creation time.
*
For nodes of any type other than ELEMENT_NODE
and
* ATTRIBUTE_NODE
and nodes created with a DOM Level 1 method, such as
* createElement
from the Document
interface, this is always
* null
.Per the Namespaces in XML Specification an attribute does not inherit its
* namespace from the element it is attached to. If an attribute is not explicitly given a
* namespace, it simply has no namespace.
*
* @since DOM Level 2
*/
public String getNamespaceURI() {
return document.getNamespaceURI();
}
/**
* The namespace prefix of this node, or null
if it is unspecified.
Note that
* setting this attribute, when permitted, changes the nodeName
attribute, which
* holds the qualified name, as well as the tagName
and name
* attributes of the Element
and Attr
interfaces, when applicable.
*
Note also that changing the prefix of an attribute that is known to have a default value,
* does not make a new attribute with the default value and the original prefix appear, since
* the namespaceURI
and localName
do not change.
For nodes of any
* type other than ELEMENT_NODE
and ATTRIBUTE_NODE
and nodes created
* with a DOM Level 1 method, such as createElement
from the Document
* interface, this is always null
.
*
* @throws DOMException INVALID_CHARACTER_ERR: Raised if the specified prefix contains an
* illegal character, per the XML 1.0 specification .
*
NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
*
NAMESPACE_ERR: Raised if the specified prefix
is
* malformed per the Namespaces in XML specification, if the
* namespaceURI
of this node is null
, if the
* specified prefix is "xml" and the namespaceURI
of this node
* is different from "http://www.w3.org/XML/1998/namespace", if this node
* is an attribute and the specified prefix is "xmlns" and the
* namespaceURI
of this node is different from "
* http://www.w3.org/2000/xmlns/", or if this node is an attribute and the
* qualifiedName
of this node is "xmlns" .
* @since DOM Level 2
*/
public String getPrefix() {
return document.getPrefix();
}
/**
* The namespace prefix of this node, or null
if it is unspecified.
Note that
* setting this attribute, when permitted, changes the nodeName
attribute, which
* holds the qualified name, as well as the tagName
and name
* attributes of the Element
and Attr
interfaces, when applicable.
*
Note also that changing the prefix of an attribute that is known to have a default value,
* does not make a new attribute with the default value and the original prefix appear, since
* the namespaceURI
and localName
do not change.
For nodes of any
* type other than ELEMENT_NODE
and ATTRIBUTE_NODE
and nodes created
* with a DOM Level 1 method, such as createElement
from the Document
* interface, this is always null
.
*
* @throws DOMException INVALID_CHARACTER_ERR: Raised if the specified prefix contains an
* illegal character, per the XML 1.0 specification .
*
NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
*
NAMESPACE_ERR: Raised if the specified prefix
is
* malformed per the Namespaces in XML specification, if the
* namespaceURI
of this node is null
, if the
* specified prefix is "xml" and the namespaceURI
of this node
* is different from "http://www.w3.org/XML/1998/namespace", if this node
* is an attribute and the specified prefix is "xmlns" and the
* namespaceURI
of this node is different from "
* http://www.w3.org/2000/xmlns/", or if this node is an attribute and the
* qualifiedName
of this node is "xmlns" .
* @since DOM Level 2
*/
public void setPrefix(String arg0) throws DOMException {
document.setPrefix(arg0);
}
/**
* Returns the local part of the qualified name of this node.
For nodes of any type other
* than ELEMENT_NODE
and ATTRIBUTE_NODE
and nodes created with a DOM
* Level 1 method, such as createElement
from the Document
interface,
* this is always null
.
*
* @since DOM Level 2
*/
public String getLocalName() {
return document.getLocalName();
}
/**
* Returns whether this node (if it is an element) has any attributes.
*
* @return true
if this node has any attributes, false
otherwise.
* @since DOM Level 2
*/
public boolean hasAttributes() {
return document.hasAttributes();
}
protected void setMessage(SOAPMessageImpl message) {
soapMessage = message;
}
/*
* DOM-Level 3 methods
*/
public String getBaseURI() {
return document.getBaseURI();
}
public short compareDocumentPosition(Node node) throws DOMException {
return document.compareDocumentPosition(node);
}
public String getTextContent() throws DOMException {
return document.getTextContent();
}
public void setTextContent(String textContent) throws DOMException {
document.setTextContent(textContent);
}
public boolean isSameNode(Node other) {
return document.isSameNode(other);
}
public String lookupPrefix(String namespaceURI) {
return document.lookupPrefix(namespaceURI);
}
public boolean isDefaultNamespace(String namespaceURI) {
return document.isDefaultNamespace(namespaceURI);
}
public String lookupNamespaceURI(String prefix) {
return document.lookupNamespaceURI(prefix);
}
public boolean isEqualNode(Node node) {
return document.isEqualNode(node);
}
public Object getFeature(String feature, String version) {
return document.getFeature(feature, version);
}
public Object setUserData(String key, Object data, UserDataHandler handler) {
return document.setUserData(key, data, handler);
}
public Object getUserData(String key) {
return document.getUserData(key);
}
public String getValue() {
//There are no immediate child text nodes to soap part
return null;
}
public void setParentElement(SOAPElement parent) throws SOAPException {
throw new SOAPException("Cannot set the parent element of SOAPPart");
}
public SOAPElement getParentElement() {
return null; //SOAP part is the root element
}
public void detachNode() {
//nothing to do here
}
public void recycleNode() {
//nothing to do here
}
public void setValue(String value) {
throw new IllegalStateException("Cannot set value of SOAPPart.");
}
Node toSAAJNode(org.w3c.dom.Node domNode) {
return ProxyNode.toSAAJNode(domNode, this);
}
}