📄 soappart.java
字号:
/* * 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");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -