source: contrib/MailArchiver/sources/vendor/mime4j/custom/core/src/main/java/org/apache/james/mime4j/stream/DefaultBodyDescriptor.java @ 6785

Revision 6785, 8.3 KB checked in by rafaelraymundo, 12 years ago (diff)

Ticket #2946 - Liberado codigo do MailArchiver?. Documentação na subpasta DOCS.

Line 
1/****************************************************************
2 * Licensed to the Apache Software Foundation (ASF) under one   *
3 * or more contributor license agreements.  See the NOTICE file *
4 * distributed with this work for additional information        *
5 * regarding copyright ownership.  The ASF licenses this file   *
6 * to you under the Apache License, Version 2.0 (the            *
7 * "License"); you may not use this file except in compliance   *
8 * with the License.  You may obtain a copy of the License at   *
9 *                                                              *
10 *   http://www.apache.org/licenses/LICENSE-2.0                 *
11 *                                                              *
12 * Unless required by applicable law or agreed to in writing,   *
13 * software distributed under the License is distributed on an  *
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
15 * KIND, either express or implied.  See the License for the    *
16 * specific language governing permissions and limitations      *
17 * under the License.                                           *
18 ****************************************************************/
19
20package org.apache.james.mime4j.stream;
21
22import java.util.HashMap;
23import java.util.Locale;
24import java.util.Map;
25
26import org.apache.james.mime4j.MimeException;
27import org.apache.james.mime4j.codec.DecodeMonitor;
28import org.apache.james.mime4j.util.MimeUtil;
29
30/**
31 * Encapsulates the values of the MIME-specific header fields
32 * (which starts with <code>Content-</code>).
33 */
34public class DefaultBodyDescriptor implements MutableBodyDescriptor {
35    private static final String US_ASCII = "us-ascii";
36
37    private static final String SUB_TYPE_EMAIL = "rfc822";
38
39    private static final String MEDIA_TYPE_TEXT = "text";
40
41    private static final String MEDIA_TYPE_MESSAGE = "message";
42
43    private static final String EMAIL_MESSAGE_MIME_TYPE = MEDIA_TYPE_MESSAGE + "/" + SUB_TYPE_EMAIL;
44
45    private static final String DEFAULT_SUB_TYPE = "plain";
46
47    private static final String DEFAULT_MEDIA_TYPE = MEDIA_TYPE_TEXT;
48
49    private static final String DEFAULT_MIME_TYPE = DEFAULT_MEDIA_TYPE + "/" + DEFAULT_SUB_TYPE;
50
51    private final DecodeMonitor monitor;
52   
53    private String mediaType = DEFAULT_MEDIA_TYPE;
54    private String subType = DEFAULT_SUB_TYPE;
55    private String mimeType = DEFAULT_MIME_TYPE;
56    private String boundary = null;
57    private String charset = US_ASCII;
58    private String transferEncoding = "7bit";
59    private Map<String, String> parameters = new HashMap<String, String>();
60    private boolean contentTypeSet;
61    private boolean contentTransferEncSet;
62    private long contentLength = -1;
63   
64    /**
65     * Creates a new root <code>BodyDescriptor</code> instance.
66     */
67    public DefaultBodyDescriptor() {
68        this(null, null);
69    }
70
71    /**
72     * Creates a new <code>BodyDescriptor</code> instance.
73     *
74     * @param parent the descriptor of the parent or <code>null</code> if this
75     *        is the root descriptor.
76     */
77    public DefaultBodyDescriptor(final BodyDescriptor parent, final DecodeMonitor monitor) {
78        if (parent != null && MimeUtil.isSameMimeType("multipart/digest", parent.getMimeType())) {
79            this.mimeType = EMAIL_MESSAGE_MIME_TYPE;
80            this.subType = SUB_TYPE_EMAIL;
81            this.mediaType = MEDIA_TYPE_MESSAGE;
82        } else {
83            this.mimeType = DEFAULT_MIME_TYPE;
84            this.subType = DEFAULT_SUB_TYPE;
85            this.mediaType = DEFAULT_MEDIA_TYPE;
86        }
87        this.monitor = monitor != null ? monitor : DecodeMonitor.SILENT;
88    }
89   
90    protected DecodeMonitor getDecodeMonitor() {
91        return monitor;
92    }
93   
94    public MutableBodyDescriptor newChild() {
95                return new DefaultBodyDescriptor(this, getDecodeMonitor());
96    }
97   
98    /**
99     * Should be called for each <code>Content-</code> header field of
100     * a MIME message or part.
101     *
102     * @param field the MIME field.
103     */
104    public void addField(RawField field) throws MimeException {
105        String name = field.getName().toLowerCase(Locale.US);
106       
107        if (name.equals("content-transfer-encoding") && !contentTransferEncSet) {
108            contentTransferEncSet = true;
109            String value = field.getBody();
110            if (value != null) {
111                value = value.trim().toLowerCase(Locale.US);
112                if (value.length() > 0) {
113                    transferEncoding = value;
114                }
115            }
116        } else if (name.equals("content-length") && contentLength == -1) {
117            String value = field.getBody();
118            if (value != null) {
119                value = value.trim();
120                try {
121                    contentLength = Long.parseLong(value.trim());
122                } catch (NumberFormatException e) {
123                    if (monitor.warn("Invalid content length: " + value,
124                            "ignoring Content-Length header")) {
125                        throw new MimeException("Invalid Content-Length header: " + value);
126                    }
127                }
128            }
129        } else if (name.equals("content-type") && !contentTypeSet) {
130            parseContentType(field);
131        }
132    }
133
134    private void parseContentType(RawField field) throws MimeException {
135        contentTypeSet = true;
136        RawBody body = RawFieldParser.DEFAULT.parseRawBody(field);
137        String main = body.getValue();
138        Map<String, String> params = new HashMap<String, String>();
139        for (NameValuePair nmp: body.getParams()) {
140            String name = nmp.getName().toLowerCase(Locale.US);
141            params.put(name, nmp.getValue());
142        }
143       
144        String type = null;
145        String subtype = null;
146        if (main != null) {
147            main = main.toLowerCase().trim();
148            int index = main.indexOf('/');
149            boolean valid = false;
150            if (index != -1) {
151                type = main.substring(0, index).trim();
152                subtype = main.substring(index + 1).trim();
153                if (type.length() > 0 && subtype.length() > 0) {
154                    main = type + "/" + subtype;
155                    valid = true;
156                }
157            }
158           
159            if (!valid) {
160                main = null;
161                type = null;
162                subtype = null;
163            }
164        }
165        String b = params.get("boundary");
166       
167        if (main != null
168                && ((main.startsWith("multipart/") && b != null)
169                        || !main.startsWith("multipart/"))) {
170            mimeType = main;
171            this.subType = subtype;
172            this.mediaType = type;
173        }
174       
175        if (MimeUtil.isMultipart(mimeType)) {
176            boundary = b;
177        }
178       
179        String c = params.get("charset");
180        charset = null;
181        if (c != null) {
182            c = c.trim();
183            if (c.length() > 0) {
184                charset = c.toLowerCase();
185            }
186        }
187        if (charset == null && MEDIA_TYPE_TEXT.equals(mediaType)) {
188            charset = US_ASCII;
189        }
190       
191        /*
192         * Add all other parameters to parameters.
193         */
194        parameters.putAll(params);
195        parameters.remove("boundary");
196        parameters.remove("charset");
197    }
198
199    /**
200     * Return the MimeType
201     *
202     * @return mimeType
203     */
204    public String getMimeType() {
205        return mimeType;
206    }
207   
208    /**
209     * Return the boundary
210     *
211     * @return boundary
212     */
213    public String getBoundary() {
214        return boundary;
215    }
216   
217    /**
218     * Return the charset
219     *
220     * @return charset
221     */
222    public String getCharset() {
223        return charset;
224    }
225   
226    /**
227     * Return all parameters for the BodyDescriptor
228     *
229     * @return parameters
230     */
231    public Map<String, String> getContentTypeParameters() {
232        return parameters;
233    }
234   
235    /**
236     * Return the TransferEncoding
237     *
238     * @return transferEncoding
239     */
240    public String getTransferEncoding() {
241        return transferEncoding;
242    }
243   
244    @Override
245    public String toString() {
246        return mimeType;
247    }
248
249    public long getContentLength() {
250        return contentLength;
251    }
252
253    public String getMediaType() {
254        return mediaType;
255    }
256
257    public String getSubType() {
258        return subType;
259    }
260
261}
Note: See TracBrowser for help on using the repository browser.