blob: a983f36c9dbb07a858220b1a343a55a8f4559181 [file] [log] [blame]
/*
* Copyright 2001-2004 The Apache Software Foundation.
*
* Licensed 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.axis ;
import org.apache.axis.components.logger.LogFactory;
import org.apache.axis.encoding.DeserializationContext;
import org.apache.axis.encoding.SerializationContext;
import org.apache.axis.message.InputStreamBody;
import org.apache.axis.message.MimeHeaders;
import org.apache.axis.message.SOAPDocumentImpl;
import org.apache.axis.message.SOAPEnvelope;
import org.apache.axis.message.SOAPHeaderElement;
import org.apache.axis.transport.http.HTTPConstants;
import org.apache.axis.utils.ByteArray;
import org.apache.axis.utils.Messages;
import org.apache.axis.utils.SessionUtils;
import org.apache.axis.utils.XMLUtils;
import org.apache.axis.handlers.HandlerChainImpl;
import org.apache.commons.logging.Log;
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.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.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.Iterator;
import java.util.Vector;
/**
* The SOAPPart provides access to the root part of the Message which
* contains the envelope.
* <p>
* SOAPPart implements Part, providing common MIME operations.
* <p>
* SOAPPart also allows access to its envelope,
* as a string, byte[], InputStream, or SOAPEnvelope. (This functionality
* used to be in Message, and has been moved here more or less verbatim
* pending further cleanup.)
*
* @author Rob Jellinghaus (robj@unrealities.com)
* @author Doug Davis (dug@us.ibm.com)
* @author Glen Daniels (gdaniels@allaire.com)
* @author Heejune Ahn (cityboy@tmax.co.kr)
*/
public class SOAPPart extends javax.xml.soap.SOAPPart implements Part
{
protected static Log log =
LogFactory.getLog(SOAPPart.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;
public static final int FORM_OPTIMIZED = 7;
private int currentForm;
/**
* property used to set SOAPEnvelope as default form
*/
public static final String ALLOW_FORM_OPTIMIZATION = "axis.form.optimization";
//private Hashtable headers = new Hashtable();
private MimeHeaders mimeHeaders = new MimeHeaders();
private static final String[] formNames =
{ "", "FORM_STRING", "FORM_INPUTSTREAM", "FORM_SOAPENVELOPE",
"FORM_BYTES", "FORM_BODYINSTREAM", "FORM_FAULT", "FORM_OPTIMIZED" };
/**
* The current representation of the SOAP contents of this part.
* May be a String, byte[], InputStream, or SOAPEnvelope, depending
* on whatever was last asked for. (ack)
* <p>
* currentForm must have the corresponding value.
* <p>
* As someone once said: "Just a placeholder until we figure out what the actual Message
* object is."
*/
private Object currentMessage ;
/**
* default message encoding charset
*/
private String currentEncoding = "UTF-8";
// These two fields are used for caching in getAsString and getAsBytes
private String currentMessageAsString = null;
private byte[] currentMessageAsBytes = null;
private org.apache.axis.message.SOAPEnvelope currentMessageAsEnvelope= null;
/**
* Message object this part is tied to. Used for serialization settings.
*/
private Message msgObject;
/** Field contentSource. */
private Source contentSource = null;
/**
* The original message. Again, may be String, byte[], InputStream,
* or SOAPEnvelope.
*/
// private Object originalMessage ; //free up reference this is not in use.
/**
* Create a new SOAPPart.
* <p>
* Do not call this directly! Should only be called by Message.
*
* @param parent the parent <code>Message</code>
* @param initialContents the initial contens <code>Object</code>
* @param isBodyStream if the body is in a stream
*/
public SOAPPart(Message parent, Object initialContents, boolean isBodyStream) {
setMimeHeader(HTTPConstants.HEADER_CONTENT_ID , SessionUtils.generateSessionId());
setMimeHeader(HTTPConstants.HEADER_CONTENT_TYPE , "text/xml");
msgObject=parent;
// originalMessage = initialContents;
int form = FORM_STRING;
if (initialContents instanceof SOAPEnvelope) {
form = FORM_SOAPENVELOPE;
((SOAPEnvelope)initialContents).setOwnerDocument(this);
} 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()");
}
}
/**
* Get the <code>Message</code> for this <code>Part</code>.
*
* @return the <code>Message</code> for this <code>Part</code>
*/
public Message getMessage(){
return msgObject;
}
/**
* Set the Message for this Part.
* Do not call this Directly. Called by Message.
*
* @param msg the <code>Message</code> for this part
*/
public void setMessage (Message msg) {
this.msgObject= msg;
}
/**
* Content type is always "text/xml" for SOAPParts.
*
* @return the content type
*/
public String getContentType() {
return "text/xml";
}
/**
* Get the content length for this SOAPPart.
* This will force buffering of the SOAPPart, but it will
* also cache the byte[] form of the SOAPPart.
*
* @return the content length in bytes
*/
public long getContentLength() throws AxisFault {
saveChanges();
if (currentForm == FORM_OPTIMIZED) {
return ((ByteArray) currentMessage).size();
} else if (currentForm == FORM_BYTES) {
return ((byte[]) currentMessage).length;
}
byte[] bytes = this.getAsBytes();
return bytes.length;
}
/**
* This set the SOAP Envelope for this part.
* <p>
* Note: It breaks the chicken/egg created.
* I need a message to create an attachment...
* From the attachment I should be able to get a reference...
* I now want to edit elements in the envelope in order to
* place the attachment reference to it.
* How do I now update the SOAP envelope with what I've changed?
*
* @param env the <code>SOAPEnvelope</CODE> for this <code>SOAPPart</code>
*/
public void setSOAPEnvelope(org.apache.axis.message.SOAPEnvelope env){
setCurrentMessage(env, FORM_SOAPENVELOPE) ;
}
/**
* Write the contents to the specified stream.
*
* @param os the <code>java.io.OutputStream</code> to write to
*/
public void writeTo(java.io.OutputStream os) throws IOException {
if ( currentForm == FORM_BYTES ) {
os.write((byte[])currentMessage);
} else if ( currentForm == FORM_OPTIMIZED ) {
((ByteArray) currentMessage).writeTo(os);
} else {
Writer writer = new OutputStreamWriter(os, currentEncoding);
writer = new BufferedWriter(new PrintWriter(writer));
writeTo(writer);
writer.flush();
}
}
/**
* Write the contents to the specified writer.
*
* @param writer the <code>Writer</code> to write to
*/
public void writeTo(Writer writer) throws IOException {
boolean inclXmlDecl = false;
if (msgObject.getMessageContext() != null) { // if we have message context (JAX-RPC), write xml decl always.
inclXmlDecl = true;
} else { // if we have no message context (SAAJ), write xml decl according to property.
try {
String xmlDecl = (String)msgObject.getProperty(SOAPMessage.WRITE_XML_DECLARATION);
if (xmlDecl != null && xmlDecl.equals("true")) {
inclXmlDecl = true;
}
} catch (SOAPException e) {
throw new IOException(e.getMessage());
}
}
if ( currentForm == FORM_FAULT ) {
AxisFault env = (AxisFault)currentMessage;
try {
SerializationContext serContext = new SerializationContext(writer, getMessage().getMessageContext());
serContext.setSendDecl(inclXmlDecl);
serContext.setEncoding(currentEncoding);
env.output(serContext);
} catch (Exception e) {
log.error(Messages.getMessage("exception00"), e);
throw env;
}
return;
}
if ( currentForm == FORM_SOAPENVELOPE ) {
SOAPEnvelope env = (SOAPEnvelope)currentMessage;
try {
SerializationContext serContext = new SerializationContext(writer, getMessage().getMessageContext());
serContext.setSendDecl(inclXmlDecl);
serContext.setEncoding(currentEncoding);
env.output(serContext);
} catch (Exception e) {
throw AxisFault.makeFault(e);
}
return;
}
String xml = this.getAsString();
if(inclXmlDecl){
if(!xml.startsWith("<?xml")){
writer.write("<?xml version=\"1.0\" encoding=\"");
writer.write(currentEncoding);
writer.write("\"?>");
}
}
writer.write(xml);
}
/**
* Get the current message, in whatever form it happens to be right now.
* Will return a String, byte[], InputStream, or SOAPEnvelope, depending
* on circumstances.
* <p>
* The method name is historical.
* TODO: rename this for clarity; should be more like getContents.
*
* @return the current content
*/
public Object getCurrentMessage() {
return currentMessage;
}
/**
* Set the current message
* @param currMsg
* @param form
*/
public void setCurrentMessage(Object currMsg, int form) {
currentMessageAsString = null; //Get rid of any cached stuff this is new.
currentMessageAsBytes = null;
currentMessageAsEnvelope= null;
setCurrentForm(currMsg, form);
}
/**
* Set the current contents of this Part.
* The method name is historical.
* TODO: rename this for clarity to something more like setContents???
*
* @param currMsg the new content of this part
* @param form the form of the message
*/
private void setCurrentForm(Object currMsg, int form) {
if (log.isDebugEnabled()) {
String msgStr;
if (currMsg instanceof String) {
msgStr = (String)currMsg;
} else {
msgStr = currMsg.getClass().getName();
}
log.debug(Messages.getMessage("setMsgForm", formNames[form],
"" + msgStr));
}
// only change form if allowed
if (isFormOptimizationAllowed()) {
currentMessage = currMsg;
currentForm = form;
if (currentForm == FORM_SOAPENVELOPE) {
currentMessageAsEnvelope = (org.apache.axis.message.SOAPEnvelope) currMsg;
}
}
}
/**
* check if the allow optimization flag is on
* @return form optimization flag
*/
private boolean isFormOptimizationAllowed() {
boolean allowFormOptimization = true;
Message msg = getMessage();
if (msg != null) {
MessageContext ctx = msg.getMessageContext();
if (ctx != null) {
Boolean propFormOptimization = (Boolean)ctx.getProperty(ALLOW_FORM_OPTIMIZATION);
if (propFormOptimization != null) {
allowFormOptimization = propFormOptimization.booleanValue();
}
}
}
return allowFormOptimization;
}
public int getCurrentForm() {
return currentForm;
}
/**
* Get the contents of this Part (not the headers!), as a byte
* array. This will force buffering of the message.
*
* @return an array of bytes containing a byte representation of this Part
* @throws AxisFault if this Part can't be serialized to the byte array
*/
public byte[] getAsBytes() throws AxisFault {
log.debug("Enter: SOAPPart::getAsBytes");
if ( currentForm == FORM_OPTIMIZED ) {
log.debug("Exit: SOAPPart::getAsBytes");
try {
return ((ByteArray) currentMessage).toByteArray();
} catch (IOException e) {
throw AxisFault.makeFault(e);
}
}
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 ) {
// Assumes we don't need a content length
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.apache.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 ){
currentEncoding = XMLUtils.getEncoding(msgObject, null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BufferedOutputStream os = new BufferedOutputStream(baos);
try {
this.writeTo(os);
os.flush();
} catch (Exception e) {
throw AxisFault.makeFault(e);
}
setCurrentForm(baos.toByteArray(), FORM_BYTES);
if (log.isDebugEnabled()) {
log.debug("Exit: SOAPPart::getAsBytes(): " + currentMessage);
}
return (byte[]) currentMessage;
}
if ( currentForm == FORM_STRING ) {
// If the current message was already converted from
// a byte[] to String, return the byte[] representation
// (this is done to avoid unnecessary conversions)
if (currentMessage == currentMessageAsString &&
currentMessageAsBytes != null) {
if (log.isDebugEnabled()) {
log.debug("Exit: SOAPPart::getAsBytes()");
}
return currentMessageAsBytes;
}
// Save this message in case it is requested later in getAsString
currentMessageAsString = (String) currentMessage;
try{
currentEncoding = XMLUtils.getEncoding(msgObject, null);
setCurrentForm( ((String)currentMessage).getBytes(currentEncoding),
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 void saveChanges() throws AxisFault {
log.debug("Enter: SOAPPart::saveChanges");
if ( currentForm == FORM_SOAPENVELOPE ||
currentForm == FORM_FAULT ){
currentEncoding = XMLUtils.getEncoding(msgObject, null);
ByteArray array = new ByteArray();
try {
writeTo(array);
array.flush();
} catch (Exception e) {
throw AxisFault.makeFault(e);
}
setCurrentForm( array, FORM_OPTIMIZED );
if (log.isDebugEnabled()) {
log.debug("Exit: SOAPPart::saveChanges(): " + currentMessage);
}
}
}
/**
* Get the contents of this Part (not the headers!), as a String.
* This will force buffering of the message.
*
* @return a <code>String</code> containing the content of this message
* @throws AxisFault if there is an error serializing this part
*/
public String getAsString() throws AxisFault {
log.debug("Enter: SOAPPart::getAsString");
if ( currentForm == FORM_STRING ) {
if (log.isDebugEnabled()) {
log.debug("Exit: SOAPPart::getAsString(): " + currentMessage);
}
return (String)currentMessage;
}
if ( currentForm == FORM_INPUTSTREAM ||
currentForm == FORM_BODYINSTREAM ) {
getAsBytes();
// Fall thru to "Bytes"
}
if ( currentForm == FORM_OPTIMIZED) {
try {
currentMessageAsBytes =
((ByteArray) currentMessage).toByteArray();
} catch (IOException e) {
throw AxisFault.makeFault(e);
}
try{
setCurrentForm(new String((byte[])currentMessageAsBytes,
currentEncoding),
FORM_STRING);
}catch(UnsupportedEncodingException ue){
setCurrentForm( new String((byte[]) currentMessageAsBytes),
FORM_STRING );
}
if (log.isDebugEnabled()) {
log.debug("Exit: SOAPPart::getAsString(): " + currentMessage);
}
return (String)currentMessage;
}
if ( currentForm == FORM_BYTES ) {
// If the current message was already converted from
// a String to byte[], return the String representation
// (this is done to avoid unnecessary conversions)
if (currentMessage == currentMessageAsBytes &&
currentMessageAsString != null) {
if (log.isDebugEnabled()) {
log.debug("Exit: SOAPPart::getAsString(): " + currentMessageAsString);
}
return currentMessageAsString;
}
// Save this message in case it is requested later in getAsBytes
currentMessageAsBytes = (byte[]) currentMessage;
try{
setCurrentForm(new String((byte[])currentMessage,
currentEncoding),
FORM_STRING);
}catch(UnsupportedEncodingException ue){
setCurrentForm( new String((byte[]) currentMessage),
FORM_STRING );
}
currentMessageAsString = (String) currentMessage;
if (log.isDebugEnabled()) {
log.debug("Exit: SOAPPart::getAsString(): " + currentMessage);
}
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 {
this.writeTo(writer);
} catch (Exception e) {
throw AxisFault.makeFault(e);
}
setCurrentForm(writer.getBuffer().toString(), FORM_STRING);
if (log.isDebugEnabled()) {
log.debug("Exit: SOAPPart::getAsString(): " + currentMessage);
}
return (String)currentMessage;
}
log.error( Messages.getMessage("cantConvert01", ""+currentForm));
log.debug("Exit: SOAPPart::getAsString()");
return null;
}
/**
* Get the contents of this Part (not the MIME headers!), as a
* SOAPEnvelope. This will force a complete parse of the
* message.
*
* @return a <code>SOAPEnvelope</code> containing the message content
* @throws AxisFault if the envelope could not be constructed
*/
public SOAPEnvelope getAsSOAPEnvelope()
throws AxisFault
{
if (log.isDebugEnabled()) {
log.debug("Enter: SOAPPart::getAsSOAPEnvelope()");
log.debug(Messages.getMessage("currForm", formNames[currentForm]));
}
if ( currentForm == FORM_SOAPENVELOPE )
return (SOAPEnvelope)currentMessage;
if (currentForm == FORM_BODYINSTREAM) {
InputStreamBody bodyEl =
new InputStreamBody((InputStream)currentMessage);
SOAPEnvelope env = new SOAPEnvelope();
env.setOwnerDocument(this);
env.addBodyElement(bodyEl);
setCurrentForm(env, FORM_SOAPENVELOPE);
return env;
}
InputSource is;
if ( currentForm == FORM_INPUTSTREAM ) {
is = new InputSource( (InputStream) currentMessage );
String encoding = XMLUtils.getEncoding(msgObject, null, null);
if (encoding != null) {
currentEncoding = encoding;
is.setEncoding(currentEncoding);
}
} else {
is = new InputSource(new StringReader(getAsString()));
}
DeserializationContext dser = new DeserializationContext(is,
getMessage().getMessageContext(),
getMessage().getMessageType());
dser.getEnvelope().setOwnerDocument(this);
// This may throw a SAXException
try {
dser.parse();
} catch (SAXException e) {
Exception real = e.getException();
if (real == null)
real = e;
throw AxisFault.makeFault(real);
}
SOAPEnvelope nse= dser.getEnvelope();
if(currentMessageAsEnvelope != null){
//Need to synchronize back processed header info.
Vector newHeaders= nse.getHeaders();
Vector oldHeaders= currentMessageAsEnvelope.getHeaders();
if( null != newHeaders && null != oldHeaders){
Iterator ohi= oldHeaders.iterator();
Iterator nhi= newHeaders.iterator();
while( ohi.hasNext() && nhi.hasNext()){
SOAPHeaderElement nhe= (SOAPHeaderElement)nhi.next();
SOAPHeaderElement ohe= (SOAPHeaderElement)ohi.next();
if(ohe.isProcessed()) nhe.setProcessed(true);
}
}
}
setCurrentForm(nse, FORM_SOAPENVELOPE);
log.debug("Exit: SOAPPart::getAsSOAPEnvelope");
SOAPEnvelope env = (SOAPEnvelope)currentMessage;
env.setOwnerDocument(this);
return env;
}
/**
* Add the specified MIME header, as per JAXM.
*
* @param header the header to add
* @param value the value of that header
*/
public void addMimeHeader (String header, String value) {
mimeHeaders.addHeader(header, value);
}
/**
* Get the specified MIME header.
*
* @param header the name of a MIME header
* @return the value of the first header named <code>header</code>
*/
private String getFirstMimeHeader (String header) {
String[] values = mimeHeaders.getHeader(header);
if(values != null && values.length>0)
return values[0];
return null;
}
/**
* Total size in bytes (of all content and headers, as encoded).
public abstract int getSize();
*/
/**
* Content location.
*
* @return the content location
*/
public String getContentLocation() {
return getFirstMimeHeader(HTTPConstants.HEADER_CONTENT_LOCATION);
}
/**
* Set content location.
*
* @param loc the content location
*/
public void setContentLocation(String loc) {
setMimeHeader(HTTPConstants.HEADER_CONTENT_LOCATION, loc);
}
/**
* Sets Content-Id of this part.
* already defined.
* @param newCid new Content-Id
*/
public void setContentId(String newCid){
setMimeHeader(HTTPConstants.HEADER_CONTENT_ID,newCid);
}
/**
* Content ID.
*
* @return the content ID
*/
public String getContentId() {
return getFirstMimeHeader(HTTPConstants.HEADER_CONTENT_ID);
}
/**
* Content ID.
*
* @return the contentId reference value that should be used directly
* as an href in a SOAP element to reference this attachment.
* <B>Not part of JAX-RPC, JAX-M, SAAJ, etc. </B>
*/
public String getContentIdRef() {
return org.apache.axis.attachments.Attachments.CIDprefix +
getContentId();
}
/**
* Get all headers that match.
*
* @param match an array of <code>String</code>s giving mime header names
* @return an <code>Iterator</code> over all values matching these headers
*/
public java.util.Iterator getMatchingMimeHeaders( final String[] match){
return mimeHeaders.getMatchingHeaders(match);
}
/**
* Get all headers that do not match.
*
* @param match an array of <code>String</code>s giving mime header names
* @return an <code>Iterator</code> over all values not matching these
* headers
*/
public java.util.Iterator getNonMatchingMimeHeaders( final String[] match){
return mimeHeaders.getNonMatchingHeaders(match);
}
/**
* Sets the content of the <CODE>SOAPEnvelope</CODE> object
* with the data from the given <CODE>Source</CODE> object.
* @param source <CODE>javax.xml.transform.Source</CODE> object with the data to
* be set
* @throws SOAPException if there is a problem in
* setting the source
* @see #getContent() getContent()
*/
public void setContent(Source source) throws SOAPException {
if(source == null)
throw new SOAPException(Messages.getMessage("illegalArgumentException00"));
// override the checks in HandlerChainImpl for JAXRPCHandler kludge
MessageContext ctx = getMessage().getMessageContext();
if (ctx != null) {
ctx.setProperty(org.apache.axis.SOAPPart.ALLOW_FORM_OPTIMIZATION,
Boolean.TRUE);
}
contentSource = source;
InputSource in = org.apache.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);
}
}
/**
* Returns the content of the SOAPEnvelope as a JAXP <CODE>
* Source</CODE> object.
* @return the content as a <CODE>
* javax.xml.transform.Source</CODE> object
* @throws SOAPException if the implementation cannot
* convert the specified <CODE>Source</CODE> object
* @see #setContent(javax.xml.transform.Source) setContent(javax.xml.transform.Source)
*/
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:
SOAPEnvelope se = (SOAPEnvelope) currentMessage;
try {
contentSource = new DOMSource(se.getAsDocument());
} catch (Exception e) {
throw new SOAPException(Messages.getMessage("errorGetDocFromSOAPEnvelope"),
e);
}
break;
case FORM_OPTIMIZED:
try {
ByteArrayInputStream baos = new ByteArrayInputStream(((ByteArray) currentMessage).toByteArray());
contentSource = new StreamSource(baos);
} catch (IOException 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;
}
/**
* Retrieves all the headers for this <CODE>SOAPPart</CODE>
* object as an iterator over the <CODE>MimeHeader</CODE>
* objects.
* @return an <CODE>Iterator</CODE> object with all of the Mime
* headers for this <CODE>SOAPPart</CODE> object
*/
public Iterator getAllMimeHeaders() {
return mimeHeaders.getAllHeaders();
}
/**
* 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.
*
* <P>Note that RFC822 headers can contain only US-ASCII
* characters.</P>
* @param name a <CODE>String</CODE> giving the
* header name for which to search
* @param value a <CODE>String</CODE> 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 <CODE>MimeHeader</CODE> object.
* @throws java.lang.IllegalArgumentException if
* there was a problem with the specified mime header name
* or value
* @see #getMimeHeader(java.lang.String) getMimeHeader(java.lang.String)
*/
public void setMimeHeader(String name, String value) {
mimeHeaders.setHeader(name,value);
}
/**
* Gets all the values of the <CODE>MimeHeader</CODE> object
* in this <CODE>SOAPPart</CODE> object that is identified by
* the given <CODE>String</CODE>.
* @param name the name of the header; example:
* "Content-Type"
* @return a <CODE>String</CODE> array giving all the values for
* the specified header
* @see #setMimeHeader(java.lang.String, java.lang.String) setMimeHeader(java.lang.String, java.lang.String)
*/
public String[] getMimeHeader(String name) {
return mimeHeaders.getHeader(name);
}
/**
* Removes all the <CODE>MimeHeader</CODE> objects for this
* <CODE>SOAPEnvelope</CODE> object.
*/
public void removeAllMimeHeaders() {
mimeHeaders.removeAllHeaders();
}
/**
* Removes all MIME headers that match the given name.
* @param header a <CODE>String</CODE> giving
* the name of the MIME header(s) to be removed
*/
public void removeMimeHeader(String header) {
mimeHeaders.removeHeader(header);
}
/**
* Gets the <CODE>SOAPEnvelope</CODE> object associated with
* this <CODE>SOAPPart</CODE> object. Once the SOAP envelope is
* obtained, it can be used to get its contents.
* @return the <CODE>SOAPEnvelope</CODE> object for this <CODE>
* SOAPPart</CODE> object
* @throws SOAPException if there is a SOAP error
*/
public javax.xml.soap.SOAPEnvelope getEnvelope() throws SOAPException {
try {
return getAsSOAPEnvelope();
} catch (AxisFault af) {
throw new SOAPException(af);
}
}
/**
* Implementation of org.w3c.Document
* Most of methods will be implemented using the delgate
* instance of SOAPDocumentImpl
* This is for two reasons:
* - possible change of message classes, by extenstion of xerces implementation
* - we cannot extends SOAPPart (multiple inheritance),
* since it is defined as Abstract class
* ***********************************************************
*/
private Document document = new SOAPDocumentImpl(this);
/**
* @since SAAJ 1.2
*/
public Document getSOAPDocument(){
if(document == null){
document = new SOAPDocumentImpl(this);
}
return document;
}
/**
* @return
*/
public DocumentType getDoctype(){
return document.getDoctype();
}
/**
* @return
*/
public DOMImplementation getImplementation(){
return document.getImplementation();
}
/**
* SOAPEnvelope is the Document Elements of this XML docuement
*/
protected Document mDocument;
public Element getDocumentElement()
{
try{
return getEnvelope();
}catch(SOAPException se){
return null;
}
}
/**
*
* @param tagName
* @return
* @throws DOMException
*/
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()
{
return currentEncoding;
}
public void setEncoding(String s)
{
currentEncoding = s;
}
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");
}
/**
* Node Implementation
*/
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();
}
public boolean isBodyStream() {
return (currentForm == SOAPPart.FORM_INPUTSTREAM || currentForm == SOAPPart.FORM_BODYINSTREAM);
}
}