View Javadoc

1   /*
2    * Copyright 2001-2004 The Apache Software Foundation.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package javax.xml.soap;
17  
18  import javax.activation.DataHandler;
19  import java.util.Iterator;
20  
21  /**
22   * <P>A single attachment to a <CODE>SOAPMessage</CODE> object. A
23   *   <CODE>SOAPMessage</CODE> object may contain zero, one, or many
24   *   <CODE>AttachmentPart</CODE> objects. Each <CODE>
25   *   AttachmentPart</CODE> object consists of two parts,
26   *   application-specific content and associated MIME headers. The
27   *   MIME headers consists of name/value pairs that can be used to
28   *   identify and describe the content.</P>
29   *
30   *   <P>An <CODE>AttachmentPart</CODE> object must conform to
31   *   certain standards.</P>
32   *
33   *   <OL>
34   *     <LI>It must conform to <A href=
35   *     "http://www.ietf.org/rfc/rfc2045.txt">MIME [RFC2045]
36   *     standards</A></LI>
37   *
38   *     <LI>It MUST contain content</LI>
39   *
40   *     <LI>
41   *       The header portion MUST include the following header:
42   *
43   *       <UL>
44   *         <LI>
45   *           <CODE>Content-Type</CODE><BR>
46   *            This header identifies the type of data in the content
47   *           of an <CODE>AttachmentPart</CODE> object and MUST
48   *           conform to [RFC2045]. The following is an example of a
49   *           Content-Type header:
50   * <PRE>
51   *      Content-Type:  application/xml
52   *
53   * </PRE>
54   *           The following line of code, in which <CODE>ap</CODE> is
55   *           an <CODE>AttachmentPart</CODE> object, sets the header
56   *           shown in the previous example.
57   * <PRE>
58   *      ap.setMimeHeader("Content-Type", "application/xml");
59   *
60   * </PRE>
61   *
62   *           <P></P>
63   *         </LI>
64   *       </UL>
65   *     </LI>
66   *   </OL>
67   *
68   *   <P>There are no restrictions on the content portion of an
69   *   <CODE>AttachmentPart</CODE> object. The content may be anything
70   *   from a simple plain text object to a complex XML document or
71   *   image file.</P>
72   *
73   *   <P>An <CODE>AttachmentPart</CODE> object is created with the
74   *   method <CODE>SOAPMessage.createAttachmentPart</CODE>. After
75   *   setting its MIME headers, the <CODE>AttachmentPart</CODE>
76   *   object is added to the message that created it with the method
77   *   <CODE>SOAPMessage.addAttachmentPart</CODE>.</P>
78   *
79   *   <P>The following code fragment, in which <CODE>m</CODE> is a
80   *   <CODE>SOAPMessage</CODE> object and <CODE>contentStringl</CODE>
81   *   is a <CODE>String</CODE>, creates an instance of <CODE>
82   *   AttachmentPart</CODE>, sets the <CODE>AttachmentPart</CODE>
83   *   object with some content and header information, and adds the
84   *   <CODE>AttachmentPart</CODE> object to the <CODE>
85   *   SOAPMessage</CODE> object.</P>
86   * <PRE>
87   *    AttachmentPart ap1 = m.createAttachmentPart();
88   *    ap1.setContent(contentString1, "text/plain");
89   *    m.addAttachmentPart(ap1);
90   * </PRE>
91   *
92   *   <P>The following code fragment creates and adds a second <CODE>
93   *   AttachmentPart</CODE> instance to the same message. <CODE>
94   *   jpegData</CODE> is a binary byte buffer representing the jpeg
95   *   file.</P>
96   * <PRE>
97   *    AttachmentPart ap2 = m.createAttachmentPart();
98   *    byte[] jpegData =  ...;
99   *    ap2.setContent(new ByteArrayInputStream(jpegData), "image/jpeg");
100  *    m.addAttachmentPart(ap2);
101  * </PRE>
102  *
103  *   <P>The <CODE>getContent</CODE> method retrieves the contents
104  *   and header from an <CODE>AttachmentPart</CODE> object.
105  *   Depending on the <CODE>DataContentHandler</CODE> objects
106  *   present, the returned <CODE>Object</CODE> can either be a typed
107  *   Java object corresponding to the MIME type or an <CODE>
108  *   InputStream</CODE> object that contains the content as
109  *   bytes.</P>
110  * <PRE>
111  *    String content1 = ap1.getContent();
112  *    java.io.InputStream content2 = ap2.getContent();
113  * </PRE>
114  *   The method <CODE>clearContent</CODE> removes all the content
115  *   from an <CODE>AttachmentPart</CODE> object but does not affect
116  *   its header information.
117  * <PRE>
118  *    ap1.clearContent();
119  * </PRE>
120  */
121 public abstract class AttachmentPart {
122 
123     // fixme: should this constructor be protected?
124     /** Create a new AttachmentPart. */
125     public AttachmentPart() {}
126 
127     /**
128      * Returns the number of bytes in this <CODE>
129      * AttachmentPart</CODE> object.
130      * @return the size of this <CODE>AttachmentPart</CODE> object
131      *     in bytes or -1 if the size cannot be determined
132      * @throws  SOAPException  if the content of this
133      *     attachment is corrupted of if there was an exception
134      *     while trying to determine the size.
135      */
136     public abstract int getSize() throws SOAPException;
137 
138     /**
139      * Clears out the content of this <CODE>
140      * AttachmentPart</CODE> object. The MIME header portion is left
141      * untouched.
142      */
143     public abstract void clearContent();
144 
145     /**
146      * Gets the content of this <code>AttachmentPart</code> object as a Java
147      * object. The type of the returned Java object depends on (1) the
148      * <code>DataContentHandler</code> object that is used to interpret the bytes
149      * and (2) the <code>Content-Type</code> given in the header.
150      * <p>
151      * For the MIME content types "text/plain", "text/html" and "text/xml", the
152      * <code>DataContentHandler</code> object does the conversions to and
153      * from the Java types corresponding to the MIME types.
154      * For other MIME types,the <code>DataContentHandler</code> object
155      * can return an <code>InputStream</code> object that contains the content data
156      * as raw bytes.
157      * <p>
158      * A JAXM-compliant implementation must, as a minimum, return a
159      * <code>java.lang.String</code> object corresponding to any content
160      * stream with a <code>Content-Type</code> value of
161      * <code>text/plain</code>, a
162      * <code>javax.xml.transform.StreamSource</code> object corresponding to a
163      * content stream with a <code>Content-Type</code> value of
164      * <code>text/xml</code>, a <code>java.awt.Image</code> object
165      * corresponding to a content stream with a
166      * <code>Content-Type</code> value of <code>image/gif</code> or
167      * <code>image/jpeg</code>.  For those content types that an
168      * installed <code>DataContentHandler</code> object does not understand, the
169      * <code>DataContentHandler</code> object is required to return a
170      * <code>java.io.InputStream</code> object with the raw bytes.
171      *
172      * @return a Java object with the content of this <CODE>
173      *     AttachmentPart</CODE> object
174      * @throws  SOAPException  if there is no content set
175      *     into this <CODE>AttachmentPart</CODE> object or if there
176      *     was a data transformation error
177      */
178     public abstract Object getContent() throws SOAPException;
179 
180     /**
181      * Sets the content of this attachment part to that of the
182      * given <CODE>Object</CODE> and sets the value of the <CODE>
183      * Content-Type</CODE> header to the given type. The type of the
184      * <CODE>Object</CODE> should correspond to the value given for
185      * the <CODE>Content-Type</CODE>. This depends on the particular
186      * set of <CODE>DataContentHandler</CODE> objects in use.
187      * @param  object  the Java object that makes up
188      * the content for this attachment part
189      * @param  contentType the MIME string that
190      * specifies the type of the content
191      * @throws java.lang.IllegalArgumentException if
192      *     the contentType does not match the type of the content
193      *     object, or if there was no <CODE>
194      *     DataContentHandler</CODE> object for this content
195      *     object
196      * @see #getContent() getContent()
197      */
198     public abstract void setContent(Object object, String contentType);
199 
200     /**
201      * Gets the <CODE>DataHandler</CODE> object for this <CODE>
202      * AttachmentPart</CODE> object.
203      * @return the <CODE>DataHandler</CODE> object associated with
204      *     this <CODE>AttachmentPart</CODE> object
205      * @throws  SOAPException  if there is
206      *     no data in this <CODE>AttachmentPart</CODE> object
207      */
208     public abstract DataHandler getDataHandler() throws SOAPException;
209 
210     /**
211      * Sets the given <CODE>DataHandler</CODE> object as the
212      * data handler for this <CODE>AttachmentPart</CODE> object.
213      * Typically, on an incoming message, the data handler is
214      * automatically set. When a message is being created and
215      * populated with content, the <CODE>setDataHandler</CODE>
216      * method can be used to get data from various data sources into
217      * the message.
218      * @param  datahandler  <CODE>DataHandler</CODE> object to
219      *     be set
220      * @throws java.lang.IllegalArgumentException if
221      *     there was a problem with the specified <CODE>
222      *     DataHandler</CODE> object
223      */
224     public abstract void setDataHandler(DataHandler datahandler);
225 
226     /**
227      * Gets the value of the MIME header whose name is
228      * "Content-Id".
229      * @return  a <CODE>String</CODE> giving the value of the
230      *     "Content-Id" header or <CODE>null</CODE> if there is
231      *     none
232      * @see #setContentId(java.lang.String) setContentId(java.lang.String)
233      */
234     public String getContentId() {
235 
236         String as[] = getMimeHeader("Content-Id");
237 
238         if (as != null && as.length > 0) {
239             return as[0];
240         } else {
241             return null;
242         }
243     }
244 
245     /**
246      * Gets the value of the MIME header
247      * "Content-Location".
248      * @return  a <CODE>String</CODE> giving the value of the
249      *     "Content-Location" header or <CODE>null</CODE> if there
250      *     is none
251      */
252     public String getContentLocation() {
253 
254         String as[] = getMimeHeader("Content-Location");
255 
256         if (as != null && as.length > 0) {
257             return as[0];
258         } else {
259             return null;
260         }
261     }
262 
263     /**
264      * Gets the value of the MIME header "Content-Type".
265      * @return  a <CODE>String</CODE> giving the value of the
266      *     "Content-Type" header or <CODE>null</CODE> if there is
267      *     none
268      */
269     public String getContentType() {
270 
271         String as[] = getMimeHeader("Content-Type");
272 
273         if (as != null && as.length > 0) {
274             return as[0];
275         } else {
276             return null;
277         }
278     }
279 
280     /**
281      * Sets the MIME header "Content-Id" with the given
282      * value.
283      * @param  contentId a <CODE>String</CODE> giving
284      *     the value of the "Content-Id" header
285      * @throws java.lang.IllegalArgumentException if
286      *     there was a problem with the specified <CODE>
287      *     contentId</CODE> value
288      * @see #getContentId() getContentId()
289      */
290     public void setContentId(String contentId) {
291         setMimeHeader("Content-Id", contentId);
292     }
293 
294     /**
295      * Sets the MIME header "Content-Location" with the given
296      * value.
297      * @param  contentLocation a <CODE>String</CODE>
298      *     giving the value of the "Content-Location" header
299      * @throws java.lang.IllegalArgumentException if
300      *     there was a problem with the specified content
301      *     location
302      */
303     public void setContentLocation(String contentLocation) {
304         setMimeHeader("Content-Location", contentLocation);
305     }
306 
307     /**
308      * Sets the MIME header "Content-Type" with the given
309      * value.
310      * @param  contentType  a <CODE>String</CODE>
311      *     giving the value of the "Content-Type" header
312      * @throws java.lang.IllegalArgumentException if
313      * there was a problem with the specified content type
314      */
315     public void setContentType(String contentType) {
316         setMimeHeader("Content-Type", contentType);
317     }
318 
319     /**
320      * Removes all MIME headers that match the given name.
321      * @param  header - the string name of the MIME
322      *     header/s to be removed
323      */
324     public abstract void removeMimeHeader(String header);
325 
326     /** Removes all the MIME header entries. */
327     public abstract void removeAllMimeHeaders();
328 
329     /**
330      * Gets all the values of the header identified by the given
331      * <CODE>String</CODE>.
332      * @param   name  the name of the header; example:
333      *     "Content-Type"
334      * @return a <CODE>String</CODE> array giving the value for the
335      *     specified header
336      * @see #setMimeHeader(java.lang.String, java.lang.String) setMimeHeader(java.lang.String, java.lang.String)
337      */
338     public abstract String[] getMimeHeader(String name);
339 
340     /**
341      * Changes the first header entry that matches the given name
342      *   to the given value, adding a new header if no existing
343      *   header matches. This method also removes all matching
344      *   headers but the first.
345      *
346      *   <P>Note that RFC822 headers can only contain US-ASCII
347      *   characters.</P>
348      * @param  name   a <CODE>String</CODE> giving the
349      *     name of the header for which to search
350      * @param  value  a <CODE>String</CODE> giving the
351      *     value to be set for the header whose name matches the
352      *     given name
353      * @throws java.lang.IllegalArgumentException if
354      *     there was a problem with the specified mime header name
355      *     or value
356      */
357     public abstract void setMimeHeader(String name, String value);
358 
359     /**
360      * Adds a MIME header with the specified name and value to
361      *   this <CODE>AttachmentPart</CODE> object.
362      *
363      *   <P>Note that RFC822 headers can contain only US-ASCII
364      *   characters.</P>
365      * @param  name   a <CODE>String</CODE> giving the
366      *     name of the header to be added
367      * @param  value  a <CODE>String</CODE> giving the
368      *     value of the header to be added
369      * @throws java.lang.IllegalArgumentException if
370      *     there was a problem with the specified mime header name
371      *     or value
372      */
373     public abstract void addMimeHeader(String name, String value);
374 
375     /**
376      * Retrieves all the headers for this <CODE>
377      * AttachmentPart</CODE> object as an iterator over the <CODE>
378      * MimeHeader</CODE> objects.
379      * @return  an <CODE>Iterator</CODE> object with all of the Mime
380      *     headers for this <CODE>AttachmentPart</CODE> object
381      */
382     public abstract Iterator getAllMimeHeaders();
383 
384     /**
385      * Retrieves all <CODE>MimeHeader</CODE> objects that match
386      * a name in the given array.
387      * @param   names a <CODE>String</CODE> array with
388      *     the name(s) of the MIME headers to be returned
389      * @return all of the MIME headers that match one of the names
390      *     in the given array as an <CODE>Iterator</CODE>
391      *     object
392      */
393     public abstract Iterator getMatchingMimeHeaders(String names[]);
394 
395     /**
396      * Retrieves all <CODE>MimeHeader</CODE> objects whose name
397      * does not match a name in the given array.
398      * @param   names  a <CODE>String</CODE> array with
399      *     the name(s) of the MIME headers not to be returned
400      * @return all of the MIME headers in this <CODE>
401      *     AttachmentPart</CODE> object except those that match one
402      *     of the names in the given array. The nonmatching MIME
403      *     headers are returned as an <CODE>Iterator</CODE>
404      *     object.
405      */
406     public abstract Iterator getNonMatchingMimeHeaders(String names[]);
407 }