1 /*
2 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 /*
27 * @(#)MimeBodyPart.java 1.52 03/02/12
28 */
29
30
31
32 package com.sun.xml.internal.messaging.saaj.packaging.mime.internet;
33
34
35 import com.sun.xml.internal.messaging.saaj.packaging.mime.MessagingException;
36 import com.sun.xml.internal.messaging.saaj.packaging.mime.util.OutputUtil;
37 import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream;
38 import com.sun.xml.internal.messaging.saaj.util.FinalArrayList;
39
40 import java.util.logging.Level;
41 import java.util.logging.Logger;
42 import javax.activation.DataHandler;
43 import java.io.BufferedInputStream;
44 import java.io.ByteArrayInputStream;
45 import java.io.IOException;
46 import java.io.InputStream;
47 import java.io.OutputStream;
48 import java.io.UnsupportedEncodingException;
49 import java.util.List;
50 import javax.activation.DataSource;
51 import com.sun.xml.internal.org.jvnet.mimepull.MIMEPart;
52
53 /**
54 * This class represents a MIME body part.
55 * MimeBodyParts are contained in <code>MimeMultipart</code>
56 * objects. <p>
57 *
58 * MimeBodyPart uses the <code>InternetHeaders</code> class to parse
59 * and store the headers of that body part. <p>
60 *
61 * <hr><strong>A note on RFC 822 and MIME headers</strong><p>
509 setHeader("Content-MD5", md5);
510 }
511
512 /**
513 * Get the languages specified in the Content-Language header
514 * of this MimeBodyPart. The Content-Language header is defined by
515 * RFC 1766. Returns <code>null</code> if this header is not
516 * available or its value is absent. <p>
517 *
518 * This implementation uses <code>getHeader(name)</code>
519 * to obtain the requisite header field.
520 */
521 public String[] getContentLanguage() throws MessagingException {
522 String s = getHeader("Content-Language", null);
523
524 if (s == null)
525 return null;
526
527 // Tokenize the header to obtain the Language-tags (skip comments)
528 HeaderTokenizer h = new HeaderTokenizer(s, HeaderTokenizer.MIME);
529 FinalArrayList v = new FinalArrayList();
530
531 HeaderTokenizer.Token tk;
532 int tkType;
533
534 while (true) {
535 tk = h.next(); // get a language-tag
536 tkType = tk.getType();
537 if (tkType == HeaderTokenizer.Token.EOF)
538 break; // done
539 else if (tkType == HeaderTokenizer.Token.ATOM) v.add(tk.getValue());
540 else // invalid token, skip it.
541 continue;
542 }
543
544 if (v.size() == 0)
545 return null;
546
547 return (String[])v.toArray(new String[v.size()]);
548 }
549
550 /**
551 * Set the Content-Language header of this MimeBodyPart. The
552 * Content-Language header is defined by RFC 1766.
553 *
554 * @param languages array of language tags
555 */
556 public void setContentLanguage(String[] languages) {
557 StringBuffer sb = new StringBuffer(languages[0]);
558 for (int i = 1; i < languages.length; i++)
559 sb.append(',').append(languages[i]);
560 setHeader("Content-Language", sb.toString());
561 }
562
563 /**
564 * Returns the "Content-Description" header field of this body part.
565 * This typically associates some descriptive information with
566 * this part. Returns null if this field is unavailable or its
567 * value is absent. <p>
568 *
569 * If the Content-Description field is encoded as per RFC 2047,
570 * it is decoded and converted into Unicode. If the decoding or
571 * conversion fails, the raw data is returned as is. <p>
572 *
573 * This implementation uses <code>getHeader(name)</code>
574 * to obtain the requisite header field.
575 *
576 * @return content description
577 */
926 if (mimePart != null) {
927 mimePart = null;
928 }
929 setDataHandler(new DataHandler(mp, mp.getContentType().toString()));
930 mp.setParent(this);
931 }
932
933 /**
934 * Output the body part as an RFC 822 format stream.
935 *
936 * @exception MessagingException
937 * @exception IOException if an error occurs writing to the
938 * stream or if an error is generated
939 * by the javax.activation layer.
940 * @see DataHandler#writeTo
941 */
942 public void writeTo(OutputStream os)
943 throws IOException, MessagingException {
944
945 // First, write out the header
946 List hdrLines = headers.getAllHeaderLines();
947 int sz = hdrLines.size();
948 for( int i=0; i<sz; i++ )
949 OutputUtil.writeln((String)hdrLines.get(i),os);
950
951 // The CRLF separator between header and content
952 OutputUtil.writeln(os);
953
954 // Finally, the content.
955 // XXX: May need to account for ESMTP ?
956 if (contentStream != null) {
957 ((SharedInputStream)contentStream).writeTo(0,-1,os);
958 } else
959 if (content != null) {
960 os.write(content,start,contentLength);
961 } else
962 if (dh!=null) {
963 // this is the slowest route, so try it as the last resort
964 OutputStream wos = MimeUtility.encode(os, getEncoding());
965 getDataHandler().writeTo(wos);
966 if(os!=wos)
967 wos.flush(); // Needed to complete encoding
968 } else if (mimePart != null) {
969 OutputStream wos = MimeUtility.encode(os, getEncoding());
1026 *
1027 * @param name header name
1028 * @param value header value
1029 * @see MimeUtility
1030 */
1031 public void addHeader(String name, String value) {
1032 headers.addHeader(name, value);
1033 }
1034
1035 /**
1036 * Remove all headers with this name.
1037 */
1038 public void removeHeader(String name) {
1039 headers.removeHeader(name);
1040 }
1041
1042 /**
1043 * Return all the headers from this Message as an Enumeration of
1044 * Header objects.
1045 */
1046 public FinalArrayList getAllHeaders() {
1047 return headers.getAllHeaders();
1048 }
1049
1050
1051 /**
1052 * Add a header line to this body part
1053 */
1054 public void addHeaderLine(String line) {
1055 headers.addHeaderLine(line);
1056 }
1057
1058 /**
1059 * Examine the content of this body part and update the appropriate
1060 * MIME headers. Typical headers that get set here are
1061 * <code>Content-Type</code> and <code>Content-Transfer-Encoding</code>.
1062 * Headers might need to be updated in two cases:
1063 *
1064 * <br>
1065 * - A message being crafted by a mail application will certainly
1066 * need to activate this method at some point to fill up its internal
|
1 /*
2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 /*
27 * @(#)MimeBodyPart.java 1.52 03/02/12
28 */
29
30
31
32 package com.sun.xml.internal.messaging.saaj.packaging.mime.internet;
33
34
35 import com.sun.xml.internal.messaging.saaj.packaging.mime.MessagingException;
36 import com.sun.xml.internal.messaging.saaj.packaging.mime.util.OutputUtil;
37 import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream;
38 import com.sun.xml.internal.messaging.saaj.util.FinalArrayList;
39
40 import javax.activation.DataHandler;
41 import java.io.BufferedInputStream;
42 import java.io.ByteArrayInputStream;
43 import java.io.IOException;
44 import java.io.InputStream;
45 import java.io.OutputStream;
46 import java.io.UnsupportedEncodingException;
47 import java.util.List;
48 import javax.activation.DataSource;
49 import com.sun.xml.internal.org.jvnet.mimepull.MIMEPart;
50
51 /**
52 * This class represents a MIME body part.
53 * MimeBodyParts are contained in <code>MimeMultipart</code>
54 * objects. <p>
55 *
56 * MimeBodyPart uses the <code>InternetHeaders</code> class to parse
57 * and store the headers of that body part. <p>
58 *
59 * <hr><strong>A note on RFC 822 and MIME headers</strong><p>
507 setHeader("Content-MD5", md5);
508 }
509
510 /**
511 * Get the languages specified in the Content-Language header
512 * of this MimeBodyPart. The Content-Language header is defined by
513 * RFC 1766. Returns <code>null</code> if this header is not
514 * available or its value is absent. <p>
515 *
516 * This implementation uses <code>getHeader(name)</code>
517 * to obtain the requisite header field.
518 */
519 public String[] getContentLanguage() throws MessagingException {
520 String s = getHeader("Content-Language", null);
521
522 if (s == null)
523 return null;
524
525 // Tokenize the header to obtain the Language-tags (skip comments)
526 HeaderTokenizer h = new HeaderTokenizer(s, HeaderTokenizer.MIME);
527 FinalArrayList<String> v = new FinalArrayList<String>();
528
529 HeaderTokenizer.Token tk;
530 int tkType;
531
532 while (true) {
533 tk = h.next(); // get a language-tag
534 tkType = tk.getType();
535 if (tkType == HeaderTokenizer.Token.EOF)
536 break; // done
537 else if (tkType == HeaderTokenizer.Token.ATOM) v.add(tk.getValue());
538 else // invalid token, skip it.
539 continue;
540 }
541
542 if (v.size() == 0)
543 return null;
544
545 return v.toArray(new String[v.size()]);
546 }
547
548 /**
549 * Set the Content-Language header of this MimeBodyPart. The
550 * Content-Language header is defined by RFC 1766.
551 *
552 * @param languages array of language tags
553 */
554 public void setContentLanguage(String[] languages) {
555 StringBuilder sb = new StringBuilder(languages[0]);
556 for (int i = 1; i < languages.length; i++)
557 sb.append(',').append(languages[i]);
558 setHeader("Content-Language", sb.toString());
559 }
560
561 /**
562 * Returns the "Content-Description" header field of this body part.
563 * This typically associates some descriptive information with
564 * this part. Returns null if this field is unavailable or its
565 * value is absent. <p>
566 *
567 * If the Content-Description field is encoded as per RFC 2047,
568 * it is decoded and converted into Unicode. If the decoding or
569 * conversion fails, the raw data is returned as is. <p>
570 *
571 * This implementation uses <code>getHeader(name)</code>
572 * to obtain the requisite header field.
573 *
574 * @return content description
575 */
924 if (mimePart != null) {
925 mimePart = null;
926 }
927 setDataHandler(new DataHandler(mp, mp.getContentType().toString()));
928 mp.setParent(this);
929 }
930
931 /**
932 * Output the body part as an RFC 822 format stream.
933 *
934 * @exception MessagingException
935 * @exception IOException if an error occurs writing to the
936 * stream or if an error is generated
937 * by the javax.activation layer.
938 * @see DataHandler#writeTo
939 */
940 public void writeTo(OutputStream os)
941 throws IOException, MessagingException {
942
943 // First, write out the header
944 List<String> hdrLines = headers.getAllHeaderLines();
945 int sz = hdrLines.size();
946 for( int i=0; i<sz; i++ )
947 OutputUtil.writeln(hdrLines.get(i),os);
948
949 // The CRLF separator between header and content
950 OutputUtil.writeln(os);
951
952 // Finally, the content.
953 // XXX: May need to account for ESMTP ?
954 if (contentStream != null) {
955 ((SharedInputStream)contentStream).writeTo(0,-1,os);
956 } else
957 if (content != null) {
958 os.write(content,start,contentLength);
959 } else
960 if (dh!=null) {
961 // this is the slowest route, so try it as the last resort
962 OutputStream wos = MimeUtility.encode(os, getEncoding());
963 getDataHandler().writeTo(wos);
964 if(os!=wos)
965 wos.flush(); // Needed to complete encoding
966 } else if (mimePart != null) {
967 OutputStream wos = MimeUtility.encode(os, getEncoding());
1024 *
1025 * @param name header name
1026 * @param value header value
1027 * @see MimeUtility
1028 */
1029 public void addHeader(String name, String value) {
1030 headers.addHeader(name, value);
1031 }
1032
1033 /**
1034 * Remove all headers with this name.
1035 */
1036 public void removeHeader(String name) {
1037 headers.removeHeader(name);
1038 }
1039
1040 /**
1041 * Return all the headers from this Message as an Enumeration of
1042 * Header objects.
1043 */
1044 public FinalArrayList<hdr> getAllHeaders() {
1045 return headers.getAllHeaders();
1046 }
1047
1048
1049 /**
1050 * Add a header line to this body part
1051 */
1052 public void addHeaderLine(String line) {
1053 headers.addHeaderLine(line);
1054 }
1055
1056 /**
1057 * Examine the content of this body part and update the appropriate
1058 * MIME headers. Typical headers that get set here are
1059 * <code>Content-Type</code> and <code>Content-Transfer-Encoding</code>.
1060 * Headers might need to be updated in two cases:
1061 *
1062 * <br>
1063 * - A message being crafted by a mail application will certainly
1064 * need to activate this method at some point to fill up its internal
|