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