blob: 1cd9cafacb70598e11b662c2fde357eddcd4e1fd [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.axis2.saaj;
import org.apache.axiom.om.OMComment;
import org.apache.axiom.om.OMDocument;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMException;
import org.apache.axiom.om.OMInformationItem;
import org.apache.axiom.om.OMText;
import org.apache.axiom.soap.SOAPBody;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axiom.soap.SOAPFault;
import org.apache.axiom.soap.SOAPFaultDetail;
import org.apache.axiom.soap.SOAPFaultNode;
import org.apache.axiom.soap.SOAPHeader;
import org.apache.axiom.soap.SOAPHeaderBlock;
import org.w3c.dom.Attr;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.TypeInfo;
import org.w3c.dom.UserDataHandler;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPException;
/**
* A representation of a node (element) in a DOM representation of an XML document that provides
* some tree manipulation methods. This interface provides methods for getting the value of a node,
* for getting and setting the parent of a node, and for removing a node.
*/
public abstract class ProxyNode<T extends org.w3c.dom.Node, S extends OMInformationItem> implements Node {
protected final T target;
protected final S omTarget;
static final String SAAJ_NODE = "saaj.node";
public ProxyNode(T target, S omTarget) {
this.target = target;
this.omTarget = omTarget;
target.setUserData(SAAJ_NODE, this, null);
}
public final T getTarget() {
return target;
}
public final S getOMTarget() {
return omTarget;
}
/**
* Notifies the implementation that this <code>Node</code> object is no longer being used by the
* application and that the implementation is free to reuse this object for nodes that may be
* created later.
* <p/>
* Calling the method <code>recycleNode</code> implies that the method <code>detachNode</code>
* has been called previously.
*/
public void recycleNode() {
// No corresponding implementation in OM
// There is no implementation in Axis 1.2 also
}
public void setType(int nodeType) throws OMException {
throw new UnsupportedOperationException("TODO");
}
public int getType() {
return this.getNodeType();
}
public TypeInfo getSchemaTypeInfo() {
// TODO - Fixme.
throw new UnsupportedOperationException("TODO");
}
public void setIdAttribute(String name, boolean isId) throws DOMException {
// TODO - Fixme.
throw new UnsupportedOperationException("TODO");
}
public void setIdAttributeNS(String namespaceURI, String localName, boolean isId)
throws DOMException {
// TODO - Fixme.
throw new UnsupportedOperationException("TODO");
}
public void setIdAttributeNode(Attr idAttr, boolean isId) throws DOMException {
// TODO - Fixme.
throw new UnsupportedOperationException("TODO");
}
/**
* Converts or extracts the SAAJ node from the given DOM Node (domNode)
*
* @param domNode
* @return the SAAJ Node corresponding to the domNode
*/
Node toSAAJNode(Node domNode) {
return toSAAJNode(domNode, this);
}
/**
* Converts or extracts the SAAJ node from the given DOM Node (domNode)
*
* @param domNode
* @return the SAAJ Node corresponding to the domNode
*/
static Node toSAAJNode(Node domNode, Node parentNode) {
if (domNode == null) {
return null;
}
Node saajNode = (Node)domNode.getUserData(SAAJ_NODE);
if (saajNode == null) { // if SAAJ node has not been set in userData, try to construct it
return toSAAJNode2(domNode, parentNode);
}
return saajNode;
}
private static Node toSAAJNode2(Node domNode, Node parentNode) {
if (domNode == null) {
return null;
}
if (domNode instanceof org.w3c.dom.Text) {
return new TextImplEx((OMText)domNode);
} else if (domNode instanceof org.w3c.dom.Comment) {
return new CommentImpl((OMComment)domNode);
} else if (domNode instanceof SOAPBody) {
return new org.apache.axis2.saaj.SOAPBodyImpl((SOAPBody)domNode);
} else if (domNode instanceof SOAPEnvelope) {
return new org.apache.axis2.saaj.SOAPEnvelopeImpl((SOAPEnvelope)domNode);
} else if (domNode instanceof SOAPFaultNode) {
return new org.apache.axis2.saaj.SOAPFaultElementImpl<SOAPFaultNode>((SOAPFaultNode)domNode);
} else if (domNode instanceof SOAPFaultDetail) {
return new org.apache.axis2.saaj.DetailImpl((SOAPFaultDetail)domNode);
} else if (domNode instanceof SOAPFault) {
return new org.apache.axis2.saaj.SOAPFaultImpl((SOAPFault)domNode);
} else if (domNode instanceof SOAPHeaderBlock) {
return new org.apache.axis2.saaj.SOAPHeaderElementImpl((SOAPHeaderBlock)domNode);
} else if (domNode instanceof SOAPHeader) {
return new org.apache.axis2.saaj.SOAPHeaderImpl((SOAPHeader)domNode);
} else if (domNode instanceof Document) {
return new SAAJDocument((OMDocument)domNode);
} else { // instanceof org.apache.axis2.om.impl.dom.ElementImpl
return new SOAPElementImpl<OMElement>((OMElement)domNode);
}
}
public org.w3c.dom.Node getParentNode() {
return toSAAJNode(target.getParentNode());
}
public final boolean hasAttributes() {
return target.hasAttributes();
}
public final boolean isSupported(String feature, String version) {
return target.isSupported(feature, version);
}
public final String getBaseURI() {
return target.getBaseURI();
}
public final String getNodeValue() throws DOMException {
return target.getNodeValue();
}
public final void setNodeValue(String nodeValue) throws DOMException {
target.setNodeValue(nodeValue);
}
public final org.w3c.dom.Node insertBefore(org.w3c.dom.Node newChild, org.w3c.dom.Node refChild) throws DOMException {
return target.insertBefore(newChild, refChild);
}
public final org.w3c.dom.Node replaceChild(org.w3c.dom.Node newChild, org.w3c.dom.Node oldChild) throws DOMException {
return target.replaceChild(newChild, oldChild);
}
public final org.w3c.dom.Node cloneNode(boolean deep) {
return target.cloneNode(deep);
}
public final void normalize() {
target.normalize();
}
public final void setPrefix(String prefix) throws DOMException {
target.setPrefix(prefix);
}
public final short compareDocumentPosition(org.w3c.dom.Node other) throws DOMException {
return target.compareDocumentPosition(other);
}
public final void setTextContent(String textContent) throws DOMException {
target.setTextContent(textContent);
}
public final boolean isSameNode(org.w3c.dom.Node other) {
return target.isSameNode(other);
}
public final String lookupPrefix(String namespaceURI) {
return target.lookupPrefix(namespaceURI);
}
public final boolean isDefaultNamespace(String namespaceURI) {
return target.isDefaultNamespace(namespaceURI);
}
public final String lookupNamespaceURI(String prefix) {
return null;
}
public final boolean isEqualNode(org.w3c.dom.Node arg) {
return target.isEqualNode(arg);
}
public final Object getFeature(String feature, String version) {
return target.getFeature(feature, version);
}
public final Object setUserData(String key, Object data, UserDataHandler handler) {
return target.setUserData(key, data, handler);
}
public final Object getUserData(String key) {
return target.getUserData(key);
}
public final org.w3c.dom.Node removeChild(org.w3c.dom.Node oldChild) throws DOMException {
if (oldChild instanceof ProxyNode) {
oldChild = ((ProxyNode<?,?>)oldChild).getTarget();
}
return target.removeChild(oldChild);
}
public final String getNodeName() {
return target.getNodeName();
}
public final short getNodeType() {
return target.getNodeType();
}
public final Document getOwnerDocument() {
return (Document)toSAAJNode(target.getOwnerDocument());
}
public final String getLocalName() {
return target.getLocalName();
}
public final String getNamespaceURI() {
return target.getNamespaceURI();
}
public final String getPrefix() {
return target.getPrefix();
}
public final org.w3c.dom.Node getFirstChild() {
return toSAAJNode(target.getFirstChild());
}
public final boolean hasChildNodes() {
return target.hasChildNodes();
}
public final org.w3c.dom.Node getLastChild() {
return toSAAJNode(target.getLastChild());
}
protected final NodeList toSAAJNodeList(NodeList nodes) {
NodeListImpl result = new NodeListImpl();
for (int i = 0; i < nodes.getLength(); i++) {
result.addNode(toSAAJNode(nodes.item(i)));
}
return result;
}
public final NodeList getChildNodes() {
return toSAAJNodeList(target.getChildNodes());
}
public final org.w3c.dom.Node appendChild(org.w3c.dom.Node child) throws DOMException {
if (getOwnerDocument() != child.getOwnerDocument()) {
throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, "Wrong document");
}
try {
if (child instanceof Element) {
return appendElement((Element)child);
} else {
target.appendChild(((ProxyNode<?,?>)child).target);
return child;
}
} catch (SOAPException e) {
DOMException ex =
new DOMException(DOMException.HIERARCHY_REQUEST_ERR, e.getMessage());
ex.initCause(e);
throw ex;
}
}
protected Element appendElement(Element child) throws SOAPException {
String namespaceURI = child.getNamespaceURI();
String prefix = child.getPrefix();
SOAPElementImpl<OMElement> childEle = (SOAPElementImpl<OMElement>)child;
if (namespaceURI != null && namespaceURI.trim().length() > 0) {
childEle.omTarget.setNamespace(childEle.omTarget.declareNamespace(namespaceURI, prefix));
}
target.appendChild(childEle.target);
childEle.setParentElement((SOAPElement)this);
return childEle;
}
public final String getTextContent() throws DOMException {
return target.getTextContent();
}
public final NamedNodeMap getAttributes() {
return target.getAttributes();
}
public final org.w3c.dom.Node getNextSibling() {
return toSAAJNode(target.getNextSibling());
}
public final org.w3c.dom.Node getPreviousSibling() {
return toSAAJNode(target.getPreviousSibling());
}
}