duke@1: /* tbell@45: * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. duke@1: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@1: * duke@1: * This code is free software; you can redistribute it and/or modify it duke@1: * under the terms of the GNU General Public License version 2 only, as duke@1: * published by the Free Software Foundation. Sun designates this duke@1: * particular file as subject to the "Classpath" exception as provided duke@1: * by Sun in the LICENSE file that accompanied this code. duke@1: * duke@1: * This code is distributed in the hope that it will be useful, but WITHOUT duke@1: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@1: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@1: * version 2 for more details (a copy is included in the LICENSE file that duke@1: * accompanied this code). duke@1: * duke@1: * You should have received a copy of the GNU General Public License version duke@1: * 2 along with this work; if not, write to the Free Software Foundation, duke@1: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@1: * duke@1: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, duke@1: * CA 95054 USA or visit www.sun.com if you need additional information or duke@1: * have any questions. duke@1: */ tbell@45: /* tbell@50: * tbell@50: * tbell@50: * tbell@45: */ tbell@45: tbell@45: duke@1: package com.sun.xml.internal.messaging.saaj.soap; duke@1: duke@1: import java.io.*; duke@1: import java.util.*; duke@1: import java.util.logging.Level; duke@1: import java.util.logging.Logger; duke@1: duke@1: import javax.activation.DataHandler; duke@1: import javax.activation.DataSource; duke@1: import javax.xml.soap.*; duke@1: import javax.xml.transform.Source; duke@1: import javax.xml.transform.stream.StreamSource; duke@1: duke@1: import com.sun.xml.internal.messaging.saaj.packaging.mime.Header; duke@1: import com.sun.xml.internal.messaging.saaj.packaging.mime.internet.*; duke@1: import com.sun.xml.internal.messaging.saaj.packaging.mime.util.*; duke@1: import com.sun.xml.internal.messaging.saaj.packaging.mime.MessagingException; duke@1: duke@1: import com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl; duke@1: import com.sun.xml.internal.messaging.saaj.soap.impl.EnvelopeImpl; duke@1: import com.sun.xml.internal.messaging.saaj.util.*; duke@1: duke@1: /** duke@1: * The message implementation for SOAP messages with duke@1: * attachments. Messages for specific profiles will likely extend this duke@1: * MessageImpl class and add more value for that particular profile. duke@1: * duke@1: * @author Anil Vijendran (akv@eng.sun.com) duke@1: * @author Rajiv Mordani (rajiv.mordani@sun.com) duke@1: * @author Manveen Kaur (manveen.kaur@sun.com) duke@1: */ duke@1: duke@1: public abstract class MessageImpl duke@1: extends SOAPMessage duke@1: implements SOAPConstants { duke@1: duke@1: duke@1: public static final String CONTENT_ID = "Content-ID"; duke@1: public static final String CONTENT_LOCATION = "Content-Location"; duke@1: tbell@50: protected static final Logger log = duke@1: Logger.getLogger(LogDomainConstants.SOAP_DOMAIN, duke@1: "com.sun.xml.internal.messaging.saaj.soap.LocalStrings"); duke@1: duke@1: protected static final int PLAIN_XML_FLAG = 1; // 00001 duke@1: protected static final int MIME_MULTIPART_FLAG = 2; // 00010 duke@1: protected static final int SOAP1_1_FLAG = 4; // 00100 duke@1: protected static final int SOAP1_2_FLAG = 8; // 01000 duke@1: protected static final int MIME_MULTIPART_XOP_FLAG = 14; // 01110 duke@1: protected static final int XOP_FLAG = 13; // 01101 duke@1: protected static final int FI_ENCODED_FLAG = 16; // 10000 duke@1: duke@1: protected MimeHeaders headers; duke@1: protected SOAPPartImpl soapPart; duke@1: protected FinalArrayList attachments; duke@1: protected boolean saved = false; duke@1: protected byte[] messageBytes; duke@1: protected int messageByteCount; duke@1: protected HashMap properties = new HashMap(); duke@1: duke@1: // used for lazy attachment initialization duke@1: protected MimeMultipart multiPart = null; duke@1: protected boolean attachmentsInitialized = false; duke@1: duke@1: /** duke@1: * True if this part is encoded using Fast Infoset. duke@1: * MIME -> application/fastinfoset duke@1: */ duke@1: protected boolean isFastInfoset = false; duke@1: duke@1: /** duke@1: * True if the Accept header of this message includes duke@1: * application/fastinfoset duke@1: */ duke@1: protected boolean acceptFastInfoset = false; duke@1: duke@1: protected MimeMultipart mmp = null; duke@1: duke@1: // if attachments are present, don't read the entire message in byte stream in saveTo() duke@1: private boolean optimizeAttachmentProcessing = true; duke@1: duke@1: // switch back to old MimeMultipart incase of problem duke@1: private static boolean switchOffBM = false; duke@1: private static boolean switchOffLazyAttachment = false; duke@1: duke@1: static { duke@1: try { duke@1: String s = System.getProperty("saaj.mime.optimization"); duke@1: if ((s != null) && s.equals("false")) { duke@1: switchOffBM = true; duke@1: } duke@1: s = System.getProperty("saaj.lazy.mime.optimization"); duke@1: if ((s != null) && s.equals("false")) { duke@1: switchOffLazyAttachment = true; duke@1: } duke@1: } catch (SecurityException ex) { duke@1: // ignore it duke@1: } duke@1: } duke@1: duke@1: //property to indicate optimized serialization for lazy attachments duke@1: private boolean lazyAttachments = false; duke@1: duke@1: // most of the times, Content-Types are already all lower cased. duke@1: // String.toLowerCase() works faster in this case, so even if you duke@1: // are only doing one comparison, it pays off to use String.toLowerCase() duke@1: // than String.equalsIgnoreCase(). When you do more than one comparison, duke@1: // the benefits of String.toLowerCase() dominates. duke@1: // duke@1: // duke@1: // for FI, duke@1: // use application/fastinfoset for SOAP 1.1 duke@1: // use application/soap+fastinfoset for SOAP 1.2 duke@1: // to speed up comparisons, test methods always use lower cases. duke@1: duke@1: /** duke@1: * @param primary duke@1: * must be all lower case duke@1: * @param sub duke@1: * must be all lower case duke@1: */ duke@1: private static boolean isSoap1_1Type(String primary, String sub) { duke@1: return primary.equals("text") && sub.equals("xml") duke@1: || primary.equals("application") duke@1: && sub.equals("fastinfoset"); duke@1: } duke@1: duke@1: /** duke@1: * @param type duke@1: * must be all lower case duke@1: */ duke@1: private static boolean isEqualToSoap1_1Type(String type) { duke@1: return type.startsWith("text/xml") || duke@1: type.startsWith("application/fastinfoset"); duke@1: } duke@1: duke@1: /** duke@1: * @param primary duke@1: * must be all lower case duke@1: * @param sub duke@1: * must be all lower case duke@1: */ duke@1: private static boolean isSoap1_2Type(String primary, String sub) { duke@1: return primary.equals("application") duke@1: && (sub.equals("soap+xml") duke@1: || sub.equals("soap+fastinfoset")); duke@1: } duke@1: duke@1: /** duke@1: * @param type duke@1: * must be all lower case duke@1: */ duke@1: private static boolean isEqualToSoap1_2Type(String type) { duke@1: return type.startsWith("application/soap+xml") || duke@1: type.startsWith("application/soap+fastinfoset"); duke@1: } duke@1: duke@1: /** duke@1: * Construct a new message. This will be invoked before message duke@1: * sends. duke@1: */ duke@1: protected MessageImpl() { duke@1: this(false, false); duke@1: attachmentsInitialized = true; duke@1: } duke@1: duke@1: /** duke@1: * Construct a new message. This will be invoked before message duke@1: * sends. duke@1: */ duke@1: protected MessageImpl(boolean isFastInfoset, boolean acceptFastInfoset) { duke@1: this.isFastInfoset = isFastInfoset; duke@1: this.acceptFastInfoset = acceptFastInfoset; duke@1: duke@1: headers = new MimeHeaders(); duke@1: headers.setHeader("Accept", getExpectedAcceptHeader()); duke@1: } duke@1: duke@1: /** duke@1: * Shallow copy. duke@1: */ duke@1: protected MessageImpl(SOAPMessage msg) { duke@1: if (!(msg instanceof MessageImpl)) { duke@1: // don't know how to handle this. duke@1: } duke@1: MessageImpl src = (MessageImpl) msg; duke@1: this.headers = src.headers; duke@1: this.soapPart = src.soapPart; duke@1: this.attachments = src.attachments; duke@1: this.saved = src.saved; duke@1: this.messageBytes = src.messageBytes; duke@1: this.messageByteCount = src.messageByteCount; duke@1: this.properties = src.properties; duke@1: } duke@1: duke@1: /** duke@1: * @param stat duke@1: * the mask value obtained from {@link #identifyContentType(ContentType)} duke@1: */ duke@1: protected static boolean isSoap1_1Content(int stat) { duke@1: return (stat & SOAP1_1_FLAG) != 0; duke@1: } duke@1: duke@1: /** duke@1: * @param stat duke@1: * the mask value obtained from {@link #identifyContentType(ContentType)} duke@1: */ duke@1: protected static boolean isSoap1_2Content(int stat) { duke@1: return (stat & SOAP1_2_FLAG) != 0; duke@1: } duke@1: duke@1: private static boolean isMimeMultipartXOPPackage(ContentType contentType) { duke@1: String type = contentType.getParameter("type"); duke@1: if(type==null) duke@1: return false; duke@1: duke@1: type = type.toLowerCase(); duke@1: if(!type.startsWith("application/xop+xml")) duke@1: return false; duke@1: duke@1: String startinfo = contentType.getParameter("start-info"); duke@1: if(startinfo == null) duke@1: return false; duke@1: startinfo = startinfo.toLowerCase(); duke@1: return isEqualToSoap1_2Type(startinfo) || isEqualToSoap1_1Type(startinfo); duke@1: } duke@1: duke@1: private static boolean isSOAPBodyXOPPackage(ContentType contentType){ duke@1: String primary = contentType.getPrimaryType(); duke@1: String sub = contentType.getSubType(); duke@1: duke@1: if (primary.equalsIgnoreCase("application")) { duke@1: if (sub.equalsIgnoreCase("xop+xml")) { duke@1: String type = getTypeParameter(contentType); duke@1: return isEqualToSoap1_2Type(type) || isEqualToSoap1_1Type(type); duke@1: } duke@1: } duke@1: return false; duke@1: } duke@1: duke@1: /** duke@1: * Construct a message from an input stream. When messages are duke@1: * received, there's two parts -- the transport headers and the duke@1: * message content in a transport specific stream. duke@1: */ duke@1: protected MessageImpl(MimeHeaders headers, final InputStream in) duke@1: throws SOAPExceptionImpl { duke@1: ContentType ct = parseContentType(headers); duke@1: init(headers,identifyContentType(ct),ct,in); duke@1: } duke@1: duke@1: private static ContentType parseContentType(MimeHeaders headers) throws SOAPExceptionImpl { duke@1: final String ct; duke@1: if (headers != null) duke@1: ct = getContentType(headers); duke@1: else { duke@1: log.severe("SAAJ0550.soap.null.headers"); duke@1: throw new SOAPExceptionImpl("Cannot create message: " + duke@1: "Headers can't be null"); duke@1: } duke@1: duke@1: if (ct == null) { duke@1: log.severe("SAAJ0532.soap.no.Content-Type"); duke@1: throw new SOAPExceptionImpl("Absent Content-Type"); duke@1: } duke@1: try { duke@1: return new ContentType(ct); duke@1: } catch (Throwable ex) { duke@1: log.severe("SAAJ0535.soap.cannot.internalize.message"); duke@1: throw new SOAPExceptionImpl("Unable to internalize message", ex); duke@1: } duke@1: } duke@1: duke@1: /** duke@1: * Construct a message from an input stream. When messages are duke@1: * received, there's two parts -- the transport headers and the duke@1: * message content in a transport specific stream. duke@1: * duke@1: * @param contentType duke@1: * The parsed content type header from the headers variable. duke@1: * This is redundant parameter, but it avoids reparsing this header again. duke@1: * @param stat duke@1: * The result of {@link #identifyContentType(ContentType)} over duke@1: * the contentType parameter. This redundant parameter, but it avoids duke@1: * recomputing this information again. duke@1: */ duke@1: protected MessageImpl(MimeHeaders headers, final ContentType contentType, int stat, final InputStream in) throws SOAPExceptionImpl { duke@1: init(headers, stat, contentType, in); duke@1: duke@1: } duke@1: duke@1: private void init(MimeHeaders headers, int stat, final ContentType contentType, final InputStream in) throws SOAPExceptionImpl { duke@1: this.headers = headers; duke@1: duke@1: try { duke@1: duke@1: // Set isFastInfoset/acceptFastInfoset flag based on MIME type duke@1: if ((stat & FI_ENCODED_FLAG) > 0) { duke@1: isFastInfoset = acceptFastInfoset = true; duke@1: } duke@1: duke@1: // If necessary, inspect Accept header to set acceptFastInfoset duke@1: if (!isFastInfoset) { duke@1: String[] values = headers.getHeader("Accept"); duke@1: if (values != null) { duke@1: for (int i = 0; i < values.length; i++) { duke@1: StringTokenizer st = new StringTokenizer(values[i], ","); duke@1: while (st.hasMoreTokens()) { duke@1: final String token = st.nextToken().trim(); duke@1: if (token.equalsIgnoreCase("application/fastinfoset") || duke@1: token.equalsIgnoreCase("application/soap+fastinfoset")) { duke@1: acceptFastInfoset = true; duke@1: break; duke@1: } duke@1: } duke@1: } duke@1: } duke@1: } duke@1: duke@1: if (!isCorrectSoapVersion(stat)) { duke@1: log.log( duke@1: Level.SEVERE, duke@1: "SAAJ0533.soap.incorrect.Content-Type", duke@1: new String[] { duke@1: contentType.toString(), duke@1: getExpectedContentType()}); duke@1: throw new SOAPVersionMismatchException( duke@1: "Cannot create message: incorrect content-type for SOAP version. Got: " duke@1: + contentType duke@1: + " Expected: " duke@1: + getExpectedContentType()); duke@1: } duke@1: duke@1: if ((stat & PLAIN_XML_FLAG) != 0) { duke@1: if (isFastInfoset) { duke@1: getSOAPPart().setContent( duke@1: FastInfosetReflection.FastInfosetSource_new(in)); duke@1: } else { duke@1: initCharsetProperty(contentType); duke@1: getSOAPPart().setContent(new StreamSource(in)); duke@1: } duke@1: } duke@1: else if ((stat & MIME_MULTIPART_FLAG) != 0) { duke@1: DataSource ds = new DataSource() { duke@1: public InputStream getInputStream() { duke@1: return in; duke@1: } duke@1: duke@1: public OutputStream getOutputStream() { duke@1: return null; duke@1: } duke@1: duke@1: public String getContentType() { duke@1: return contentType.toString(); duke@1: } duke@1: duke@1: public String getName() { duke@1: return ""; duke@1: } duke@1: }; duke@1: duke@1: multiPart = null; duke@1: if (switchOffBM) { duke@1: multiPart = new MimeMultipart(ds,contentType); duke@1: } else { duke@1: multiPart = new BMMimeMultipart(ds,contentType); duke@1: } duke@1: duke@1: String startParam = contentType.getParameter("start"); duke@1: MimeBodyPart soapMessagePart = null; duke@1: String contentID = null; duke@1: if (switchOffBM || switchOffLazyAttachment) { duke@1: if(startParam == null) { duke@1: soapMessagePart = multiPart.getBodyPart(0); duke@1: for (int i = 1; i < multiPart.getCount(); i++) { duke@1: initializeAttachment(multiPart, i); duke@1: } duke@1: } else { duke@1: soapMessagePart = multiPart.getBodyPart(startParam); duke@1: for (int i = 0; i < multiPart.getCount(); i++) { duke@1: contentID = multiPart.getBodyPart(i).getContentID(); duke@1: if(!contentID.equals(startParam)) duke@1: initializeAttachment(multiPart, i); duke@1: } duke@1: } duke@1: } else { duke@1: BMMimeMultipart bmMultipart = duke@1: (BMMimeMultipart)multiPart; duke@1: InputStream stream = bmMultipart.initStream(); duke@1: duke@1: SharedInputStream sin = null; duke@1: if (stream instanceof SharedInputStream) { duke@1: sin = (SharedInputStream)stream; duke@1: } duke@1: duke@1: String boundary = "--" + duke@1: contentType.getParameter("boundary"); duke@1: byte[] bndbytes = ASCIIUtility.getBytes(boundary); duke@1: if (startParam == null) { duke@1: soapMessagePart = duke@1: bmMultipart.getNextPart(stream, bndbytes, sin); duke@1: bmMultipart.removeBodyPart(soapMessagePart); duke@1: } else { duke@1: MimeBodyPart bp = null; duke@1: try { duke@1: while(!startParam.equals(contentID)) { duke@1: bp = bmMultipart.getNextPart( duke@1: stream, bndbytes, sin); duke@1: contentID = bp.getContentID(); duke@1: } duke@1: soapMessagePart = bp; duke@1: bmMultipart.removeBodyPart(bp); duke@1: } catch (Exception e) { duke@1: throw new SOAPExceptionImpl(e); duke@1: } duke@1: } duke@1: } duke@1: duke@1: ContentType soapPartCType = new ContentType( duke@1: soapMessagePart.getContentType()); duke@1: initCharsetProperty(soapPartCType); duke@1: String baseType = soapPartCType.getBaseType().toLowerCase(); duke@1: if(!(isEqualToSoap1_1Type(baseType) duke@1: || isEqualToSoap1_2Type(baseType) duke@1: || isSOAPBodyXOPPackage(soapPartCType))) { duke@1: log.log(Level.SEVERE, duke@1: "SAAJ0549.soap.part.invalid.Content-Type", duke@1: new Object[] {baseType}); duke@1: throw new SOAPExceptionImpl( duke@1: "Bad Content-Type for SOAP Part : " + duke@1: baseType); duke@1: } duke@1: duke@1: SOAPPart soapPart = getSOAPPart(); duke@1: setMimeHeaders(soapPart, soapMessagePart); duke@1: soapPart.setContent(isFastInfoset ? duke@1: (Source) FastInfosetReflection.FastInfosetSource_new( duke@1: soapMessagePart.getInputStream()) : duke@1: (Source) new StreamSource(soapMessagePart.getInputStream())); duke@1: } else { duke@1: log.severe("SAAJ0534.soap.unknown.Content-Type"); duke@1: throw new SOAPExceptionImpl("Unrecognized Content-Type"); duke@1: } duke@1: } catch (Throwable ex) { duke@1: log.severe("SAAJ0535.soap.cannot.internalize.message"); duke@1: throw new SOAPExceptionImpl("Unable to internalize message", ex); duke@1: } duke@1: needsSave(); duke@1: } duke@1: duke@1: public boolean isFastInfoset() { duke@1: return isFastInfoset; duke@1: } duke@1: duke@1: public boolean acceptFastInfoset() { duke@1: return acceptFastInfoset; duke@1: } duke@1: duke@1: public void setIsFastInfoset(boolean value) { duke@1: if (value != isFastInfoset) { duke@1: isFastInfoset = value; duke@1: if (isFastInfoset) { duke@1: acceptFastInfoset = true; duke@1: } duke@1: saved = false; // ensure transcoding if necessary duke@1: } duke@1: } duke@1: duke@1: public Object getProperty(String property) { duke@1: return (String) properties.get(property); duke@1: } duke@1: duke@1: public void setProperty(String property, Object value) { duke@1: verify(property, value); duke@1: properties.put(property, value); duke@1: } duke@1: duke@1: private void verify(String property, Object value) { duke@1: if (property.equalsIgnoreCase(SOAPMessage.WRITE_XML_DECLARATION)) { duke@1: if (!("true".equals(value) || "false".equals(value))) duke@1: throw new RuntimeException( duke@1: property + " must have value false or true"); duke@1: duke@1: try { duke@1: EnvelopeImpl env = (EnvelopeImpl) getSOAPPart().getEnvelope(); duke@1: if ("true".equalsIgnoreCase((String)value)) { duke@1: env.setOmitXmlDecl("no"); duke@1: } else if ("false".equalsIgnoreCase((String)value)) { duke@1: env.setOmitXmlDecl("yes"); duke@1: } duke@1: } catch (Exception e) { duke@1: log.log(Level.SEVERE, "SAAJ0591.soap.exception.in.set.property", duke@1: new Object[] {e.getMessage(), "javax.xml.soap.write-xml-declaration"}); duke@1: throw new RuntimeException(e); duke@1: } duke@1: return; duke@1: } duke@1: duke@1: if (property.equalsIgnoreCase(SOAPMessage.CHARACTER_SET_ENCODING)) { duke@1: try { duke@1: ((EnvelopeImpl) getSOAPPart().getEnvelope()).setCharsetEncoding((String)value); duke@1: } catch (Exception e) { duke@1: log.log(Level.SEVERE, "SAAJ0591.soap.exception.in.set.property", duke@1: new Object[] {e.getMessage(), "javax.xml.soap.character-set-encoding"}); duke@1: throw new RuntimeException(e); duke@1: } duke@1: } duke@1: } duke@1: duke@1: protected abstract boolean isCorrectSoapVersion(int contentTypeId); duke@1: duke@1: protected abstract String getExpectedContentType(); duke@1: protected abstract String getExpectedAcceptHeader(); duke@1: duke@1: /** duke@1: * Sniffs the Content-Type header so that we can determine how to process. duke@1: * duke@1: *
duke@1: * In the absence of type attribute we assume it to be text/xml.
duke@1: * That would mean we're easy on accepting the message and
duke@1: * generate the correct thing (as the SWA spec also specifies
duke@1: * that the type parameter should always be text/xml)
duke@1: *
duke@1: * @return
duke@1: * combination of flags, such as PLAIN_XML_CODE and MIME_MULTIPART_CODE.
duke@1: */
duke@1: // SOAP1.2 allow SOAP1.2 content type
duke@1: static int identifyContentType(ContentType contentType)
duke@1: throws SOAPExceptionImpl {
duke@1: // TBD
duke@1: // Is there anything else we need to verify here?
duke@1:
duke@1: String primary = contentType.getPrimaryType().toLowerCase();
duke@1: String sub = contentType.getSubType().toLowerCase();
duke@1:
duke@1: if (primary.equals("multipart")) {
duke@1: if (sub.equals("related")) {
duke@1: String type = getTypeParameter(contentType);
duke@1: if (isEqualToSoap1_1Type(type)) {
duke@1: return (type.equals("application/fastinfoset") ?
duke@1: FI_ENCODED_FLAG : 0) | MIME_MULTIPART_FLAG | SOAP1_1_FLAG;
duke@1: }
duke@1: else if (isEqualToSoap1_2Type(type)) {
duke@1: return (type.equals("application/soap+fastinfoset") ?
duke@1: FI_ENCODED_FLAG : 0) | MIME_MULTIPART_FLAG | SOAP1_2_FLAG;
duke@1: } else if (isMimeMultipartXOPPackage(contentType)) {
duke@1: return MIME_MULTIPART_XOP_FLAG;
duke@1: } else {
duke@1: log.severe("SAAJ0536.soap.content-type.mustbe.multipart");
duke@1: throw new SOAPExceptionImpl(
duke@1: "Content-Type needs to be Multipart/Related "
duke@1: + "and with \"type=text/xml\" "
duke@1: + "or \"type=application/soap+xml\"");
duke@1: }
duke@1: } else {
duke@1: log.severe("SAAJ0537.soap.invalid.content-type");
duke@1: throw new SOAPExceptionImpl(
duke@1: "Invalid Content-Type: " + primary + '/' + sub);
duke@1: }
duke@1: }
duke@1: else if (isSoap1_1Type(primary, sub)) {
duke@1: return (primary.equalsIgnoreCase("application")
duke@1: && sub.equalsIgnoreCase("fastinfoset") ?
duke@1: FI_ENCODED_FLAG : 0)
duke@1: | PLAIN_XML_FLAG | SOAP1_1_FLAG;
duke@1: }
duke@1: else if (isSoap1_2Type(primary, sub)) {
duke@1: return (primary.equalsIgnoreCase("application")
duke@1: && sub.equalsIgnoreCase("soap+fastinfoset") ?
duke@1: FI_ENCODED_FLAG : 0)
duke@1: | PLAIN_XML_FLAG | SOAP1_2_FLAG;
duke@1: } else if(isSOAPBodyXOPPackage(contentType)){
duke@1: return XOP_FLAG;
duke@1: } else {
duke@1: log.severe("SAAJ0537.soap.invalid.content-type");
duke@1: throw new SOAPExceptionImpl(
duke@1: "Invalid Content-Type:"
duke@1: + primary
duke@1: + '/'
duke@1: + sub
duke@1: + ". Is this an error message instead of a SOAP response?");
duke@1: }
duke@1: }
duke@1:
duke@1: /**
duke@1: * Obtains the type parameter of the Content-Type header. Defaults to "text/xml".
duke@1: */
duke@1: private static String getTypeParameter(ContentType contentType) {
duke@1: String p = contentType.getParameter("type");
duke@1: if(p!=null)
duke@1: return p.toLowerCase();
duke@1: else
duke@1: return "text/xml";
duke@1: }
duke@1:
duke@1: public MimeHeaders getMimeHeaders() {
duke@1: return this.headers;
duke@1: }
duke@1:
duke@1: final static String getContentType(MimeHeaders headers) {
duke@1: String[] values = headers.getHeader("Content-Type");
duke@1: if (values == null)
duke@1: return null;
duke@1: else
duke@1: return values[0];
duke@1: }
duke@1:
duke@1: /*
duke@1: * Get the complete ContentType value along with optional parameters.
duke@1: */
duke@1: public String getContentType() {
duke@1: return getContentType(this.headers);
duke@1: }
duke@1:
duke@1: public void setContentType(String type) {
duke@1: headers.setHeader("Content-Type", type);
duke@1: needsSave();
duke@1: }
duke@1:
duke@1: private ContentType ContentType() {
duke@1: ContentType ct = null;
duke@1: try {
duke@1: ct = new ContentType(getContentType());
duke@1: } catch (Exception e) {
duke@1: // what to do here?
duke@1: }
duke@1: return ct;
duke@1: }
duke@1:
duke@1: /*
duke@1: * Return the MIME type string, without the parameters.
duke@1: */
duke@1: public String getBaseType() {
duke@1: return ContentType().getBaseType();
duke@1: }
duke@1:
duke@1: public void setBaseType(String type) {
duke@1: ContentType ct = ContentType();
duke@1: ct.setParameter("type", type);
duke@1: headers.setHeader("Content-Type", ct.toString());
duke@1: needsSave();
duke@1: }
duke@1:
duke@1: public String getAction() {
duke@1: return ContentType().getParameter("action");
duke@1: }
duke@1:
duke@1: public void setAction(String action) {
duke@1: ContentType ct = ContentType();
duke@1: ct.setParameter("action", action);
duke@1: headers.setHeader("Content-Type", ct.toString());
duke@1: needsSave();
duke@1: }
duke@1:
duke@1: public String getCharset() {
duke@1: return ContentType().getParameter("charset");
duke@1: }
duke@1:
duke@1: public void setCharset(String charset) {
duke@1: ContentType ct = ContentType();
duke@1: ct.setParameter("charset", charset);
duke@1: headers.setHeader("Content-Type", ct.toString());
duke@1: needsSave();
duke@1: }
duke@1:
duke@1: /**
duke@1: * All write methods (i.e setters) should call this method in
duke@1: * order to make sure that a save is necessary since the state
duke@1: * has been modified.
duke@1: */
duke@1: private final void needsSave() {
duke@1: saved = false;
duke@1: }
duke@1:
duke@1: public boolean saveRequired() {
duke@1: return saved != true;
duke@1: }
duke@1:
duke@1: public String getContentDescription() {
duke@1: String[] values = headers.getHeader("Content-Description");
duke@1: if (values != null && values.length > 0)
duke@1: return values[0];
duke@1: return null;
duke@1: }
duke@1:
duke@1: public void setContentDescription(String description) {
duke@1: headers.setHeader("Content-Description", description);
duke@1: needsSave();
duke@1: }
duke@1:
duke@1: public abstract SOAPPart getSOAPPart();
duke@1:
duke@1: public void removeAllAttachments() {
duke@1: try {
duke@1: initializeAllAttachments();
duke@1: } catch (Exception e) {
duke@1: throw new RuntimeException(e);
duke@1: }
duke@1:
duke@1: if (attachments != null) {
duke@1: attachments.clear();
duke@1: needsSave();
duke@1: }
duke@1: }
duke@1:
duke@1: public int countAttachments() {
duke@1: try {
duke@1: initializeAllAttachments();
duke@1: } catch (Exception e) {
duke@1: throw new RuntimeException(e);
duke@1: }
duke@1: if (attachments != null)
duke@1: return attachments.size();
duke@1: return 0;
duke@1: }
duke@1:
duke@1: public void addAttachmentPart(AttachmentPart attachment) {
duke@1: try {
duke@1: initializeAllAttachments();
duke@1: } catch (Exception e) {
duke@1: throw new RuntimeException(e);
duke@1: }
duke@1: if (attachments == null)
duke@1: attachments = new FinalArrayList();
duke@1:
duke@1: attachments.add(attachment);
duke@1:
duke@1: needsSave();
duke@1: }
duke@1:
duke@1: static private final Iterator nullIter = Collections.EMPTY_LIST.iterator();
duke@1:
duke@1: public Iterator getAttachments() {
duke@1: try {
duke@1: initializeAllAttachments();
duke@1: } catch (Exception e) {
duke@1: throw new RuntimeException(e);
duke@1: }
duke@1: if (attachments == null)
duke@1: return nullIter;
duke@1: return attachments.iterator();
duke@1: }
duke@1:
duke@1: private class MimeMatchingIterator implements Iterator {
duke@1: public MimeMatchingIterator(MimeHeaders headers) {
duke@1: this.headers = headers;
duke@1: this.iter = attachments.iterator();
duke@1: }
duke@1:
duke@1: private Iterator iter;
duke@1: private MimeHeaders headers;
duke@1: private Object nextAttachment;
duke@1:
duke@1: public boolean hasNext() {
duke@1: if (nextAttachment == null)
duke@1: nextAttachment = nextMatch();
duke@1: return nextAttachment != null;
duke@1: }
duke@1:
duke@1: public Object next() {
duke@1: if (nextAttachment != null) {
duke@1: Object ret = nextAttachment;
duke@1: nextAttachment = null;
duke@1: return ret;
duke@1: }
duke@1:
duke@1: if (hasNext())
duke@1: return nextAttachment;
duke@1:
duke@1: return null;
duke@1: }
duke@1:
duke@1: Object nextMatch() {
duke@1: while (iter.hasNext()) {
duke@1: AttachmentPartImpl ap = (AttachmentPartImpl) iter.next();
duke@1: if (ap.hasAllHeaders(headers))
duke@1: return ap;
duke@1: }
duke@1: return null;
duke@1: }
duke@1:
duke@1: public void remove() {
duke@1: iter.remove();
duke@1: }
duke@1: }
duke@1:
duke@1: public Iterator getAttachments(MimeHeaders headers) {
duke@1: try {
duke@1: initializeAllAttachments();
duke@1: } catch (Exception e) {
duke@1: throw new RuntimeException(e);
duke@1: }
duke@1: if (attachments == null)
duke@1: return nullIter;
duke@1:
duke@1: return new MimeMatchingIterator(headers);
duke@1: }
duke@1:
duke@1: public void removeAttachments(MimeHeaders headers) {
duke@1: try {
duke@1: initializeAllAttachments();
duke@1: } catch (Exception e) {
duke@1: throw new RuntimeException(e);
duke@1: }
duke@1: if (attachments == null)
duke@1: return ;
duke@1:
duke@1: Iterator it = new MimeMatchingIterator(headers);
duke@1: while (it.hasNext()) {
duke@1: int index = attachments.indexOf(it.next());
duke@1: attachments.set(index, null);
duke@1: }
duke@1: FinalArrayList f = new FinalArrayList();
duke@1: for (int i = 0; i < attachments.size(); i++) {
duke@1: if (attachments.get(i) != null) {
duke@1: f.add(attachments.get(i));
duke@1: }
duke@1: }
duke@1: attachments = f;
duke@1: }
duke@1:
duke@1: public AttachmentPart createAttachmentPart() {
duke@1: return new AttachmentPartImpl();
duke@1: }
duke@1:
duke@1: public AttachmentPart getAttachment(SOAPElement element)
duke@1: throws SOAPException {
duke@1: try {
duke@1: initializeAllAttachments();
duke@1: } catch (Exception e) {
duke@1: throw new RuntimeException(e);
duke@1: }
duke@1: String uri;
duke@1: String hrefAttr = element.getAttribute("href");
duke@1: if ("".equals(hrefAttr)) {
duke@1: Node node = getValueNodeStrict(element);
duke@1: String swaRef = null;
duke@1: if (node != null) {
duke@1: swaRef = node.getValue();
duke@1: }
duke@1: if (swaRef == null || "".equals(swaRef)) {
duke@1: return null;
duke@1: } else {
duke@1: uri = swaRef;
duke@1: }
duke@1: } else {
duke@1: uri = hrefAttr;
duke@1: }
duke@1: return getAttachmentPart(uri);
duke@1: }
duke@1:
duke@1: private Node getValueNodeStrict(SOAPElement element) {
duke@1: Node node = (Node)element.getFirstChild();
duke@1: if (node != null) {
duke@1: if (node.getNextSibling() == null
duke@1: && node.getNodeType() == org.w3c.dom.Node.TEXT_NODE) {
duke@1: return node;
duke@1: } else {
duke@1: return null;
duke@1: }
duke@1: }
duke@1: return null;
duke@1: }
duke@1:
duke@1:
duke@1: private AttachmentPart getAttachmentPart(String uri) throws SOAPException {
duke@1: AttachmentPart _part;
duke@1: try {
duke@1: if (uri.startsWith("cid:")) {
duke@1: // rfc2392
duke@1: uri = '<'+uri.substring("cid:".length())+'>';
duke@1:
duke@1: MimeHeaders headersToMatch = new MimeHeaders();
duke@1: headersToMatch.addHeader(CONTENT_ID, uri);
duke@1:
duke@1: Iterator i = this.getAttachments(headersToMatch);
duke@1: _part = (i == null) ? null : (AttachmentPart)i.next();
duke@1: } else {
duke@1: // try content-location
duke@1: MimeHeaders headersToMatch = new MimeHeaders();
duke@1: headersToMatch.addHeader(CONTENT_LOCATION, uri);
duke@1:
duke@1: Iterator i = this.getAttachments(headersToMatch);
duke@1: _part = (i == null) ? null : (AttachmentPart)i.next();
duke@1: }
duke@1:
duke@1: // try auto-generated JAXRPC CID
duke@1: if (_part == null) {
duke@1: Iterator j = this.getAttachments();
duke@1:
duke@1: while (j.hasNext()) {
duke@1: AttachmentPart p = (AttachmentPart)j.next();
duke@1: String cl = p.getContentId();
duke@1: if (cl != null) {
duke@1: // obtain the partname
duke@1: int eqIndex = cl.indexOf("=");
duke@1: if (eqIndex > -1) {
duke@1: cl = cl.substring(1, eqIndex);
duke@1: if (cl.equalsIgnoreCase(uri)) {
duke@1: _part = p;
duke@1: break;
duke@1: }
duke@1: }
duke@1: }
duke@1: }
duke@1: }
duke@1:
duke@1: } catch (Exception se) {
duke@1: log.log(Level.SEVERE, "SAAJ0590.soap.unable.to.locate.attachment", new Object[] {uri});
duke@1: throw new SOAPExceptionImpl(se);
duke@1: }
duke@1: return _part;
duke@1: }
duke@1:
duke@1: private final ByteInputStream getHeaderBytes()
duke@1: throws IOException {
duke@1: SOAPPartImpl sp = (SOAPPartImpl) getSOAPPart();
duke@1: return sp.getContentAsStream();
duke@1: }
duke@1:
duke@1: private String convertToSingleLine(String contentType) {
duke@1: StringBuffer buffer = new StringBuffer();
duke@1: for (int i = 0; i < contentType.length(); i ++) {
duke@1: char c = contentType.charAt(i);
duke@1: if (c != '\r' && c != '\n' && c != '\t')
duke@1: buffer.append(c);
duke@1: }
duke@1: return buffer.toString();
duke@1: }
duke@1:
duke@1: private MimeMultipart getMimeMessage() throws SOAPException {
duke@1: try {
duke@1: SOAPPartImpl soapPart = (SOAPPartImpl) getSOAPPart();
duke@1: MimeBodyPart mimeSoapPart = soapPart.getMimePart();
duke@1:
duke@1: /*
duke@1: * Get content type from this message instead of soapPart
duke@1: * to ensure agreement if soapPart is transcoded (XML <-> FI)
duke@1: */
duke@1: ContentType soapPartCtype = new ContentType(getExpectedContentType());
duke@1:
duke@1: if (!isFastInfoset) {
duke@1: soapPartCtype.setParameter("charset", initCharset());
duke@1: }
duke@1: mimeSoapPart.setHeader("Content-Type", soapPartCtype.toString());
duke@1:
duke@1: MimeMultipart headerAndBody = null;
duke@1:
duke@1: if (!switchOffBM && !switchOffLazyAttachment &&
duke@1: (multiPart != null) && !attachmentsInitialized) {
duke@1: headerAndBody = new BMMimeMultipart();
duke@1: headerAndBody.addBodyPart(mimeSoapPart);
duke@1: if (attachments != null) {
duke@1: for (Iterator eachAttachment = attachments.iterator();
duke@1: eachAttachment.hasNext();) {
duke@1: headerAndBody.addBodyPart(
duke@1: ((AttachmentPartImpl) eachAttachment.next())
duke@1: .getMimePart());
duke@1: }
duke@1: }
duke@1: InputStream in = ((BMMimeMultipart)multiPart).getInputStream();
duke@1: if (!((BMMimeMultipart)multiPart).lastBodyPartFound() &&
duke@1: !((BMMimeMultipart)multiPart).isEndOfStream()) {
duke@1: ((BMMimeMultipart)headerAndBody).setInputStream(in);
duke@1: ((BMMimeMultipart)headerAndBody).setBoundary(
duke@1: ((BMMimeMultipart)multiPart).getBoundary());
duke@1: ((BMMimeMultipart)headerAndBody).
duke@1: setLazyAttachments(lazyAttachments);
duke@1: }
duke@1:
duke@1: } else {
duke@1: headerAndBody = new MimeMultipart();
duke@1: headerAndBody.addBodyPart(mimeSoapPart);
duke@1:
duke@1: for (Iterator eachAttachement = getAttachments();
duke@1: eachAttachement.hasNext();
duke@1: ) {
duke@1: headerAndBody.addBodyPart(
duke@1: ((AttachmentPartImpl) eachAttachement.next())
duke@1: .getMimePart());
duke@1: }
duke@1: }
duke@1:
duke@1: ContentType contentType = headerAndBody.getContentType();
duke@1:
duke@1: ParameterList l = contentType.getParameterList();
duke@1:
duke@1: // set content type depending on SOAP version
duke@1: l.set("type", getExpectedContentType());
duke@1: l.set("boundary", contentType.getParameter("boundary"));
duke@1: ContentType nct = new ContentType("multipart", "related", l);
duke@1:
duke@1: headers.setHeader(
duke@1: "Content-Type",
duke@1: convertToSingleLine(nct.toString()));
duke@1: // TBD
duke@1: // Set content length MIME header here.
duke@1:
duke@1: return headerAndBody;
duke@1: } catch (SOAPException ex) {
duke@1: throw ex;
duke@1: } catch (Throwable ex) {
duke@1: log.severe("SAAJ0538.soap.cannot.convert.msg.to.multipart.obj");
duke@1: throw new SOAPExceptionImpl(
duke@1: "Unable to convert SOAP message into "
duke@1: + "a MimeMultipart object",
duke@1: ex);
duke@1: }
duke@1: }
duke@1:
duke@1: private String initCharset() {
duke@1:
duke@1: String charset = null;
duke@1:
duke@1: String[] cts = getMimeHeaders().getHeader("Content-Type");
duke@1: if ((cts != null) && (cts[0] != null)) {
duke@1: charset = getCharsetString(cts[0]);
duke@1: }
duke@1:
duke@1: if (charset == null) {
duke@1: charset = (String) getProperty(CHARACTER_SET_ENCODING);
duke@1: }
duke@1:
duke@1: if (charset != null) {
duke@1: return charset;
duke@1: }
duke@1:
duke@1: return "utf-8";
duke@1: }
duke@1:
duke@1: private String getCharsetString(String s) {
duke@1: try {
duke@1: int index = s.indexOf(";");
duke@1: if(index < 0)
duke@1: return null;
duke@1: ParameterList pl = new ParameterList(s.substring(index));
duke@1: return pl.get("charset");
duke@1: } catch(Exception e) {
duke@1: return null;
duke@1: }
duke@1: }
duke@1:
duke@1: public void saveChanges() throws SOAPException {
duke@1:
duke@1: // suck in all the data from the attachments and have it
duke@1: // ready for writing/sending etc.
duke@1:
duke@1: String charset = initCharset();
duke@1:
duke@1: /*if (countAttachments() == 0) {*/
duke@1: int attachmentCount = (attachments == null) ? 0 : attachments.size();
duke@1: if (attachmentCount == 0) {
duke@1: if (!switchOffBM && !switchOffLazyAttachment &&
duke@1: !attachmentsInitialized && (multiPart != null)) {
duke@1: // so there might be attachments
duke@1: attachmentCount = 1;
duke@1: }
duke@1: }
duke@1:
duke@1: try {
duke@1: if ((attachmentCount == 0) && !hasXOPContent()) {
duke@1: ByteInputStream in;
duke@1: try{
duke@1: /*
duke@1: * Not sure why this is called getHeaderBytes(), but it actually
duke@1: * returns the whole message as a byte stream. This stream could
duke@1: * be either XML of Fast depending on the mode.
duke@1: */
duke@1: in = getHeaderBytes();
duke@1: // no attachments, hence this property can be false
duke@1: this.optimizeAttachmentProcessing = false;
duke@1: } catch (IOException ex) {
duke@1: log.severe("SAAJ0539.soap.cannot.get.header.stream");
duke@1: throw new SOAPExceptionImpl(
duke@1: "Unable to get header stream in saveChanges: ",
duke@1: ex);
duke@1: }
duke@1:
duke@1: messageBytes = in.getBytes();
duke@1: messageByteCount = in.getCount();
duke@1:
duke@1: headers.setHeader(
duke@1: "Content-Type",
duke@1: getExpectedContentType() +
duke@1: (isFastInfoset ? "" : "; charset=" + charset));
duke@1: headers.setHeader(
duke@1: "Content-Length",
duke@1: Integer.toString(messageByteCount));
duke@1: } else {
duke@1: if(hasXOPContent())
duke@1: mmp = getXOPMessage();
duke@1: else
duke@1: mmp = getMimeMessage();
duke@1: }
duke@1: } catch (Throwable ex) {
duke@1: log.severe("SAAJ0540.soap.err.saving.multipart.msg");
duke@1: throw new SOAPExceptionImpl(
duke@1: "Error during saving a multipart message",
duke@1: ex);
duke@1: }
duke@1:
duke@1: // FIX ME -- SOAP Action replaced by Content-Type optional parameter action
duke@1: /*
duke@1: if(isCorrectSoapVersion(SOAP1_1_FLAG)) {
duke@1:
duke@1: String[] soapAction = headers.getHeader("SOAPAction");
duke@1:
duke@1: if (soapAction == null || soapAction.length == 0)
duke@1: headers.setHeader("SOAPAction", "\"\"");
duke@1:
duke@1: }
duke@1: */
duke@1:
duke@1: saved = true;
duke@1: }
duke@1:
duke@1: private MimeMultipart getXOPMessage() throws SOAPException {
duke@1: try {
duke@1: MimeMultipart headerAndBody = new MimeMultipart();
duke@1: SOAPPartImpl soapPart = (SOAPPartImpl)getSOAPPart();
duke@1: MimeBodyPart mimeSoapPart = soapPart.getMimePart();
duke@1: ContentType soapPartCtype =
duke@1: new ContentType("application/xop+xml");
duke@1: soapPartCtype.setParameter("type", getExpectedContentType());
duke@1: String charset = initCharset();
duke@1: soapPartCtype.setParameter("charset", charset);
duke@1: mimeSoapPart.setHeader("Content-Type", soapPartCtype.toString());
duke@1: headerAndBody.addBodyPart(mimeSoapPart);
duke@1:
duke@1: for (Iterator eachAttachement = getAttachments();
duke@1: eachAttachement.hasNext();
duke@1: ) {
duke@1: headerAndBody.addBodyPart(
duke@1: ((AttachmentPartImpl) eachAttachement.next())
duke@1: .getMimePart());
duke@1: }
duke@1:
duke@1: ContentType contentType = headerAndBody.getContentType();
duke@1:
duke@1: ParameterList l = contentType.getParameterList();
duke@1:
duke@1: //lets not write start-info for now till we get servlet fix done
duke@1: l.set("start-info", getExpectedContentType());//+";charset="+initCharset());
duke@1:
duke@1: // set content type depending on SOAP version
duke@1: l.set("type", "application/xop+xml");
duke@1:
duke@1: if (isCorrectSoapVersion(SOAP1_2_FLAG)) {
duke@1: String action = getAction();
duke@1: if(action != null)
duke@1: l.set("action", action);
duke@1: }
duke@1:
duke@1: l.set("boundary", contentType.getParameter("boundary"));
duke@1: ContentType nct = new ContentType("Multipart", "Related", l);
duke@1: headers.setHeader(
duke@1: "Content-Type",
duke@1: convertToSingleLine(nct.toString()));
duke@1: // TBD
duke@1: // Set content length MIME header here.
duke@1:
duke@1: return headerAndBody;
duke@1: } catch (SOAPException ex) {
duke@1: throw ex;
duke@1: } catch (Throwable ex) {
duke@1: log.severe("SAAJ0538.soap.cannot.convert.msg.to.multipart.obj");
duke@1: throw new SOAPExceptionImpl(
duke@1: "Unable to convert SOAP message into "
duke@1: + "a MimeMultipart object",
duke@1: ex);
duke@1: }
duke@1:
duke@1: }
duke@1:
duke@1: private boolean hasXOPContent() throws ParseException {
duke@1: String type = getContentType();
duke@1: if(type == null)
duke@1: return false;
duke@1: ContentType ct = new ContentType(type);
duke@1: return isMimeMultipartXOPPackage(ct) || isSOAPBodyXOPPackage(ct);
duke@1: }
duke@1:
duke@1: public void writeTo(OutputStream out) throws SOAPException, IOException {
duke@1: if (saveRequired()){
duke@1: this.optimizeAttachmentProcessing = true;
duke@1: saveChanges();
duke@1: }
duke@1:
duke@1: if(!optimizeAttachmentProcessing){
duke@1: out.write(messageBytes, 0, messageByteCount);
duke@1: }
duke@1: else{
duke@1: try{
duke@1: if(hasXOPContent()){
duke@1: mmp.writeTo(out);
duke@1: }else{
duke@1: mmp.writeTo(out);
duke@1: if (!switchOffBM && !switchOffLazyAttachment &&
duke@1: (multiPart != null) && !attachmentsInitialized) {
duke@1: ((BMMimeMultipart)multiPart).setInputStream(
duke@1: ((BMMimeMultipart)mmp).getInputStream());
duke@1: }
duke@1: }
duke@1: } catch(Exception ex){
duke@1: log.severe("SAAJ0540.soap.err.saving.multipart.msg");
duke@1: throw new SOAPExceptionImpl(
duke@1: "Error during saving a multipart message",
duke@1: ex);
duke@1: }
duke@1: }
duke@1:
duke@1: if(isCorrectSoapVersion(SOAP1_1_FLAG)) {
duke@1:
duke@1: String[] soapAction = headers.getHeader("SOAPAction");
duke@1:
duke@1: if (soapAction == null || soapAction.length == 0)
duke@1: headers.setHeader("SOAPAction", "\"\"");
duke@1:
duke@1: }
duke@1:
duke@1: messageBytes = null;
duke@1: needsSave();
duke@1: }
duke@1:
duke@1: public SOAPBody getSOAPBody() throws SOAPException {
tbell@45: SOAPBody body = getSOAPPart().getEnvelope().getBody();
tbell@45: /*if (body == null) {
tbell@45: throw new SOAPException("No SOAP Body was found in the SOAP Message");
tbell@45: }*/
tbell@45: return body;
duke@1: }
duke@1:
duke@1: public SOAPHeader getSOAPHeader() throws SOAPException {
tbell@45: SOAPHeader hdr = getSOAPPart().getEnvelope().getHeader();
tbell@45: /*if (hdr == null) {
tbell@45: throw new SOAPException("No SOAP Header was found in the SOAP Message");
tbell@45: }*/
tbell@45: return hdr;
duke@1: }
duke@1:
duke@1: private void initializeAllAttachments ()
duke@1: throws MessagingException, SOAPException {
duke@1: if (switchOffBM || switchOffLazyAttachment) {
duke@1: return;
duke@1: }
duke@1:
duke@1: if (attachmentsInitialized || (multiPart == null)) {
duke@1: return;
duke@1: }
duke@1:
duke@1: if (attachments == null)
duke@1: attachments = new FinalArrayList();
duke@1:
duke@1: int count = multiPart.getCount();
duke@1: for (int i=0; i < count; i++ ) {
duke@1: initializeAttachment(multiPart.getBodyPart(i));
duke@1: }
duke@1: attachmentsInitialized = true;
duke@1: //multiPart = null;
duke@1: needsSave();
duke@1: }
duke@1:
duke@1: private void initializeAttachment(MimeBodyPart mbp) throws SOAPException {
duke@1: AttachmentPartImpl attachmentPart = new AttachmentPartImpl();
duke@1: DataHandler attachmentHandler = mbp.getDataHandler();
duke@1: attachmentPart.setDataHandler(attachmentHandler);
duke@1:
duke@1: AttachmentPartImpl.copyMimeHeaders(mbp, attachmentPart);
duke@1: attachments.add(attachmentPart);
duke@1: }
duke@1:
duke@1: private void initializeAttachment(MimeMultipart multiPart, int i)
duke@1: throws Exception {
duke@1: MimeBodyPart currentBodyPart = multiPart.getBodyPart(i);
duke@1: AttachmentPartImpl attachmentPart = new AttachmentPartImpl();
duke@1:
duke@1: DataHandler attachmentHandler = currentBodyPart.getDataHandler();
duke@1: attachmentPart.setDataHandler(attachmentHandler);
duke@1:
duke@1: AttachmentPartImpl.copyMimeHeaders(currentBodyPart, attachmentPart);
duke@1: addAttachmentPart(attachmentPart);
duke@1: }
duke@1:
duke@1: private void setMimeHeaders(SOAPPart soapPart,
duke@1: MimeBodyPart soapMessagePart) throws Exception {
duke@1:
duke@1: // first remove the existing content-type
duke@1: soapPart.removeAllMimeHeaders();
duke@1: // add everything present in soapMessagePart
duke@1: List headers = soapMessagePart.getAllHeaders();
duke@1: int sz = headers.size();
duke@1: for( int i=0; i