1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
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 }