001: /*
002: * $Id: AttachmentPart.java,v 1.13 2006/03/30 00:59:38 ofung Exp $
003: * $Revision: 1.13 $
004: * $Date: 2006/03/30 00:59:38 $
005: */
006:
007: /*
008: * The contents of this file are subject to the terms
009: * of the Common Development and Distribution License
010: * (the License). You may not use this file except in
011: * compliance with the License.
012: *
013: * You can obtain a copy of the license at
014: * https://glassfish.dev.java.net/public/CDDLv1.0.html.
015: * See the License for the specific language governing
016: * permissions and limitations under the License.
017: *
018: * When distributing Covered Code, include this CDDL
019: * Header Notice in each file and include the License file
020: * at https://glassfish.dev.java.net/public/CDDLv1.0.html.
021: * If applicable, add the following below the CDDL Header,
022: * with the fields enclosed by brackets [] replaced by
023: * you own identifying information:
024: * "Portions Copyrighted [year] [name of copyright owner]"
025: *
026: * Copyright 2006 Sun Microsystems Inc. All Rights Reserved
027: */
028: package javax.xml.soap;
029:
030: import java.io.InputStream;
031: import java.io.Reader;
032: import java.util.Iterator;
033:
034: import javax.activation.DataHandler;
035:
036: /**
037: * A single attachment to a <code>SOAPMessage</code> object. A <code>SOAPMessage</code>
038: * object may contain zero, one, or many <code>AttachmentPart</code> objects.
039: * Each <code>AttachmentPart</code> object consists of two parts,
040: * application-specific content and associated MIME headers. The
041: * MIME headers consists of name/value pairs that can be used to
042: * identify and describe the content.
043: * <p>
044: * An <code>AttachmentPart</code> object must conform to certain standards.
045: * <OL>
046: * <LI>It must conform to <a href="http://www.ietf.org/rfc/rfc2045.txt">
047: * MIME [RFC2045] standards</a>
048: * <LI>It MUST contain content
049: * <LI>The header portion MUST include the following header:
050: * <UL>
051: * <LI><code>Content-Type</code><br>
052: * This header identifies the type of data in the content of an
053: * <code>AttachmentPart</code> object and MUST conform to [RFC2045].
054: * The following is an example of a Content-Type header:
055: * <PRE>
056: * Content-Type: application/xml
057: * </PRE>
058: * The following line of code, in which <code>ap</code> is an
059: * <code>AttachmentPart</code> object, sets the header shown in
060: * the previous example.
061: * <PRE>
062: * ap.setMimeHeader("Content-Type", "application/xml");
063: * </PRE>
064: * <p>
065: * </UL>
066: * </OL>
067: * <p>
068: * There are no restrictions on the content portion of an <code>
069: * AttachmentPart</code> object. The content may be anything from a
070: * simple plain text object to a complex XML document or image file.
071: *
072: * <p>
073: * An <code>AttachmentPart</code> object is created with the method
074: * <code>SOAPMessage.createAttachmentPart</code>. After setting its MIME headers,
075: * the <code>AttachmentPart</code> object is added to the message
076: * that created it with the method <code>SOAPMessage.addAttachmentPart</code>.
077: *
078: * <p>
079: * The following code fragment, in which <code>m</code> is a
080: * <code>SOAPMessage</code> object and <code>contentStringl</code> is a
081: * <code>String</code>, creates an instance of <code>AttachmentPart</code>,
082: * sets the <code>AttachmentPart</code> object with some content and
083: * header information, and adds the <code>AttachmentPart</code> object to
084: * the <code>SOAPMessage</code> object.
085: * <PRE>
086: * AttachmentPart ap1 = m.createAttachmentPart();
087: * ap1.setContent(contentString1, "text/plain");
088: * m.addAttachmentPart(ap1);
089: * </PRE>
090: *
091: *
092: * <p>
093: * The following code fragment creates and adds a second
094: * <code>AttachmentPart</code> instance to the same message. <code>jpegData</code>
095: * is a binary byte buffer representing the jpeg file.
096: * <PRE>
097: * AttachmentPart ap2 = m.createAttachmentPart();
098: * byte[] jpegData = ...;
099: * ap2.setContent(new ByteArrayInputStream(jpegData), "image/jpeg");
100: * m.addAttachmentPart(ap2);
101: * </PRE>
102: * <p>
103: * The <code>getContent</code> method retrieves the contents and header from
104: * an <code>AttachmentPart</code> object. Depending on the
105: * <code>DataContentHandler</code> objects present, the returned
106: * <code>Object</code> can either be a typed Java object corresponding
107: * to the MIME type or an <code>InputStream</code> object that contains the
108: * content as bytes.
109: * <PRE>
110: * String content1 = ap1.getContent();
111: * java.io.InputStream content2 = ap2.getContent();
112: * </PRE>
113: *
114: * The method <code>clearContent</code> removes all the content from an
115: * <code>AttachmentPart</code> object but does not affect its header information.
116: * <PRE>
117: * ap1.clearContent();
118: * </PRE>
119: */
120:
121: public abstract class AttachmentPart {
122: /**
123: * Returns the number of bytes in this <code>AttachmentPart</code>
124: * object.
125: *
126: * @return the size of this <code>AttachmentPart</code> object in bytes
127: * or -1 if the size cannot be determined
128: * @exception SOAPException if the content of this attachment is
129: * corrupted of if there was an exception while trying
130: * to determine the size.
131: */
132: public abstract int getSize() throws SOAPException;
133:
134: /**
135: * Clears out the content of this <code>AttachmentPart</code> object.
136: * The MIME header portion is left untouched.
137: */
138: public abstract void clearContent();
139:
140: /**
141: * Gets the content of this <code>AttachmentPart</code> object as a Java
142: * object. The type of the returned Java object depends on (1) the
143: * <code>DataContentHandler</code> object that is used to interpret the bytes
144: * and (2) the <code>Content-Type</code> given in the header.
145: * <p>
146: * For the MIME content types "text/plain", "text/html" and "text/xml", the
147: * <code>DataContentHandler</code> object does the conversions to and
148: * from the Java types corresponding to the MIME types.
149: * For other MIME types,the <code>DataContentHandler</code> object
150: * can return an <code>InputStream</code> object that contains the content data
151: * as raw bytes.
152: * <p>
153: * A SAAJ-compliant implementation must, as a minimum, return a
154: * <code>java.lang.String</code> object corresponding to any content
155: * stream with a <code>Content-Type</code> value of
156: * <code>text/plain</code>, a
157: * <code>javax.xml.transform.stream.StreamSource</code> object corresponding to a
158: * content stream with a <code>Content-Type</code> value of
159: * <code>text/xml</code>, a <code>java.awt.Image</code> object
160: * corresponding to a content stream with a
161: * <code>Content-Type</code> value of <code>image/gif</code> or
162: * <code>image/jpeg</code>. For those content types that an
163: * installed <code>DataContentHandler</code> object does not understand, the
164: * <code>DataContentHandler</code> object is required to return a
165: * <code>java.io.InputStream</code> object with the raw bytes.
166: *
167: * @return a Java object with the content of this <code>AttachmentPart</code>
168: * object
169: *
170: * @exception SOAPException if there is no content set into this
171: * <code>AttachmentPart</code> object or if there was a data
172: * transformation error
173: */
174: public abstract Object getContent() throws SOAPException;
175:
176: /**
177: * Gets the content of this <code>AttachmentPart</code> object as an
178: * InputStream as if a call had been made to <code>getContent</code> and no
179: * <code>DataContentHandler</code> had been registered for the
180: * <code>content-type</code> of this <code>AttachmentPart</code>.
181: *<p>
182: * Note that reading from the returned InputStream would result in consuming
183: * the data in the stream. It is the responsibility of the caller to reset
184: * the InputStream appropriately before calling a Subsequent API. If a copy
185: * of the raw attachment content is required then the {@link #getRawContentBytes} API
186: * should be used instead.
187: *
188: * @return an <code>InputStream</code> from which the raw data contained by
189: * the <code>AttachmentPart</code> can be accessed.
190: *
191: * @throws SOAPException if there is no content set into this
192: * <code>AttachmentPart</code> object or if there was a data
193: * transformation error.
194: *
195: * @since SAAJ 1.3
196: * @see #getRawContentBytes
197: */
198: public abstract InputStream getRawContent() throws SOAPException;
199:
200: /**
201: * Gets the content of this <code>AttachmentPart</code> object as a
202: * byte[] array as if a call had been made to <code>getContent</code> and no
203: * <code>DataContentHandler</code> had been registered for the
204: * <code>content-type</code> of this <code>AttachmentPart</code>.
205: *
206: * @return a <code>byte[]</code> array containing the raw data of the
207: * <code>AttachmentPart</code>.
208: *
209: * @throws SOAPException if there is no content set into this
210: * <code>AttachmentPart</code> object or if there was a data
211: * transformation error.
212: *
213: * @since SAAJ 1.3
214: */
215: public abstract byte[] getRawContentBytes() throws SOAPException;
216:
217: /**
218: * Returns an <code>InputStream</code> which can be used to obtain the
219: * content of <code>AttachmentPart</code> as Base64 encoded
220: * character data, this method would base64 encode the raw bytes
221: * of the attachment and return.
222: *
223: * @return an <code>InputStream</code> from which the Base64 encoded
224: * <code>AttachmentPart</code> can be read.
225: *
226: * @throws SOAPException if there is no content set into this
227: * <code>AttachmentPart</code> object or if there was a data
228: * transformation error.
229: *
230: * @since SAAJ 1.3
231: */
232: public abstract InputStream getBase64Content() throws SOAPException;
233:
234: /**
235: * Sets the content of this attachment part to that of the given
236: * <code>Object</code> and sets the value of the <code>Content-Type</code>
237: * header to the given type. The type of the
238: * <code>Object</code> should correspond to the value given for the
239: * <code>Content-Type</code>. This depends on the particular
240: * set of <code>DataContentHandler</code> objects in use.
241: *
242: *
243: * @param object the Java object that makes up the content for
244: * this attachment part
245: * @param contentType the MIME string that specifies the type of
246: * the content
247: *
248: * @exception IllegalArgumentException may be thrown if the contentType
249: * does not match the type of the content object, or if there
250: * was no <code>DataContentHandler</code> object for this
251: * content object
252: *
253: * @see #getContent
254: */
255: public abstract void setContent(Object object, String contentType);
256:
257: /**
258: * Sets the content of this attachment part to that contained by the
259: * <code>InputStream</code> <code>content</code> and sets the value of the
260: * <code>Content-Type</code> header to the value contained in
261: * <code>contentType</code>.
262: * <P>
263: * A subsequent call to getSize() may not be an exact measure
264: * of the content size.
265: *
266: * @param content the raw data to add to the attachment part
267: * @param contentType the value to set into the <code>Content-Type</code>
268: * header
269: *
270: * @exception SOAPException if an there is an error in setting the content
271: * @exception NullPointerException if <code>content</code> is null
272: * @since SAAJ 1.3
273: */
274: public abstract void setRawContent(InputStream content,
275: String contentType) throws SOAPException;
276:
277: /**
278: * Sets the content of this attachment part to that contained by the
279: * <code>byte[]</code> array <code>content</code> and sets the value of the
280: * <code>Content-Type</code> header to the value contained in
281: * <code>contentType</code>.
282: *
283: * @param content the raw data to add to the attachment part
284: * @param contentType the value to set into the <code>Content-Type</code>
285: * header
286: * @param offset the offset in the byte array of the content
287: * @param len the number of bytes that form the content
288: *
289: * @exception SOAPException if an there is an error in setting the content
290: * or content is null
291: * @since SAAJ 1.3
292: */
293: public abstract void setRawContentBytes(byte[] content, int offset,
294: int len, String contentType) throws SOAPException;
295:
296: /**
297: * Sets the content of this attachment part from the Base64 source
298: * <code>InputStream</code> and sets the value of the
299: * <code>Content-Type</code> header to the value contained in
300: * <code>contentType</code>, This method would first decode the base64
301: * input and write the resulting raw bytes to the attachment.
302: * <P>
303: * A subsequent call to getSize() may not be an exact measure
304: * of the content size.
305: *
306: * @param content the base64 encoded data to add to the attachment part
307: * @param contentType the value to set into the <code>Content-Type</code>
308: * header
309: *
310: * @exception SOAPException if an there is an error in setting the content
311: * @exception NullPointerException if <code>content</code> is null
312: *
313: * @since SAAJ 1.3
314: */
315: public abstract void setBase64Content(InputStream content,
316: String contentType) throws SOAPException;
317:
318: /**
319: * Gets the <code>DataHandler</code> object for this <code>AttachmentPart</code>
320: * object.
321: *
322: * @return the <code>DataHandler</code> object associated with this
323: * <code>AttachmentPart</code> object
324: *
325: * @exception SOAPException if there is no data in
326: * this <code>AttachmentPart</code> object
327: */
328: public abstract DataHandler getDataHandler() throws SOAPException;
329:
330: /**
331: * Sets the given <code>DataHandler</code> object as the data handler
332: * for this <code>AttachmentPart</code> object. Typically, on an incoming
333: * message, the data handler is automatically set. When
334: * a message is being created and populated with content, the
335: * <code>setDataHandler</code> method can be used to get data from
336: * various data sources into the message.
337: *
338: * @param dataHandler the <code>DataHandler</code> object to be set
339: *
340: * @exception IllegalArgumentException if there was a problem with
341: * the specified <code>DataHandler</code> object
342: */
343: public abstract void setDataHandler(DataHandler dataHandler);
344:
345: /**
346: * Gets the value of the MIME header whose name is "Content-ID".
347: *
348: * @return a <code>String</code> giving the value of the
349: * "Content-ID" header or <code>null</code> if there
350: * is none
351: * @see #setContentId
352: */
353: public String getContentId() {
354: String[] values = getMimeHeader("Content-ID");
355: if (values != null && values.length > 0)
356: return values[0];
357: return null;
358: }
359:
360: /**
361: * Gets the value of the MIME header whose name is "Content-Location".
362: *
363: * @return a <code>String</code> giving the value of the
364: * "Content-Location" header or <code>null</code> if there
365: * is none
366: */
367: public String getContentLocation() {
368: String[] values = getMimeHeader("Content-Location");
369: if (values != null && values.length > 0)
370: return values[0];
371: return null;
372: }
373:
374: /**
375: * Gets the value of the MIME header whose name is "Content-Type".
376: *
377: * @return a <code>String</code> giving the value of the
378: * "Content-Type" header or <code>null</code> if there
379: * is none
380: */
381: public String getContentType() {
382: String[] values = getMimeHeader("Content-Type");
383: if (values != null && values.length > 0)
384: return values[0];
385: return null;
386: }
387:
388: /**
389: * Sets the MIME header whose name is "Content-ID" with the given value.
390: *
391: * @param contentId a <code>String</code> giving the value of the
392: * "Content-ID" header
393: *
394: * @exception IllegalArgumentException if there was a problem with
395: * the specified <code>contentId</code> value
396: * @see #getContentId
397: */
398: public void setContentId(String contentId) {
399: setMimeHeader("Content-ID", contentId);
400: }
401:
402: /**
403: * Sets the MIME header whose name is "Content-Location" with the given value.
404: *
405: *
406: * @param contentLocation a <code>String</code> giving the value of the
407: * "Content-Location" header
408: * @exception IllegalArgumentException if there was a problem with
409: * the specified content location
410: */
411: public void setContentLocation(String contentLocation) {
412: setMimeHeader("Content-Location", contentLocation);
413: }
414:
415: /**
416: * Sets the MIME header whose name is "Content-Type" with the given value.
417: *
418: * @param contentType a <code>String</code> giving the value of the
419: * "Content-Type" header
420: *
421: * @exception IllegalArgumentException if there was a problem with
422: * the specified content type
423: */
424: public void setContentType(String contentType) {
425: setMimeHeader("Content-Type", contentType);
426: }
427:
428: /**
429: * Removes all MIME headers that match the given name.
430: *
431: * @param header the string name of the MIME header/s to
432: * be removed
433: */
434: public abstract void removeMimeHeader(String header);
435:
436: /**
437: * Removes all the MIME header entries.
438: */
439: public abstract void removeAllMimeHeaders();
440:
441: /**
442: * Gets all the values of the header identified by the given
443: * <code>String</code>.
444: *
445: * @param name the name of the header; example: "Content-Type"
446: * @return a <code>String</code> array giving the value for the
447: * specified header
448: * @see #setMimeHeader
449: */
450: public abstract String[] getMimeHeader(String name);
451:
452: /**
453: * Changes the first header entry that matches the given name
454: * to the given value, adding a new header if no existing header
455: * matches. This method also removes all matching headers but the first. <p>
456: *
457: * Note that RFC822 headers can only contain US-ASCII characters.
458: *
459: * @param name a <code>String</code> giving the name of the header
460: * for which to search
461: * @param value a <code>String</code> giving the value to be set for
462: * the header whose name matches the given name
463: *
464: * @exception IllegalArgumentException if there was a problem with
465: * the specified mime header name or value
466: */
467: public abstract void setMimeHeader(String name, String value);
468:
469: /**
470: * Adds a MIME header with the specified name and value to this
471: * <code>AttachmentPart</code> object.
472: * <p>
473: * Note that RFC822 headers can contain only US-ASCII characters.
474: *
475: * @param name a <code>String</code> giving the name of the header
476: * to be added
477: * @param value a <code>String</code> giving the value of the header
478: * to be added
479: *
480: * @exception IllegalArgumentException if there was a problem with
481: * the specified mime header name or value
482: */
483: public abstract void addMimeHeader(String name, String value);
484:
485: /**
486: * Retrieves all the headers for this <code>AttachmentPart</code> object
487: * as an iterator over the <code>MimeHeader</code> objects.
488: *
489: * @return an <code>Iterator</code> object with all of the Mime
490: * headers for this <code>AttachmentPart</code> object
491: */
492: public abstract Iterator getAllMimeHeaders();
493:
494: /**
495: * Retrieves all <code>MimeHeader</code> objects that match a name in
496: * the given array.
497: *
498: * @param names a <code>String</code> array with the name(s) of the
499: * MIME headers to be returned
500: * @return all of the MIME headers that match one of the names in the
501: * given array as an <code>Iterator</code> object
502: */
503: public abstract Iterator getMatchingMimeHeaders(String[] names);
504:
505: /**
506: * Retrieves all <code>MimeHeader</code> objects whose name does
507: * not match a name in the given array.
508: *
509: * @param names a <code>String</code> array with the name(s) of the
510: * MIME headers not to be returned
511: * @return all of the MIME headers in this <code>AttachmentPart</code> object
512: * except those that match one of the names in the
513: * given array. The nonmatching MIME headers are returned as an
514: * <code>Iterator</code> object.
515: */
516: public abstract Iterator getNonMatchingMimeHeaders(String[] names);
517: }
|