package org.jboss.axis;
import org.jboss.axis.encoding.DeserializationContext;
import org.jboss.axis.encoding.DeserializationContextImpl;
import org.jboss.axis.encoding.SerializationContextImpl;
import org.jboss.axis.message.InputStreamBody;
import org.jboss.axis.message.MimeHeadersImpl;
import org.jboss.axis.message.SOAPBodyAxisImpl;
import org.jboss.axis.message.SOAPDocumentImpl;
import org.jboss.axis.message.SOAPEnvelopeAxisImpl;
import org.jboss.axis.message.SOAPHeaderElementAxisImpl;
import org.jboss.axis.message.SOAPPartAxisImpl;
import org.jboss.axis.soap.SOAPConstants;
import org.jboss.axis.transport.http.HTTPConstants;
import org.jboss.axis.utils.Messages;
import org.jboss.axis.utils.SessionUtils;
import org.jboss.logging.Logger;
import org.w3c.dom.Attr;
import org.w3c.dom.CDATASection;
import org.w3c.dom.Comment;
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.xml.sax.InputSource;
import org.xml.sax.SAXException;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Vector;
public class MessagePart extends SOAPPartAxisImpl implements Part
{
private static Logger log = Logger.getLogger(MessagePart.class.getName());
public static final int FORM_STRING = 1;
public static final int FORM_INPUTSTREAM = 2;
public static final int FORM_SOAPENVELOPE = 3;
public static final int FORM_BYTES = 4;
public static final int FORM_BODYINSTREAM = 5;
public static final int FORM_FAULT = 6;
private int currentForm;
private MimeHeadersImpl mimeHeaders = new MimeHeadersImpl();
private static final String[] formNames =
{"", "FORM_STRING", "FORM_INPUTSTREAM", "FORM_SOAPENVELOPE",
"FORM_BYTES", "FORM_BODYINSTREAM", "FORM_FAULT"};
private Object currentMessage;
private String currentMessageAsString = null;
private byte[] currentMessageAsBytes = null;
private SOAPEnvelopeAxisImpl currentMessageAsEnvelope = null;
private Message msgObject;
private Source contentSource = null;
public MessagePart(Message parent, Object initialContents, boolean isBodyStream)
{
setMimeHeader(HTTPConstants.HEADER_CONTENT_ID, SessionUtils.generateSessionId());
setMimeHeader(HTTPConstants.HEADER_CONTENT_TYPE, "text/xml");
msgObject = parent;
int form = FORM_STRING;
if (initialContents instanceof SOAPEnvelopeAxisImpl)
{
form = FORM_SOAPENVELOPE;
}
else if (initialContents instanceof InputStream)
{
form = isBodyStream ? FORM_BODYINSTREAM : FORM_INPUTSTREAM;
}
else if (initialContents instanceof byte[])
{
form = FORM_BYTES;
}
else if (initialContents instanceof AxisFault)
{
form = FORM_FAULT;
}
if (log.isDebugEnabled())
{
log.debug("Enter: SOAPPart ctor(" + formNames[form] + ")");
}
setCurrentMessage(initialContents, form);
if (log.isDebugEnabled())
{
log.debug("Exit: SOAPPart ctor()");
}
}
public Message getMessage()
{
return msgObject;
}
public void setMessage(Message msg)
{
this.msgObject = msg;
}
public String getContentType()
{
return "text/xml";
}
public int getContentLength()
{
try
{
byte[] bytes = this.getAsBytes();
return bytes.length;
}
catch (AxisFault fault)
{
return 0; }
}
public void setSOAPEnvelope(SOAPEnvelopeAxisImpl env)
{
setCurrentMessage(env, FORM_SOAPENVELOPE);
}
public int getSize()
{
return this.getContentLength();
}
public void writeTo(Writer writer) throws IOException
{
if (currentForm == FORM_FAULT)
{
AxisFault env = (AxisFault)currentMessage;
try
{
env.output(new SerializationContextImpl(writer, getMessage().getMessageContext()));
}
catch (Exception e)
{
log.error(Messages.getMessage("exception00"), e);
throw env;
}
}
else if (currentForm == FORM_SOAPENVELOPE)
{
SOAPEnvelopeAxisImpl env = (SOAPEnvelopeAxisImpl)currentMessage;
try
{
env.output(new SerializationContextImpl(writer, getMessage().getMessageContext()));
}
catch (Exception e)
{
throw AxisFault.makeFault(e);
}
}
else
{
String xmlMessage = getAsString();
writer.write(xmlMessage);
}
}
public Object getCurrentMessage()
{
return currentMessage;
}
public void setCurrentMessage(Object currMsg, int form)
{
setCurrentForm(currMsg, form);
}
private void setCurrentForm(Object currMsg, int form)
{
if (currentForm == FORM_SOAPENVELOPE && currentMessageAsEnvelope.isProcessingRPCInvocation() && form == FORM_STRING)
{
log.debug("Preventing FORM_STRING while processing RPCInvocation");
return;
}
log.debug("Changing message form: " + formNames[currentForm] + " -> " + formNames[form]);
currentMessageAsString = null;
currentMessageAsBytes = null;
currentMessageAsEnvelope = null;
currentMessage = currMsg;
currentForm = form;
if (currentForm == FORM_STRING && log.isTraceEnabled())
{
log.trace(currMsg);
}
if (currentForm == FORM_SOAPENVELOPE)
{
currentMessageAsEnvelope = (SOAPEnvelopeAxisImpl)currMsg;
}
}
public byte[] getAsBytes() throws AxisFault
{
log.debug("Enter: SOAPPart::getAsBytes");
if (currentForm == FORM_BYTES)
{
log.debug("Exit: SOAPPart::getAsBytes");
return (byte[])currentMessage;
}
if (currentForm == FORM_BODYINSTREAM)
{
try
{
getAsSOAPEnvelope();
}
catch (Exception e)
{
log.fatal(Messages.getMessage("makeEnvFail00"), e);
log.debug("Exit: SOAPPart::getAsBytes");
return null;
}
}
if (currentForm == FORM_INPUTSTREAM)
{
try
{
InputStream inp = null;
byte[] buf = null;
try
{
inp = (InputStream)currentMessage;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
buf = new byte[4096];
int len;
while ((len = inp.read(buf, 0, 4096)) != -1)
baos.write(buf, 0, len);
buf = baos.toByteArray();
}
finally
{
if (inp != null &&
currentMessage instanceof org.jboss.axis.transport.http.SocketInputStream)
inp.close();
}
setCurrentForm(buf, FORM_BYTES);
log.debug("Exit: SOAPPart::getAsBytes");
return (byte[])currentMessage;
}
catch (Exception e)
{
log.error(Messages.getMessage("exception00"), e);
}
log.debug("Exit: SOAPPart::getAsBytes");
return null;
}
if (currentForm == FORM_SOAPENVELOPE ||
currentForm == FORM_FAULT)
{
getAsString();
}
if (currentForm == FORM_STRING)
{
if (currentMessage == currentMessageAsString &&
currentMessageAsBytes != null)
{
if (log.isDebugEnabled())
{
log.debug("Exit: SOAPPart::getAsBytes()");
}
return currentMessageAsBytes;
}
currentMessageAsString = (String)currentMessage;
try
{
String encoding = null;
if (msgObject != null)
{
try
{
encoding = (String)msgObject.getProperty(SOAPMessage.CHARACTER_SET_ENCODING);
}
catch (SOAPException e)
{
}
}
if (encoding == null)
{
encoding = "UTF-8";
}
setCurrentForm(((String)currentMessage).getBytes(encoding),
FORM_BYTES);
}
catch (UnsupportedEncodingException ue)
{
setCurrentForm(((String)currentMessage).getBytes(),
FORM_BYTES);
}
currentMessageAsBytes = (byte[])currentMessage;
log.debug("Exit: SOAPPart::getAsBytes");
return (byte[])currentMessage;
}
log.error(Messages.getMessage("cantConvert00", "" + currentForm));
log.debug("Exit: SOAPPart::getAsBytes");
return null;
}
public String getAsString() throws AxisFault
{
log.debug("Enter: SOAPPart::getAsString");
if (currentForm == FORM_STRING)
{
if (log.isDebugEnabled())
{
log.debug("Exit: SOAPPart::getAsString()");
}
return (String)currentMessage;
}
if (currentForm == FORM_INPUTSTREAM || currentForm == FORM_BODYINSTREAM)
{
getAsBytes();
}
if (currentForm == FORM_BYTES)
{
if (currentMessage == currentMessageAsBytes && currentMessageAsString != null)
{
if (log.isDebugEnabled())
{
log.debug("Exit: SOAPPart::getAsString()");
}
return currentMessageAsString;
}
currentMessageAsBytes = (byte[])currentMessage;
try
{
setCurrentForm(new String((byte[])currentMessage, "UTF-8"), FORM_STRING);
}
catch (UnsupportedEncodingException ue)
{
setCurrentForm(new String((byte[])currentMessage), FORM_STRING);
}
currentMessageAsString = (String)currentMessage;
if (log.isDebugEnabled())
{
log.debug("Exit: SOAPPart::getAsString()");
}
return (String)currentMessage;
}
if (currentForm == FORM_FAULT)
{
StringWriter writer = new StringWriter();
try
{
this.writeTo(writer);
}
catch (Exception e)
{
log.error(Messages.getMessage("exception00"), e);
return null;
}
setCurrentForm(writer.getBuffer().toString(), FORM_STRING);
if (log.isDebugEnabled())
{
log.debug("Exit: SOAPPart::getAsString(): " + currentMessage);
}
return (String)currentMessage;
}
if (currentForm == FORM_SOAPENVELOPE)
{
StringWriter writer = new StringWriter();
try
{
writeTo(writer);
}
catch (Exception e)
{
throw AxisFault.makeFault(e);
}
String msgAsString = writer.getBuffer().toString();
setCurrentForm(msgAsString, FORM_STRING);
if (log.isDebugEnabled())
{
log.debug("Exit: SOAPPart::getAsString()");
}
return msgAsString;
}
log.error(Messages.getMessage("cantConvert01", "" + currentForm));
log.debug("Exit: SOAPPart::getAsString()");
return null;
}
public SOAPEnvelopeAxisImpl getAsSOAPEnvelope() throws AxisFault
{
if (log.isDebugEnabled())
{
log.debug("Enter: SOAPPart::getAsSOAPEnvelope()");
log.debug(Messages.getMessage("currForm", formNames[currentForm]));
}
if (currentForm == FORM_SOAPENVELOPE)
{
SOAPEnvelopeAxisImpl env = (SOAPEnvelopeAxisImpl)currentMessage;
return env;
}
if (currentForm == FORM_BODYINSTREAM)
{
InputStreamBody bodyEl = new InputStreamBody((InputStream)currentMessage);
SOAPEnvelopeAxisImpl env = new SOAPEnvelopeAxisImpl();
env.addBodyElement(bodyEl);
setCurrentForm(env, FORM_SOAPENVELOPE);
return env;
}
InputSource is;
if (currentForm == FORM_INPUTSTREAM)
{
is = new InputSource((InputStream)currentMessage);
String encoding = null;
if (msgObject != null)
{
try
{
encoding = (String)msgObject.getProperty(SOAPMessage.CHARACTER_SET_ENCODING);
}
catch (SOAPException e)
{
}
}
if (encoding != null)
{
is.setEncoding(encoding);
}
}
else if (currentForm == FORM_BYTES)
{
is = new InputSource(new ByteArrayInputStream((byte[])currentMessage));
}
else
{
is = new InputSource(new StringReader(getAsString()));
}
DeserializationContext dser = new DeserializationContextImpl(is,
getMessage().getMessageContext(),
getMessage().getMessageType());
try
{
dser.parse();
}
catch (SAXException e)
{
Exception real = e.getException();
if (real == null)
real = e;
throw AxisFault.makeFault(real);
}
SOAPEnvelopeAxisImpl env = dser.getEnvelope();
if (currentMessageAsEnvelope != null)
{
checkMustUnderstand(getMessage().getMessageContext(), env);
Vector newHeaders = env.getHeaders();
Vector oldHeaders = currentMessageAsEnvelope.getHeaders();
if (null != newHeaders && null != oldHeaders)
{
Iterator ohi = oldHeaders.iterator();
Iterator nhi = newHeaders.iterator();
while (ohi.hasNext() && nhi.hasNext())
{
SOAPHeaderElementAxisImpl nhe = (SOAPHeaderElementAxisImpl)nhi.next();
SOAPHeaderElementAxisImpl ohe = (SOAPHeaderElementAxisImpl)ohi.next();
if (ohe.isProcessed()) nhe.setProcessed(true);
}
}
}
((SOAPBodyAxisImpl)env.getBody()).setAllImmutable(true);
setCurrentForm(env, FORM_SOAPENVELOPE);
log.debug("Exit: SOAPPart::getAsSOAPEnvelope");
return (SOAPEnvelopeAxisImpl)currentMessage;
}
private void checkMustUnderstand(MessageContext msgContext, SOAPEnvelopeAxisImpl envelope) throws AxisFault
{
String svcActor = "";
Vector headers = null; try
{
headers = envelope.getHeaders();
}
catch (AxisFault axisFault)
{
axisFault.printStackTrace(); }
Vector misunderstoodHeaders = null;
Enumeration en = headers.elements();
while (en.hasMoreElements())
{
SOAPHeaderElementAxisImpl header = (SOAPHeaderElementAxisImpl)en.
nextElement();
if (header.getActor() != null && header.getMustUnderstand() &&
header.getActor() != svcActor)
{
if (misunderstoodHeaders == null)
misunderstoodHeaders = new Vector();
misunderstoodHeaders.addElement(header);
}
}
SOAPConstants soapConstants = msgContext.getSOAPConstants();
if (misunderstoodHeaders != null)
{
AxisFault fault =
new AxisFault(soapConstants.getMustunderstandFaultQName(),
null, null,
null, null,
null);
StringBuffer whatWasMissUnderstood = new StringBuffer(256);
if (soapConstants == SOAPConstants.SOAP12_CONSTANTS)
{
en = misunderstoodHeaders.elements();
while (en.hasMoreElements())
{
SOAPHeaderElementAxisImpl badHeader = (SOAPHeaderElementAxisImpl)en.
nextElement();
QName badQName = new QName(badHeader.getNamespaceURI(),
badHeader.getName());
if (whatWasMissUnderstood.length() != 0) whatWasMissUnderstood.append(", ");
whatWasMissUnderstood.append(badQName.toString());
SOAPHeaderElementAxisImpl newHeader = new
SOAPHeaderElementAxisImpl(Constants.URI_SOAP12_ENV,
Constants.ELEM_NOTUNDERSTOOD);
newHeader.addAttribute(null,
Constants.ATTR_QNAME,
badQName);
fault.addHeader(newHeader);
}
}
fault.setFaultString(Messages.getMessage("noUnderstand00",
whatWasMissUnderstood.toString()));
throw fault;
}
}
public void addMimeHeader(String header, String value)
{
mimeHeaders.addHeader(header, value);
}
private String getFirstMimeHeader(String header)
{
String[] values = mimeHeaders.getHeader(header);
if (values != null && values.length > 0)
return values[0];
return null;
}
public String getContentLocation()
{
return getFirstMimeHeader(HTTPConstants.HEADER_CONTENT_LOCATION);
}
public void setContentLocation(String loc)
{
setMimeHeader(HTTPConstants.HEADER_CONTENT_LOCATION, loc);
}
public void setContentId(String newCid)
{
setMimeHeader(HTTPConstants.HEADER_CONTENT_ID, newCid);
}
public String getContentId()
{
return getFirstMimeHeader(HTTPConstants.HEADER_CONTENT_ID);
}
public String getContentIdRef()
{
return org.jboss.axis.attachments.Attachments.CIDprefix +
getContentId();
}
public java.util.Iterator getMatchingMimeHeaders(final String[] match)
{
return mimeHeaders.getMatchingHeaders(match);
}
public java.util.Iterator getNonMatchingMimeHeaders(final String[] match)
{
return mimeHeaders.getNonMatchingHeaders(match);
}
public void setContent(Source source) throws SOAPException
{
if (source == null)
throw new SOAPException(Messages.getMessage("illegalArgumentException00"));
contentSource = source;
InputSource in = org.jboss.axis.utils.XMLUtils.sourceToInputSource(contentSource);
InputStream is = in.getByteStream();
if (is != null)
{
setCurrentMessage(is, FORM_INPUTSTREAM);
}
else
{
Reader r = in.getCharacterStream();
if (r == null)
{
throw new SOAPException(Messages.getMessage("noCharacterOrByteStream"));
}
BufferedReader br = new BufferedReader(r);
String line = null;
StringBuffer sb = new StringBuffer();
try
{
while ((line = br.readLine()) != null)
{
sb.append(line);
}
}
catch (IOException e)
{
throw new SOAPException(Messages.getMessage("couldNotReadFromCharStream"), e);
}
setCurrentMessage(sb.toString(), FORM_STRING);
}
}
public Source getContent() throws SOAPException
{
if (contentSource == null)
{
switch (currentForm)
{
case FORM_STRING:
String s = (String)currentMessage;
contentSource = new StreamSource(new StringReader(s));
break;
case FORM_INPUTSTREAM:
contentSource = new StreamSource((InputStream)currentMessage);
break;
case FORM_SOAPENVELOPE:
SOAPEnvelopeAxisImpl se = (SOAPEnvelopeAxisImpl)currentMessage;
try
{
contentSource = new DOMSource(se.getAsDocument());
}
catch (Exception e)
{
throw new SOAPException(Messages.getMessage("errorGetDocFromSOAPEnvelope"), e);
}
break;
case FORM_BYTES:
byte[] bytes = (byte[])currentMessage;
contentSource = new StreamSource(new ByteArrayInputStream(bytes));
break;
case FORM_BODYINSTREAM:
contentSource = new StreamSource((InputStream)currentMessage);
break;
}
}
return contentSource;
}
public Iterator getAllMimeHeaders()
{
return mimeHeaders.getAllHeaders();
}
public void setMimeHeader(String name, String value)
{
mimeHeaders.setHeader(name, value);
}
public String[] getMimeHeader(String name)
{
return mimeHeaders.getHeader(name);
}
public void removeAllMimeHeaders()
{
mimeHeaders.removeAllHeaders();
}
public void removeMimeHeader(String header)
{
mimeHeaders.removeHeader(header);
}
public javax.xml.soap.SOAPEnvelope getEnvelope() throws SOAPException
{
try
{
return getAsSOAPEnvelope();
}
catch (AxisFault af)
{
throw new SOAPException(af);
}
}
private Document document = new SOAPDocumentImpl(this);
public Document getSOAPDocument()
{
if (document == null)
{
document = new SOAPDocumentImpl(this);
}
return document;
}
public DocumentType getDoctype()
{
return document.getDoctype();
}
public DOMImplementation getImplementation()
{
return document.getImplementation();
}
protected Document mDocument;
public Element getDocumentElement()
{
try
{
return getEnvelope();
}
catch (SOAPException se)
{
return null;
}
}
public Element createElement(String tagName) throws DOMException
{
return document.createElement(tagName);
}
public DocumentFragment createDocumentFragment()
{
return document.createDocumentFragment();
}
public Text createTextNode(String data)
{
return document.createTextNode(data);
}
public Comment createComment(String data)
{
return document.createComment(data);
}
public CDATASection createCDATASection(String data) throws DOMException
{
return document.createCDATASection(data);
}
public ProcessingInstruction createProcessingInstruction(String target, String data)
throws DOMException
{
return document.createProcessingInstruction(target, data);
}
public Attr createAttribute(String name) throws DOMException
{
return document.createAttribute(name);
}
public EntityReference createEntityReference(String name) throws DOMException
{
return document.createEntityReference(name);
}
public NodeList getElementsByTagName(String tagname)
{
return document.getElementsByTagName(tagname);
}
public Node importNode(Node importedNode, boolean deep)
throws DOMException
{
return document.importNode(importedNode, deep);
}
public Element createElementNS(String namespaceURI, String qualifiedName)
throws DOMException
{
return document.createElementNS(namespaceURI, qualifiedName);
}
public Attr createAttributeNS(String namespaceURI, String qualifiedName)
throws DOMException
{
return document.createAttributeNS(namespaceURI, qualifiedName);
}
public NodeList getElementsByTagNameNS(String namespaceURI, String localName)
{
return document.getElementsByTagNameNS(namespaceURI, localName);
}
public Element getElementById(String elementId)
{
return document.getElementById(elementId);
}
public String getEncoding()
{
throw new UnsupportedOperationException("Not yet implemented.69");
}
public void setEncoding(String s)
{
throw new UnsupportedOperationException("Not yet implemented.70");
}
public boolean getStandalone()
{
throw new UnsupportedOperationException("Not yet implemented.71");
}
public void setStandalone(boolean flag)
{
throw new UnsupportedOperationException("Not yet implemented.72");
}
public boolean getStrictErrorChecking()
{
throw new UnsupportedOperationException("Not yet implemented.73");
}
public void setStrictErrorChecking(boolean flag)
{
throw new UnsupportedOperationException("Not yet implemented. 74");
}
public String getVersion()
{
throw new UnsupportedOperationException("Not yet implemented. 75");
}
public void setVersion(String s)
{
throw new UnsupportedOperationException("Not yet implemented.76");
}
public Node adoptNode(Node node)
throws DOMException
{
throw new UnsupportedOperationException("Not yet implemented.77");
}
public String getNodeName()
{
return document.getNodeName();
}
public String getNodeValue() throws DOMException
{
return document.getNodeValue();
}
public void setNodeValue(String nodeValue) throws DOMException
{
document.setNodeValue(nodeValue);
}
public short getNodeType()
{
return document.getNodeType();
}
public Node getParentNode()
{
return document.getParentNode();
}
public NodeList getChildNodes()
{
return document.getChildNodes();
}
public Node getFirstChild()
{
return document.getFirstChild();
}
public Node getLastChild()
{
return document.getLastChild();
}
public Node getPreviousSibling()
{
return document.getPreviousSibling();
}
public Node getNextSibling()
{
return document.getNextSibling();
}
public NamedNodeMap getAttributes()
{
return document.getAttributes();
}
public Document getOwnerDocument()
{
return document.getOwnerDocument();
}
public Node insertBefore(Node newChild, Node refChild) throws DOMException
{
return document.insertBefore(newChild, refChild);
}
public Node replaceChild(Node newChild, Node oldChild) throws DOMException
{
return document.replaceChild(newChild, oldChild);
}
public Node removeChild(Node oldChild) throws DOMException
{
return document.removeChild(oldChild);
}
public Node appendChild(Node newChild) throws DOMException
{
return document.appendChild(newChild);
}
public boolean hasChildNodes()
{
return document.hasChildNodes();
}
public Node cloneNode(boolean deep)
{
return document.cloneNode(deep);
}
public void normalize()
{
document.normalize();
}
public boolean isSupported(String feature, String version)
{
return document.isSupported(feature, version);
}
public String getNamespaceURI()
{
return document.getNamespaceURI();
}
public String getPrefix()
{
return document.getPrefix();
}
public void setPrefix(String prefix) throws DOMException
{
document.setPrefix(prefix);
}
public String getLocalName()
{
return document.getLocalName();
}
public boolean hasAttributes()
{
return document.hasAttributes();
}
}