aoqi@0: /*
aoqi@0: * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0: *
aoqi@0: * This code is free software; you can redistribute it and/or modify it
aoqi@0: * under the terms of the GNU General Public License version 2 only, as
aoqi@0: * published by the Free Software Foundation. Oracle designates this
aoqi@0: * particular file as subject to the "Classpath" exception as provided
aoqi@0: * by Oracle in the LICENSE file that accompanied this code.
aoqi@0: *
aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0: * accompanied this code).
aoqi@0: *
aoqi@0: * You should have received a copy of the GNU General Public License version
aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0: *
aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0: * or visit www.oracle.com if you need additional information or have any
aoqi@0: * questions.
aoqi@0: */
aoqi@0:
aoqi@0: package javax.xml.soap;
aoqi@0:
aoqi@0: import java.io.InputStream;
aoqi@0: import java.io.Reader;
aoqi@0: import java.util.Iterator;
aoqi@0:
aoqi@0: import javax.activation.DataHandler;
aoqi@0:
aoqi@0: /**
aoqi@0: * A single attachment to a SOAPMessage
object. A SOAPMessage
aoqi@0: * object may contain zero, one, or many AttachmentPart
objects.
aoqi@0: * Each AttachmentPart
object consists of two parts,
aoqi@0: * application-specific content and associated MIME headers. The
aoqi@0: * MIME headers consists of name/value pairs that can be used to
aoqi@0: * identify and describe the content.
aoqi@0: *
aoqi@0: * An AttachmentPart
object must conform to certain standards.
aoqi@0: *
Content-Type
AttachmentPart
object and MUST conform to [RFC2045].
aoqi@0: * The following is an example of a Content-Type header:
aoqi@0: * aoqi@0: * Content-Type: application/xml aoqi@0: *aoqi@0: * The following line of code, in which
ap
is an
aoqi@0: * AttachmentPart
object, sets the header shown in
aoqi@0: * the previous example.
aoqi@0: * aoqi@0: * ap.setMimeHeader("Content-Type", "application/xml"); aoqi@0: *aoqi@0: *
aoqi@0: *
aoqi@0: * There are no restrictions on the content portion of an
aoqi@0: * AttachmentPart
object. The content may be anything from a
aoqi@0: * simple plain text object to a complex XML document or image file.
aoqi@0: *
aoqi@0: *
aoqi@0: * An AttachmentPart
object is created with the method
aoqi@0: * SOAPMessage.createAttachmentPart
. After setting its MIME headers,
aoqi@0: * the AttachmentPart
object is added to the message
aoqi@0: * that created it with the method SOAPMessage.addAttachmentPart
.
aoqi@0: *
aoqi@0: *
aoqi@0: * The following code fragment, in which m
is a
aoqi@0: * SOAPMessage
object and contentStringl
is a
aoqi@0: * String
, creates an instance of AttachmentPart
,
aoqi@0: * sets the AttachmentPart
object with some content and
aoqi@0: * header information, and adds the AttachmentPart
object to
aoqi@0: * the SOAPMessage
object.
aoqi@0: *
aoqi@0: * AttachmentPart ap1 = m.createAttachmentPart(); aoqi@0: * ap1.setContent(contentString1, "text/plain"); aoqi@0: * m.addAttachmentPart(ap1); aoqi@0: *aoqi@0: * aoqi@0: * aoqi@0: *
aoqi@0: * The following code fragment creates and adds a second
aoqi@0: * AttachmentPart
instance to the same message. jpegData
aoqi@0: * is a binary byte buffer representing the jpeg file.
aoqi@0: *
aoqi@0: * AttachmentPart ap2 = m.createAttachmentPart(); aoqi@0: * byte[] jpegData = ...; aoqi@0: * ap2.setContent(new ByteArrayInputStream(jpegData), "image/jpeg"); aoqi@0: * m.addAttachmentPart(ap2); aoqi@0: *aoqi@0: *
aoqi@0: * The getContent
method retrieves the contents and header from
aoqi@0: * an AttachmentPart
object. Depending on the
aoqi@0: * DataContentHandler
objects present, the returned
aoqi@0: * Object
can either be a typed Java object corresponding
aoqi@0: * to the MIME type or an InputStream
object that contains the
aoqi@0: * content as bytes.
aoqi@0: *
aoqi@0: * String content1 = ap1.getContent(); aoqi@0: * java.io.InputStream content2 = ap2.getContent(); aoqi@0: *aoqi@0: * aoqi@0: * The method
clearContent
removes all the content from an
aoqi@0: * AttachmentPart
object but does not affect its header information.
aoqi@0: * aoqi@0: * ap1.clearContent(); aoqi@0: *aoqi@0: */ aoqi@0: aoqi@0: public abstract class AttachmentPart { aoqi@0: /** aoqi@0: * Returns the number of bytes in this
AttachmentPart
aoqi@0: * object.
aoqi@0: *
aoqi@0: * @return the size of this AttachmentPart
object in bytes
aoqi@0: * or -1 if the size cannot be determined
aoqi@0: * @exception SOAPException if the content of this attachment is
aoqi@0: * corrupted of if there was an exception while trying
aoqi@0: * to determine the size.
aoqi@0: */
aoqi@0: public abstract int getSize() throws SOAPException;
aoqi@0:
aoqi@0: /**
aoqi@0: * Clears out the content of this AttachmentPart
object.
aoqi@0: * The MIME header portion is left untouched.
aoqi@0: */
aoqi@0: public abstract void clearContent();
aoqi@0:
aoqi@0: /**
aoqi@0: * Gets the content of this AttachmentPart
object as a Java
aoqi@0: * object. The type of the returned Java object depends on (1) the
aoqi@0: * DataContentHandler
object that is used to interpret the bytes
aoqi@0: * and (2) the Content-Type
given in the header.
aoqi@0: *
aoqi@0: * For the MIME content types "text/plain", "text/html" and "text/xml", the
aoqi@0: * DataContentHandler
object does the conversions to and
aoqi@0: * from the Java types corresponding to the MIME types.
aoqi@0: * For other MIME types,the DataContentHandler
object
aoqi@0: * can return an InputStream
object that contains the content data
aoqi@0: * as raw bytes.
aoqi@0: *
aoqi@0: * A SAAJ-compliant implementation must, as a minimum, return a
aoqi@0: * java.lang.String
object corresponding to any content
aoqi@0: * stream with a Content-Type
value of
aoqi@0: * text/plain
, a
aoqi@0: * javax.xml.transform.stream.StreamSource
object corresponding to a
aoqi@0: * content stream with a Content-Type
value of
aoqi@0: * text/xml
, a java.awt.Image
object
aoqi@0: * corresponding to a content stream with a
aoqi@0: * Content-Type
value of image/gif
or
aoqi@0: * image/jpeg
. For those content types that an
aoqi@0: * installed DataContentHandler
object does not understand, the
aoqi@0: * DataContentHandler
object is required to return a
aoqi@0: * java.io.InputStream
object with the raw bytes.
aoqi@0: *
aoqi@0: * @return a Java object with the content of this AttachmentPart
aoqi@0: * object
aoqi@0: *
aoqi@0: * @exception SOAPException if there is no content set into this
aoqi@0: * AttachmentPart
object or if there was a data
aoqi@0: * transformation error
aoqi@0: */
aoqi@0: public abstract Object getContent() throws SOAPException;
aoqi@0:
aoqi@0: /**
aoqi@0: * Gets the content of this AttachmentPart
object as an
aoqi@0: * InputStream as if a call had been made to getContent
and no
aoqi@0: * DataContentHandler
had been registered for the
aoqi@0: * content-type
of this AttachmentPart
.
aoqi@0: *
aoqi@0: * Note that reading from the returned InputStream would result in consuming
aoqi@0: * the data in the stream. It is the responsibility of the caller to reset
aoqi@0: * the InputStream appropriately before calling a Subsequent API. If a copy
aoqi@0: * of the raw attachment content is required then the {@link #getRawContentBytes} API
aoqi@0: * should be used instead.
aoqi@0: *
aoqi@0: * @return an InputStream
from which the raw data contained by
aoqi@0: * the AttachmentPart
can be accessed.
aoqi@0: *
aoqi@0: * @throws SOAPException if there is no content set into this
aoqi@0: * AttachmentPart
object or if there was a data
aoqi@0: * transformation error.
aoqi@0: *
aoqi@0: * @since SAAJ 1.3
aoqi@0: * @see #getRawContentBytes
aoqi@0: */
aoqi@0: public abstract InputStream getRawContent() throws SOAPException;
aoqi@0:
aoqi@0: /**
aoqi@0: * Gets the content of this AttachmentPart
object as a
aoqi@0: * byte[] array as if a call had been made to getContent
and no
aoqi@0: * DataContentHandler
had been registered for the
aoqi@0: * content-type
of this AttachmentPart
.
aoqi@0: *
aoqi@0: * @return a byte[]
array containing the raw data of the
aoqi@0: * AttachmentPart
.
aoqi@0: *
aoqi@0: * @throws SOAPException if there is no content set into this
aoqi@0: * AttachmentPart
object or if there was a data
aoqi@0: * transformation error.
aoqi@0: *
aoqi@0: * @since SAAJ 1.3
aoqi@0: */
aoqi@0: public abstract byte[] getRawContentBytes() throws SOAPException;
aoqi@0:
aoqi@0: /**
aoqi@0: * Returns an InputStream
which can be used to obtain the
aoqi@0: * content of AttachmentPart
as Base64 encoded
aoqi@0: * character data, this method would base64 encode the raw bytes
aoqi@0: * of the attachment and return.
aoqi@0: *
aoqi@0: * @return an InputStream
from which the Base64 encoded
aoqi@0: * AttachmentPart
can be read.
aoqi@0: *
aoqi@0: * @throws SOAPException if there is no content set into this
aoqi@0: * AttachmentPart
object or if there was a data
aoqi@0: * transformation error.
aoqi@0: *
aoqi@0: * @since SAAJ 1.3
aoqi@0: */
aoqi@0: public abstract InputStream getBase64Content() throws SOAPException;
aoqi@0:
aoqi@0: /**
aoqi@0: * Sets the content of this attachment part to that of the given
aoqi@0: * Object
and sets the value of the Content-Type
aoqi@0: * header to the given type. The type of the
aoqi@0: * Object
should correspond to the value given for the
aoqi@0: * Content-Type
. This depends on the particular
aoqi@0: * set of DataContentHandler
objects in use.
aoqi@0: *
aoqi@0: *
aoqi@0: * @param object the Java object that makes up the content for
aoqi@0: * this attachment part
aoqi@0: * @param contentType the MIME string that specifies the type of
aoqi@0: * the content
aoqi@0: *
aoqi@0: * @exception IllegalArgumentException may be thrown if the contentType
aoqi@0: * does not match the type of the content object, or if there
aoqi@0: * was no DataContentHandler
object for this
aoqi@0: * content object
aoqi@0: *
aoqi@0: * @see #getContent
aoqi@0: */
aoqi@0: public abstract void setContent(Object object, String contentType);
aoqi@0:
aoqi@0: /**
aoqi@0: * Sets the content of this attachment part to that contained by the
aoqi@0: * InputStream
content
and sets the value of the
aoqi@0: * Content-Type
header to the value contained in
aoqi@0: * contentType
.
aoqi@0: *
aoqi@0: * A subsequent call to getSize() may not be an exact measure
aoqi@0: * of the content size.
aoqi@0: *
aoqi@0: * @param content the raw data to add to the attachment part
aoqi@0: * @param contentType the value to set into the Content-Type
aoqi@0: * header
aoqi@0: *
aoqi@0: * @exception SOAPException if an there is an error in setting the content
aoqi@0: * @exception NullPointerException if content
is null
aoqi@0: * @since SAAJ 1.3
aoqi@0: */
aoqi@0: public abstract void setRawContent(InputStream content, String contentType) throws SOAPException;
aoqi@0:
aoqi@0: /**
aoqi@0: * Sets the content of this attachment part to that contained by the
aoqi@0: * byte[]
array content
and sets the value of the
aoqi@0: * Content-Type
header to the value contained in
aoqi@0: * contentType
.
aoqi@0: *
aoqi@0: * @param content the raw data to add to the attachment part
aoqi@0: * @param contentType the value to set into the Content-Type
aoqi@0: * header
aoqi@0: * @param offset the offset in the byte array of the content
aoqi@0: * @param len the number of bytes that form the content
aoqi@0: *
aoqi@0: * @exception SOAPException if an there is an error in setting the content
aoqi@0: * or content is null
aoqi@0: * @since SAAJ 1.3
aoqi@0: */
aoqi@0: public abstract void setRawContentBytes(
aoqi@0: byte[] content, int offset, int len, String contentType)
aoqi@0: throws SOAPException;
aoqi@0:
aoqi@0:
aoqi@0: /**
aoqi@0: * Sets the content of this attachment part from the Base64 source
aoqi@0: * InputStream
and sets the value of the
aoqi@0: * Content-Type
header to the value contained in
aoqi@0: * contentType
, This method would first decode the base64
aoqi@0: * input and write the resulting raw bytes to the attachment.
aoqi@0: *
aoqi@0: * A subsequent call to getSize() may not be an exact measure
aoqi@0: * of the content size.
aoqi@0: *
aoqi@0: * @param content the base64 encoded data to add to the attachment part
aoqi@0: * @param contentType the value to set into the Content-Type
aoqi@0: * header
aoqi@0: *
aoqi@0: * @exception SOAPException if an there is an error in setting the content
aoqi@0: * @exception NullPointerException if content
is null
aoqi@0: *
aoqi@0: * @since SAAJ 1.3
aoqi@0: */
aoqi@0: public abstract void setBase64Content(
aoqi@0: InputStream content, String contentType) throws SOAPException;
aoqi@0:
aoqi@0:
aoqi@0: /**
aoqi@0: * Gets the DataHandler
object for this AttachmentPart
aoqi@0: * object.
aoqi@0: *
aoqi@0: * @return the DataHandler
object associated with this
aoqi@0: * AttachmentPart
object
aoqi@0: *
aoqi@0: * @exception SOAPException if there is no data in
aoqi@0: * this AttachmentPart
object
aoqi@0: */
aoqi@0: public abstract DataHandler getDataHandler()
aoqi@0: throws SOAPException;
aoqi@0:
aoqi@0: /**
aoqi@0: * Sets the given DataHandler
object as the data handler
aoqi@0: * for this AttachmentPart
object. Typically, on an incoming
aoqi@0: * message, the data handler is automatically set. When
aoqi@0: * a message is being created and populated with content, the
aoqi@0: * setDataHandler
method can be used to get data from
aoqi@0: * various data sources into the message.
aoqi@0: *
aoqi@0: * @param dataHandler the DataHandler
object to be set
aoqi@0: *
aoqi@0: * @exception IllegalArgumentException if there was a problem with
aoqi@0: * the specified DataHandler
object
aoqi@0: */
aoqi@0: public abstract void setDataHandler(DataHandler dataHandler);
aoqi@0:
aoqi@0:
aoqi@0: /**
aoqi@0: * Gets the value of the MIME header whose name is "Content-ID".
aoqi@0: *
aoqi@0: * @return a String
giving the value of the
aoqi@0: * "Content-ID" header or null
if there
aoqi@0: * is none
aoqi@0: * @see #setContentId
aoqi@0: */
aoqi@0: public String getContentId() {
aoqi@0: String[] values = getMimeHeader("Content-ID");
aoqi@0: if (values != null && values.length > 0)
aoqi@0: return values[0];
aoqi@0: return null;
aoqi@0: }
aoqi@0:
aoqi@0: /**
aoqi@0: * Gets the value of the MIME header whose name is "Content-Location".
aoqi@0: *
aoqi@0: * @return a String
giving the value of the
aoqi@0: * "Content-Location" header or null
if there
aoqi@0: * is none
aoqi@0: */
aoqi@0: public String getContentLocation() {
aoqi@0: String[] values = getMimeHeader("Content-Location");
aoqi@0: if (values != null && values.length > 0)
aoqi@0: return values[0];
aoqi@0: return null;
aoqi@0: }
aoqi@0:
aoqi@0: /**
aoqi@0: * Gets the value of the MIME header whose name is "Content-Type".
aoqi@0: *
aoqi@0: * @return a String
giving the value of the
aoqi@0: * "Content-Type" header or null
if there
aoqi@0: * is none
aoqi@0: */
aoqi@0: public String getContentType() {
aoqi@0: String[] values = getMimeHeader("Content-Type");
aoqi@0: if (values != null && values.length > 0)
aoqi@0: return values[0];
aoqi@0: return null;
aoqi@0: }
aoqi@0:
aoqi@0: /**
aoqi@0: * Sets the MIME header whose name is "Content-ID" with the given value.
aoqi@0: *
aoqi@0: * @param contentId a String
giving the value of the
aoqi@0: * "Content-ID" header
aoqi@0: *
aoqi@0: * @exception IllegalArgumentException if there was a problem with
aoqi@0: * the specified contentId
value
aoqi@0: * @see #getContentId
aoqi@0: */
aoqi@0: public void setContentId(String contentId)
aoqi@0: {
aoqi@0: setMimeHeader("Content-ID", contentId);
aoqi@0: }
aoqi@0:
aoqi@0:
aoqi@0: /**
aoqi@0: * Sets the MIME header whose name is "Content-Location" with the given value.
aoqi@0: *
aoqi@0: *
aoqi@0: * @param contentLocation a String
giving the value of the
aoqi@0: * "Content-Location" header
aoqi@0: * @exception IllegalArgumentException if there was a problem with
aoqi@0: * the specified content location
aoqi@0: */
aoqi@0: public void setContentLocation(String contentLocation)
aoqi@0: {
aoqi@0: setMimeHeader("Content-Location", contentLocation);
aoqi@0: }
aoqi@0:
aoqi@0: /**
aoqi@0: * Sets the MIME header whose name is "Content-Type" with the given value.
aoqi@0: *
aoqi@0: * @param contentType a String
giving the value of the
aoqi@0: * "Content-Type" header
aoqi@0: *
aoqi@0: * @exception IllegalArgumentException if there was a problem with
aoqi@0: * the specified content type
aoqi@0: */
aoqi@0: public void setContentType(String contentType)
aoqi@0: {
aoqi@0: setMimeHeader("Content-Type", contentType);
aoqi@0: }
aoqi@0:
aoqi@0: /**
aoqi@0: * Removes all MIME headers that match the given name.
aoqi@0: *
aoqi@0: * @param header the string name of the MIME header/s to
aoqi@0: * be removed
aoqi@0: */
aoqi@0: public abstract void removeMimeHeader(String header);
aoqi@0:
aoqi@0: /**
aoqi@0: * Removes all the MIME header entries.
aoqi@0: */
aoqi@0: public abstract void removeAllMimeHeaders();
aoqi@0:
aoqi@0:
aoqi@0: /**
aoqi@0: * Gets all the values of the header identified by the given
aoqi@0: * String
.
aoqi@0: *
aoqi@0: * @param name the name of the header; example: "Content-Type"
aoqi@0: * @return a String
array giving the value for the
aoqi@0: * specified header
aoqi@0: * @see #setMimeHeader
aoqi@0: */
aoqi@0: public abstract String[] getMimeHeader(String name);
aoqi@0:
aoqi@0:
aoqi@0: /**
aoqi@0: * Changes the first header entry that matches the given name
aoqi@0: * to the given value, adding a new header if no existing header
aoqi@0: * matches. This method also removes all matching headers but the first.
aoqi@0: *
aoqi@0: * Note that RFC822 headers can only contain US-ASCII characters.
aoqi@0: *
aoqi@0: * @param name a String
giving the name of the header
aoqi@0: * for which to search
aoqi@0: * @param value a String
giving the value to be set for
aoqi@0: * the header whose name matches the given name
aoqi@0: *
aoqi@0: * @exception IllegalArgumentException if there was a problem with
aoqi@0: * the specified mime header name or value
aoqi@0: */
aoqi@0: public abstract void setMimeHeader(String name, String value);
aoqi@0:
aoqi@0:
aoqi@0: /**
aoqi@0: * Adds a MIME header with the specified name and value to this
aoqi@0: * AttachmentPart
object.
aoqi@0: *
aoqi@0: * Note that RFC822 headers can contain only US-ASCII characters.
aoqi@0: *
aoqi@0: * @param name a String
giving the name of the header
aoqi@0: * to be added
aoqi@0: * @param value a String
giving the value of the header
aoqi@0: * to be added
aoqi@0: *
aoqi@0: * @exception IllegalArgumentException if there was a problem with
aoqi@0: * the specified mime header name or value
aoqi@0: */
aoqi@0: public abstract void addMimeHeader(String name, String value);
aoqi@0:
aoqi@0: /**
aoqi@0: * Retrieves all the headers for this AttachmentPart
object
aoqi@0: * as an iterator over the MimeHeader
objects.
aoqi@0: *
aoqi@0: * @return an Iterator
object with all of the Mime
aoqi@0: * headers for this AttachmentPart
object
aoqi@0: */
aoqi@0: public abstract Iterator getAllMimeHeaders();
aoqi@0:
aoqi@0: /**
aoqi@0: * Retrieves all MimeHeader
objects that match a name in
aoqi@0: * the given array.
aoqi@0: *
aoqi@0: * @param names a String
array with the name(s) of the
aoqi@0: * MIME headers to be returned
aoqi@0: * @return all of the MIME headers that match one of the names in the
aoqi@0: * given array as an Iterator
object
aoqi@0: */
aoqi@0: public abstract Iterator getMatchingMimeHeaders(String[] names);
aoqi@0:
aoqi@0: /**
aoqi@0: * Retrieves all MimeHeader
objects whose name does
aoqi@0: * not match a name in the given array.
aoqi@0: *
aoqi@0: * @param names a String
array with the name(s) of the
aoqi@0: * MIME headers not to be returned
aoqi@0: * @return all of the MIME headers in this AttachmentPart
object
aoqi@0: * except those that match one of the names in the
aoqi@0: * given array. The nonmatching MIME headers are returned as an
aoqi@0: * Iterator
object.
aoqi@0: */
aoqi@0: public abstract Iterator getNonMatchingMimeHeaders(String[] names);
aoqi@0: }