/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Axis" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.axis.message;
import java.io.Reader;
import java.io.Serializable;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import javax.xml.namespace.QName;
import javax.xml.rpc.encoding.TypeMapping;
import javax.xml.soap.Name;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFactory;
import org.apache.axis.AxisFault;
import org.apache.axis.Constants;
import org.apache.axis.MessageContext;
import org.apache.axis.components.logger.LogFactory;
import org.apache.axis.encoding.DeserializationContext;
import org.apache.axis.encoding.DeserializationContextImpl;
import org.apache.axis.encoding.Deserializer;
import org.apache.axis.encoding.SerializationContext;
import org.apache.axis.encoding.SerializationContextImpl;
import org.apache.axis.enum.Style;
import org.apache.axis.soap.SOAPConstants;
import org.apache.axis.utils.Mapping;
import org.apache.axis.utils.Messages;
import org.apache.axis.utils.XMLUtils;
import org.apache.commons.logging.Log;
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.Text;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
/*
* MessageElement is the base type of nodes of the SOAP message parse tree.
*
* Note: it was made Serializable to help users of Apache SOAP who had
* exploited the serializability of the DOM tree to migrate to Axis.
*/
public class MessageElement implements SOAPElement, Serializable
{
protected static Log log =
LogFactory.getLog(MessageElement.class.getName());
private static final Mapping enc11Mapping =
new Mapping(Constants.URI_SOAP11_ENC,
"SOAP-ENC");
private static final Mapping enc12Mapping =
new Mapping(Constants.URI_SOAP12_ENC,
"SOAP-ENC");
protected String name ;
protected String prefix ;
protected String namespaceURI ;
protected transient Attributes attributes = NullAttributes.singleton;
protected String id;
protected String href;
protected boolean _isRoot = true;
protected SOAPEnvelope message = null;
protected boolean _isDirty = false;
protected transient DeserializationContext context;
protected transient QName typeQName = null;
protected Vector qNameAttrs = null;
// Some message representations - as recorded SAX events...
protected transient SAX2EventRecorder recorder = null;
protected int startEventIndex = 0;
protected int startContentsIndex = 0;
protected int endEventIndex = -1;
// ...or as DOM
protected Element elementRep = null;
protected Text textRep = null;
protected MessageElement parent = null;
public ArrayList namespaces = null;
/** Our encoding style, if any */
protected String encodingStyle = null;
/** Object value, possibly supplied by subclass */
private Object objectValue = null;
/** No-arg constructor for building messages?
*/
public MessageElement()
{
}
public MessageElement(String namespace, String localPart)
{
namespaceURI = namespace;
name = localPart;
}
public MessageElement(String localPart, String prefix, String namespace)
{
this.namespaceURI = namespace;
this.name = localPart;
this.prefix = prefix;
addMapping(new Mapping(namespace, prefix));
}
public MessageElement(Name eltName)
{
this(eltName.getLocalName(),eltName.getPrefix(), eltName.getURI());
}
public MessageElement(String namespace, String localPart, Object value)
{
this(namespace, localPart);
objectValue = value;
}
public MessageElement(QName name, Object value)
{
this(name.getNamespaceURI(), name.getLocalPart());
objectValue = value;
}
public MessageElement(Element elem)
{
elementRep = elem;
namespaceURI = elem.getNamespaceURI();
name = elem.getLocalName();
}
public MessageElement(Text text)
{
textRep = text;
namespaceURI = text.getNamespaceURI();
name = text.getLocalName();
}
public MessageElement(String namespace, String localPart, String prefix,
Attributes attributes, DeserializationContext context)
throws AxisFault
{
if (log.isDebugEnabled()) {
log.debug(Messages.getMessage("newElem00", super.toString(),
"{" + prefix + "}" + localPart));
for (int i = 0; attributes != null && i < attributes.getLength(); i++) {
log.debug(" " + attributes.getQName(i) + " = '" + attributes.getValue(i) + "'");
}
}
this.namespaceURI = namespace;
this.name = localPart;
this.prefix = prefix;
this.context = context;
this.startEventIndex = context.getStartOfMappingsPos();
setNSMappings(context.getCurrentNSMappings());
this.recorder = context.getRecorder();
if (attributes != null && attributes.getLength() > 0) {
this.attributes = attributes;
typeQName = context.getTypeFromAttributes(namespace,
localPart,
attributes);
String rootVal = attributes.getValue(Constants.URI_DEFAULT_SOAP_ENC, Constants.ATTR_ROOT);
if (rootVal != null)
_isRoot = rootVal.equals("1");
id = attributes.getValue(Constants.ATTR_ID);
// Register this ID with the context.....
if (id != null) {
context.registerElementByID(id, this);
if (recorder == null) {
recorder = new SAX2EventRecorder();
context.setRecorder(recorder);
}
}
// Set the encoding style to the attribute value. If null,
// we just automatically use our parent's (see getEncodingStyle)
MessageContext mc = context.getMessageContext();
SOAPConstants sc = (mc != null) ?
mc.getSOAPConstants() :
SOAPConstants.SOAP11_CONSTANTS;
href = attributes.getValue(sc.getAttrHref());
// If there's an arrayType attribute, we can pretty well guess that we're an Array???
if (attributes.getValue(Constants.URI_DEFAULT_SOAP_ENC, Constants.ATTR_ARRAY_TYPE) != null)
typeQName = Constants.SOAP_ARRAY;
encodingStyle =
attributes.getValue(sc.getEncodingURI(),
Constants.ATTR_ENCODING_STYLE);
// if no-encoding style was defined, we don't define as well
if (Constants.URI_SOAP12_NOENC.equals(encodingStyle))
encodingStyle = null;
// If we have an encoding style, and are not a MESSAGE style
// operation (in other words - we're going to do some data
// binding), AND we're SOAP 1.2, check the encoding style against
// the ones we've got type mappings registered for. If it isn't
// registered, throw a DataEncodingUnknown fault as per the
// SOAP 1.2 spec.
if (encodingStyle != null &&
sc.equals(SOAPConstants.SOAP12_CONSTANTS) &&
(mc.getOperationStyle() != Style.MESSAGE)) {
TypeMapping tm = mc.getTypeMappingRegistry().
getTypeMapping(encodingStyle);
if (tm == null ||
(tm.equals(mc.getTypeMappingRegistry().
getDefaultTypeMapping()))) {
AxisFault badEncodingFault = new AxisFault(
Constants.FAULT_SOAP12_DATAENCODINGUNKNOWN,
"bad encoding style", null, null);
throw badEncodingFault;
}
}
}
}
/** !!! TODO : Make sure this handles multiple targets
*/
Deserializer fixupDeserializer;
public void setFixupDeserializer(Deserializer dser)
{
// !!! Merge targets here if already set?
fixupDeserializer = dser;
}
public Deserializer getFixupDeserializer()
{
return fixupDeserializer;
}
public void setEndIndex(int endIndex)
{
endEventIndex = endIndex;
//context.setRecorder(null);
}
public boolean isDirty() { return _isDirty; }
public void setDirty(boolean dirty) { _isDirty = dirty; }
public boolean isRoot() { return _isRoot; }
public String getID() { return id; }
public String getHref() { return href; }
public Attributes getAttributesEx() { return attributes; }
public Node getFirstChild() {
return null; //TODO: Fix this for SAAJ 1.2 Implementation
}
public Node getLastChild() {
return null; //TODO: Fix this for SAAJ 1.2 Implementation
}
public Node getNextSibling() {
return null; //TODO: Fix this for SAAJ 1.2 Implementation
}
public Node getParentNode() {
return null; //TODO: Fix this for SAAJ 1.2 Implementation
}
public Node getPreviousSibling() {
return null; //TODO: Fix this for SAAJ 1.2 Implementation
}
public Node cloneNode(boolean deep) {
return null; //TODO: Fix this for SAAJ 1.2 Implementation
}
public NodeList getChildNodes() {
return new NodeListImpl( children);
}
public boolean isSupported(String feature, String version) {
return false; //TODO: Fix this for SAAJ 1.2 Implementation
}
public Node appendChild(Node newChild) throws DOMException {
return null; //TODO: Fix this for SAAJ 1.2 Implementation
}
public Node removeChild(Node oldChild) throws DOMException {
return null; //TODO: Fix this for SAAJ 1.2 Implementation
}
public Node insertBefore(Node newChild, Node refChild) throws DOMException {
return null; //TODO: Fix this for SAAJ 1.2 Implementation
}
public Node replaceChild(Node newChild, Node oldChild) throws DOMException {
return null; //TODO: Fix this for SAAJ 1.2 Implementation
}
/**
* Obtain an Attributes collection consisting of all attributes
* for this MessageElement, including namespace declarations.
*
* @return Attributes collection
*/
public Attributes getCompleteAttributes() {
if (namespaces == null)
return attributes;
AttributesImpl attrs = null;
if (attributes == NullAttributes.singleton)
attrs = new AttributesImpl();
else
attrs = new AttributesImpl(attributes);
for (Iterator iterator = namespaces.iterator(); iterator.hasNext();) {
Mapping mapping = (Mapping) iterator.next();
String prefix = mapping.getPrefix();
String nsURI = mapping.getNamespaceURI();
attrs.addAttribute(Constants.NS_URI_XMLNS, prefix,
"xmlns:" + prefix, nsURI, "CDATA");
}
return attrs;
}
public String getName() { return( name ); }
public void setName(String name) { this.name = name; }
public QName getQName() { return new QName(namespaceURI, name); }
public void setQName(QName qName) {
this.name = qName.getLocalPart();
this.namespaceURI = qName.getNamespaceURI();
}
public String getPrefix() { return( prefix ); }
public void setNodeValue(String nodeValue) throws DOMException {
//TODO: Fix this for SAAJ 1.2 Implementation
}
public void setPrefix(String prefix) { this.prefix = prefix; }
public Document getOwnerDocument() {
return null; //TODO: Fix this for SAAJ 1.2 Implementation
}
public NamedNodeMap getAttributes() {
return new NamedNodeMapImpl(attributes);
}
public short getNodeType() {
return 0; //TODO: Fix this for SAAJ 1.2 Implementation
}
public void normalize() {
//TODO: Fix this for SAAJ 1.2 Implementation
}
public boolean hasAttributes() {
return false; //TODO: Fix this for SAAJ 1.2 Implementation
}
public boolean hasChildNodes() {
return false; //TODO: Fix this for SAAJ 1.2 Implementation
}
public String getLocalName() {
return name;
}
public String getNamespaceURI() { return( namespaceURI ); }
public String getNodeName() {
return name;
}
public String getNodeValue() throws DOMException {
return null; //TODO: Fix this for SAAJ 1.2 Implementation
}
public void setNamespaceURI(String nsURI) { namespaceURI = nsURI; }
public QName getType() {
// Try to get the type from our target if we're a reference...
if (typeQName == null && href != null && context != null) {
MessageElement referent = context.getElementByID(href);
if (referent != null) {
typeQName = referent.getType();
}
}
return typeQName;
}
public void setType(QName qname) {
typeQName = qname;
}
public SAX2EventRecorder getRecorder() { return recorder; }
public void setRecorder(SAX2EventRecorder rec) { recorder = rec; }
/**
* Get the encoding style. If ours is null, walk up the hierarchy
* and use our parent's. Default if we're the root is "".
*
* @return the currently in-scope encoding style
*/
public String getEncodingStyle() {
if (encodingStyle == null) {
if (parent == null)
return "";
return parent.getEncodingStyle();
}
return encodingStyle;
}
public void removeContents() {
//TODO: Fix this for SAAJ 1.2 Implementation
}
public Iterator getVisibleNamespacePrefixes() {
return null; //TODO: Fix this for SAAJ 1.2 Implementation
}
/**
* Sets the encoding style for this <CODE>SOAPElement</CODE>
* object to one specified. The semantics of a null value,
* as above in getEncodingStyle() are to just use the parent's value,
* but null here means set to "".
*
* @param encodingStyle a <CODE>String</CODE>
* giving the encoding style
* @throws java.lang.IllegalArgumentException if
* there was a problem in the encoding style being set.
* @see #getEncodingStyle() getEncodingStyle()
*/
public void setEncodingStyle(String encodingStyle) throws SOAPException {
if (encodingStyle == null) {
encodingStyle = "";
}
this.encodingStyle = encodingStyle;
// Wherever we set the encoding style, map the SOAP-ENC prefix
// just for fun (if it's a known style)
if (encodingStyle.equals(Constants.URI_SOAP11_ENC)) {
addMapping(enc11Mapping);
} else if (encodingStyle.equals(Constants.URI_SOAP12_ENC)) {
addMapping(enc12Mapping);
}
}
private MessageElement getParent() { return parent; }
private void setParent(MessageElement parent) throws SOAPException
{
this.parent = parent;
if (parent != null) {
parent.addChild(this);
}
}
private ArrayList children = null;
/**
* Note that this method will log a error and no-op if there is
* a value (set using setObjectValue) in the MessageElement.
*/
public void addChild(MessageElement el) throws SOAPException
{
if (objectValue != null) {
SOAPException exc = new SOAPException(Messages.getMessage("valuePresent"));
log.error(Messages.getMessage("valuePresent"), exc);
throw exc;
}
if (children == null)
children = new ArrayList();
children.add(el);
el.parent = this;
}
/**
* Remove a child element.
*/
public void removeChild(MessageElement child) {
// Remove all occurrences in case it has been added multiple times.
int i;
while ((i = children.indexOf(child)) != -1) {
children.remove(i);
}
}
public ArrayList getChildren()
{
return children;
}
public void setContentsIndex(int index)
{
startContentsIndex = index;
}
public void setNSMappings(ArrayList namespaces)
{
this.namespaces = namespaces;
}
public String getPrefix(String namespaceURI) {
if ((namespaceURI == null) || (namespaceURI.equals("")))
return null;
if (href != null && getRealElement() != null) {
return getRealElement().getPrefix(namespaceURI);
}
for (int i = 0; namespaces != null && i < namespaces.size(); i++) {
Mapping map = (Mapping)namespaces.get(i);
if (map.getNamespaceURI().equals(namespaceURI))
return map.getPrefix();
}
if (parent != null)
return parent.getPrefix(namespaceURI);
return null;
}
public String getNamespaceURI(String prefix) {
if (prefix == null)
prefix = "";
if (href != null && getRealElement() != null) {
return getRealElement().getNamespaceURI(prefix);
}
for (int i = 0; namespaces != null && i < namespaces.size(); i++) {
Mapping map = (Mapping)namespaces.get(i);
if (map.getPrefix().equals(prefix)) {
return map.getNamespaceURI();
}
}
if (parent != null)
return parent.getNamespaceURI(prefix);
if (log.isDebugEnabled()) {
log.debug(Messages.getMessage("noPrefix00", "" + this, prefix));
}
return null;
}
/**
* Returns value of the node as an object of registered type.
* @return Object of proper type, or null if no mapping could be found.
*/
public Object getObjectValue() {
Object obj = null;
try {
obj = getObjectValue(null);
} catch (Exception e) {
log.debug("getValue()", e);
}
return obj;
}
/**
* Returns value of the node as an object of registered type.
* @param cls Class that contains top level deserializer metadata
* @return Object of proper type, or null if no mapping could be found.
*/
public Object getObjectValue(Class cls) throws Exception {
if (objectValue == null) {
objectValue = getValueAsType(getType(), cls);
}
return objectValue;
}
/**
* Sets value of this node to an Object.
* A serializer needs to be registered for this object class for proper
* operation.
* <p>
* Note that this method will log an error and no-op if there are
* any children in the MessageElement or if the MessageElement was
* constructed from XML.
* @param newValue node's value or null.
*/
public void setObjectValue(Object newValue) throws SOAPException {
if (children != null && !children.isEmpty()) {
SOAPException exc = new SOAPException(Messages.getMessage("childPresent"));
log.error(Messages.getMessage("childPresent"), exc);
throw exc;
}
if (elementRep != null) {
SOAPException exc = new SOAPException(Messages.getMessage("xmlPresent"));
log.error(Messages.getMessage("xmlPresent"), exc);
throw exc;
}
if (textRep != null) {
SOAPException exc = new SOAPException(Messages.getMessage("xmlPresent"));
log.error(Messages.getMessage("xmlPresent"), exc);
throw exc;
}
this.objectValue = newValue;
}
public Object getValueAsType(QName type) throws Exception
{
return getValueAsType(type, null);
}
public Object getValueAsType(QName type, Class cls) throws Exception
{
if (context == null)
throw new Exception(Messages.getMessage("noContext00"));
Deserializer dser = null;
if (cls == null) {
dser = context.getDeserializerForType(type);
} else {
dser = context.getDeserializerForClass(cls);
}
if (dser == null)
throw new Exception(Messages.getMessage("noDeser00", "" + type));
boolean oldVal = context.isDoneParsing();
((DeserializationContextImpl)context).deserializing(true);
context.pushElementHandler(new EnvelopeHandler((SOAPHandler)dser));
publishToHandler((org.xml.sax.ContentHandler) context);
((DeserializationContextImpl)context).deserializing(oldVal);
return dser.getValue();
}
protected static class QNameAttr {
QName name;
QName value;
}
public void addAttribute(String namespace, String localName,
QName value)
{
if (qNameAttrs == null)
qNameAttrs = new Vector();
QNameAttr attr = new QNameAttr();
attr.name = new QName(namespace, localName);
attr.value = value;
qNameAttrs.addElement(attr);
// !!! Add attribute to attributes!
}
protected AttributesImpl makeAttributesEditable() {
if (attributes == null || attributes instanceof NullAttributes) {
attributes = new AttributesImpl();
} else if (!(attributes instanceof AttributesImpl)) {
attributes = new AttributesImpl(attributes);
}
return (AttributesImpl) attributes;
}
public void addAttribute(String namespace, String localName,
String value)
{
AttributesImpl attributes = makeAttributesEditable();
attributes.addAttribute(namespace, localName, "", "CDATA",
value);
}
public void addAttribute(String prefix, String namespace, String localName,
String value)
{
AttributesImpl attributes = makeAttributesEditable();
String attrName = localName;
if (prefix != null && prefix.length() > 0) {
attrName = prefix + ":" + localName;
}
attributes.addAttribute(namespace, localName, attrName, "CDATA",
value);
}
/**
* Set an attribute, adding the attribute if it isn't already present
* in this element, and changing the value if it is. Passing null as the
* value will cause any pre-existing attribute by this name to go away.
*/
public void setAttribute(String namespace, String localName,
String value)
{
AttributesImpl attributes = makeAttributesEditable();
int idx = attributes.getIndex(namespace, localName);
if (idx > -1) {
// Got it, so replace it's value.
if (value != null) {
attributes.setValue(idx, value);
} else {
attributes.removeAttribute(idx);
}
return;
}
addAttribute(namespace, localName, value);
}
public String getAttributeValue(String localName)
{
if (attributes == null) {
return null;
}
return attributes.getValue(localName);
}
public void setEnvelope(SOAPEnvelope env)
{
env.setDirty(true);
message = env;
}
public SOAPEnvelope getEnvelope()
{
return message;
}
public MessageElement getRealElement()
{
if (href == null)
return this;
Object obj = context.getObjectByRef(href);
if (obj == null)
return null;
if (!(obj instanceof MessageElement))
return null;
return (MessageElement)obj;
}
public Document getAsDocument() throws Exception
{
String elementString = getAsString();
Reader reader = new StringReader(elementString);
Document doc = XMLUtils.newDocument(new InputSource(reader));
if (doc == null)
throw new Exception(
Messages.getMessage("noDoc00", elementString));
return doc;
}
public String getAsString() throws Exception {
SerializationContext serializeContext = null;
StringWriter writer = new StringWriter();
MessageContext msgContext;
if (context != null) {
msgContext = context.getMessageContext();
} else {
msgContext = MessageContext.getCurrentContext();
}
serializeContext = new SerializationContextImpl(writer, msgContext);
serializeContext.setSendDecl(false);
output(serializeContext);
writer.close();
return writer.getBuffer().toString();
}
public Element getAsDOM() throws Exception
{
return getAsDocument().getDocumentElement();
}
public void publishToHandler(ContentHandler handler) throws SAXException
{
if (recorder == null)
throw new SAXException(Messages.getMessage("noRecorder00"));
recorder.replay(startEventIndex, endEventIndex, handler);
}
public void publishContents(ContentHandler handler) throws SAXException
{
if (recorder == null)
throw new SAXException(Messages.getMessage("noRecorder00"));
recorder.replay(startContentsIndex, endEventIndex-1, handler);
}
/** This is the public output() method, which will always simply use
* the recorded SAX stream for this element if it is available. If
* not, this method calls outputImpl() to allow subclasses and
* programmatically created messages to serialize themselves.
*
* @param context the SerializationContext we will write to.
*/
public final void output(SerializationContext context) throws Exception
{
if ((recorder != null) && (!_isDirty)) {
recorder.replay(startEventIndex,
endEventIndex,
new SAXOutputter(context));
return;
}
// Turn QName attributes into strings
if (qNameAttrs != null) {
for (int i = 0; i < qNameAttrs.size(); i++) {
QNameAttr attr = (QNameAttr)qNameAttrs.get(i);
QName attrName = attr.name;
setAttribute(attrName.getNamespaceURI(),
attrName.getLocalPart(),
context.qName2String(attr.value));
}
}
/**
* Write the encoding style attribute IF it's different from
* whatever encoding style is in scope....
*/
if (encodingStyle != null) {
MessageContext mc = context.getMessageContext();
SOAPConstants soapConstants = (mc != null) ?
mc.getSOAPConstants() :
SOAPConstants.SOAP11_CONSTANTS;
if (parent == null) {
// don't emit an encoding style if its "" (literal)
if (!encodingStyle.equals("")) {
setAttribute(soapConstants.getEnvelopeURI(),
Constants.ATTR_ENCODING_STYLE,
encodingStyle);
}
} else if (!encodingStyle.equals(parent.getEncodingStyle())) {
setAttribute(soapConstants.getEnvelopeURI(),
Constants.ATTR_ENCODING_STYLE,
encodingStyle);
}
}
outputImpl(context);
}
/** Subclasses can override
*/
protected void outputImpl(SerializationContext context) throws Exception
{
if (elementRep != null) {
boolean oldPretty = context.getPretty();
context.setPretty(false);
context.writeDOMElement(elementRep);
context.setPretty(oldPretty);
return;
}
if (textRep != null) {
boolean oldPretty = context.getPretty();
context.setPretty(false);
context.writeSafeString(textRep.getData());
context.setPretty(oldPretty);
return;
}
if (prefix != null)
context.registerPrefixForURI(prefix, namespaceURI);
if (namespaces != null) {
for (Iterator i = namespaces.iterator(); i.hasNext();) {
Mapping mapping = (Mapping) i.next();
context.registerPrefixForURI(mapping.getPrefix(), mapping.getNamespaceURI());
}
}
if (objectValue != null) {
context.serialize(new QName(namespaceURI, name),
attributes,
objectValue, null, false, null);
return;
}
context.startElement(new QName(namespaceURI, name), attributes);
if (children != null) {
for (Iterator it = children.iterator(); it.hasNext();) {
((MessageElement)it.next()).output(context);
}
}
context.endElement();
}
public String toString() {
try {
return getAsString();
}
catch( Exception exp ) {
log.error(Messages.getMessage("exception00"), exp);
return null;
}
}
public void addMapping(Mapping map) {
if (namespaces == null)
namespaces = new ArrayList();
namespaces.add(map);
}
// JAXM Node methods...
/**
* Returns the the value of the immediate child of this <code>Node</code>
* object if a child exists and its value is text.
* @return a <code>String</code> with the text of the immediate child of
* this <code>Node</code> object if (1) there is a child and
* (2) the child is a <code>Text</code> object;
* <code>null</code> otherwise
*/
public String getValue() {
try {
Element element = getAsDOM();
if(element.hasChildNodes()){
org.w3c.dom.Node node = element.getFirstChild();
if(node.getNodeType()==org.w3c.dom.Node.TEXT_NODE){
return node.getNodeValue();
}
}
} catch (Exception t){
log.debug("getValue()", t);
}
return null;
}
public void setParentElement(SOAPElement parent) throws SOAPException {
if(parent == null)
throw new IllegalArgumentException(Messages.getMessage("nullParent00"));
try {
setParent((MessageElement)parent);
} catch (Throwable t) {
throw new SOAPException(t);
}
}
public SOAPElement getParentElement() {
return getParent();
}
/**
* Break the relationship between this element and its parent, if any.
*/
public void detachNode() {
if (parent != null) {
parent.removeChild(this);
parent = null;
}
}
/**
* No-opped - Axis does not recycle nodes.
*/
public void recycleNode() {}
public void setValue(String s) {
//TODO: Fix this for SAAJ 1.2 Implementation
}
// JAXM SOAPElement methods...
public SOAPElement addChildElement(Name name) throws SOAPException {
MessageElement child = new MessageElement(name.getLocalName(),
name.getPrefix(),
name.getURI());
addChild(child);
return child;
}
public SOAPElement addChildElement(String localName) throws SOAPException {
// Inherit parent's namespace
MessageElement child = new MessageElement(getNamespaceURI(),
localName);
addChild(child);
return child;
}
public SOAPElement addChildElement(String localName,
String prefix) throws SOAPException {
MessageElement child = new MessageElement(getNamespaceURI(prefix),
localName);
child.setPrefix(prefix);
addChild(child);
return child;
}
public SOAPElement addChildElement(String localName,
String prefix,
String uri) throws SOAPException {
MessageElement child = new MessageElement(uri, localName);
child.setPrefix(prefix);
child.addNamespaceDeclaration(prefix, uri);
addChild(child);
return child;
}
/**
* The added child must be an instance of MessageElement rather than
* an abitrary SOAPElement otherwise a (wrapped) ClassCastException
* will be thrown.
*/
public SOAPElement addChildElement(SOAPElement element)
throws SOAPException {
try {
addChild((MessageElement)element);
return element;
} catch (ClassCastException e) {
throw new SOAPException(e);
}
}
/**
* Text nodes are not supported.
*/
public SOAPElement addTextNode(String s) throws SOAPException {
org.apache.axis.message.Text text = new org.apache.axis.message.Text(s);
try {
addChild(text);
return this;
} catch (ClassCastException e) {
throw new SOAPException(e);
}
}
public SOAPElement addAttribute(Name name, String value)
throws SOAPException {
try {
addAttribute(name.getPrefix(), name.getURI(), name.getLocalName(), value);
} catch (RuntimeException t) {
throw new SOAPException(t);
}
return this;
}
public SOAPElement addNamespaceDeclaration(String prefix,
String uri)
throws SOAPException {
try {
Mapping map = new Mapping(uri, prefix);
addMapping(map);
} catch (RuntimeException t) {
throw new SOAPException(t);
}
return this;
}
public String getAttributeValue(Name name) {
return attributes.getValue(name.getURI(), name.getLocalName());
}
public Iterator getAllAttributes() {
int num = attributes.getLength();
Vector attrs = new Vector(num);
for (int i = 0; i < num; i++) {
String q = attributes.getQName(i);
String prefix = "";
if (q != null) {
int idx = q.indexOf(":");
if (idx > 0) {
prefix = q.substring(0, idx);
} else {
prefix= "";
}
}
attrs.add(new PrefixedQName(attributes.getURI(i),
attributes.getLocalName(i),
prefix));
}
return attrs.iterator();
}
// getNamespaceURI implemented above
public Iterator getNamespacePrefixes() {
Vector prefixes = new Vector();
for (int i = 0; namespaces != null && i < namespaces.size(); i++) {
prefixes.add(((Mapping)namespaces.get(i)).getPrefix());
}
return prefixes.iterator();
}
public Name getElementName() {
return new PrefixedQName(getNamespaceURI(), getName(), getPrefix());
}
public boolean removeAttribute(Name name) {
AttributesImpl attributes = makeAttributesEditable();
boolean removed = false;
for (int i = 0; i < attributes.getLength() && !removed; i++) {
if (attributes.getURI(i).equals(name.getURI()) &&
attributes.getLocalName(i).equals(name.getLocalName())) {
attributes.removeAttribute(i);
removed = true;
}
}
return removed;
}
public boolean removeNamespaceDeclaration(String prefix) {
makeAttributesEditable();
boolean removed = false;
for (int i = 0; namespaces != null && i < namespaces.size() && !removed; i++) {
if (((Mapping)namespaces.get(i)).getPrefix().equals(prefix)) {
namespaces.remove(i);
removed = true;
}
}
return removed;
}
public Iterator getChildElements() {
if (children == null)
children = new ArrayList();
return children.iterator();
}
public Iterator getChildElements(Name name) {
if (children == null)
children = new ArrayList();
int num = children.size();
Vector c = new Vector(num);
for (int i = 0; i < num; i++) {
MessageElement child = (MessageElement)children.get(i);
Name cname = child.getElementName();
if (cname.getURI().equals(name.getURI()) &&
cname.getLocalName().equals(name.getLocalName())) {
c.add(child);
}
}
return c.iterator();
}
public String getTagName() {
return null; //TODO: Fix this for SAAJ 1.2 Implementation
}
public void removeAttribute(String name) throws DOMException {
//TODO: Fix this for SAAJ 1.2 Implementation
}
public boolean hasAttribute(String name) {
return false; //TODO: Fix this for SAAJ 1.2 Implementation
}
public String getAttribute(String name) {
return null; //TODO: Fix this for SAAJ 1.2 Implementation
}
public void removeAttributeNS(String namespaceURI, String localName) throws DOMException {
//TODO: Fix this for SAAJ 1.2 Implementation
}
public void setAttribute(String name, String value) throws DOMException {
//TODO: Fix this for SAAJ 1.2 Implementation
}
public boolean hasAttributeNS(String namespaceURI, String localName) {
return false; //TODO: Fix this for SAAJ 1.2 Implementation
}
public Attr getAttributeNode(String name) {
return null; //TODO: Fix this for SAAJ 1.2 Implementation
}
public Attr removeAttributeNode(Attr oldAttr) throws DOMException {
return null; //TODO: Fix this for SAAJ 1.2 Implementation
}
public Attr setAttributeNode(Attr newAttr) throws DOMException {
return null; //TODO: Fix this for SAAJ 1.2 Implementation
}
public Attr setAttributeNodeNS(Attr newAttr) throws DOMException {
return null; //TODO: Fix this for SAAJ 1.2 Implementation
}
public NodeList getElementsByTagName(String name) {
return null; //TODO: Fix this for SAAJ 1.2 Implementation
}
public String getAttributeNS(String namespaceURI, String localName) {
return null; //TODO: Fix this for SAAJ 1.2 Implementation
}
public void setAttributeNS(String namespaceURI, String qualifiedName, String value) throws DOMException {
//TODO: Fix this for SAAJ 1.2 Implementation
}
public Attr getAttributeNodeNS(String namespaceURI, String localName) {
return null; //TODO: Fix this for SAAJ 1.2 Implementation
}
public NodeList getElementsByTagNameNS(String namespaceURI, String localName) {
return null; //TODO: Fix this for SAAJ 1.2 Implementation
}
// setEncodingStyle implemented above
// getEncodingStyle() implemented above
/**
* Implementation of org.w3c.dom.NodeList for SAAJ 1.2
* This inner class can be replaced or moved if there is an
* Implementation for the whole Axis project
*/
class NodeListImpl implements NodeList {
private ArrayList items = new ArrayList();
NodeListImpl( List list) {
if ( null == list)
return;
Iterator iter = list.iterator();
while (iter.hasNext()) {
Node node = (Node) iter.next();
items.add( node);
}
}
public int getLength() {
return items.size();
}
public Node item(int index) {
return (Node)items.get(index);
}
}
/**
* Implementation of org.w3c.dom.NamedNodeMap for SAAJ 1.2
* This inner class can be replaced or moved if there is an
* Implementation for the whole Axis project
*/
class NamedNodeMapImpl implements NamedNodeMap {
private String[] name, namespaceURI;
NamedNodeMapImpl(Attributes attributes) {
name = new String[attributes.getLength()];
namespaceURI = new String[attributes.getLength()];
for( int i = 0; i < attributes.getLength(); i++) {
name[i] = attributes.getLocalName(i);
namespaceURI[i] = attributes.getURI(i);
}
}
public Node getNamedItem(String name) {
try {
for(int i = 0; i < name.length(); i++) {
if (this.name[i].equals(name))
return SOAPFactory.newInstance().createElement( this.name[i], null, namespaceURI[i]);
}
} catch (SOAPException e) {}
return null;
}
public Node item(int i) {
try {
return SOAPFactory.newInstance().createElement( name[i], null, namespaceURI[i]);
} catch (SOAPException e) {
return null;
}
}
public int getLength() {
return name.length;
}
public Node getNamedItemNS(String namespaceURI, String localName) {
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
}
public Node setNamedItemNS(Node arg) throws DOMException {
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
}
public Node setNamedItem(Node arg) throws DOMException {
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
}
public Node removeNamedItem(String name) throws DOMException {
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
}
public Node removeNamedItemNS(String namespaceURI, String localName) throws DOMException {
throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
}
}
}