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