source: contrib/MailArchiver/sources/vendor/mime4j/apache-mime4j-0.7-SNAPSHOT-20110327.010440-17/dom/src/main/java/org/apache/james/mime4j/message/MaximalBodyDescriptor.java @ 6785

Revision 6785, 18.4 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.message;
21
22import java.io.StringReader;
23import java.util.Collections;
24import java.util.List;
25import java.util.Map;
26
27import org.apache.james.mime4j.MimeException;
28import org.apache.james.mime4j.codec.DecodeMonitor;
29import org.apache.james.mime4j.dom.datetime.DateTime;
30import org.apache.james.mime4j.field.datetime.parser.DateTimeParser;
31import org.apache.james.mime4j.field.datetime.parser.ParseException;
32import org.apache.james.mime4j.field.language.parser.ContentLanguageParser;
33import org.apache.james.mime4j.field.mimeversion.parser.MimeVersionParser;
34import org.apache.james.mime4j.field.structured.parser.StructuredFieldParser;
35import org.apache.james.mime4j.stream.BodyDescriptor;
36import org.apache.james.mime4j.stream.DefaultBodyDescriptor;
37import org.apache.james.mime4j.stream.MutableBodyDescriptor;
38import org.apache.james.mime4j.stream.RawField;
39import org.apache.james.mime4j.util.MimeUtil;
40
41/**
42 * Parses and stores values for standard MIME header values.
43 *
44 */
45public class MaximalBodyDescriptor extends DefaultBodyDescriptor {
46
47    private static final int DEFAULT_MINOR_VERSION = 0;
48    private static final int DEFAULT_MAJOR_VERSION = 1;
49    private boolean isMimeVersionSet;
50    private int mimeMinorVersion;
51    private int mimeMajorVersion;
52    private MimeException mimeVersionException;
53    private String contentId;
54    private boolean isContentIdSet;
55    private String contentDescription;
56    private boolean isContentDescriptionSet;
57    private String contentDispositionType;
58    private Map<String, String> contentDispositionParameters;
59    private DateTime contentDispositionModificationDate;
60    private MimeException contentDispositionModificationDateParseException;
61    private DateTime contentDispositionCreationDate;
62    private MimeException contentDispositionCreationDateParseException;
63    private DateTime contentDispositionReadDate;
64    private MimeException contentDispositionReadDateParseException;
65    private long contentDispositionSize;
66    private MimeException contentDispositionSizeParseException;
67    private boolean isContentDispositionSet;
68    private List<String> contentLanguage;
69    private MimeException contentLanguageParseException;
70    private boolean isContentLanguageSet;
71    private MimeException contentLocationParseException;
72    private String contentLocation;
73    private boolean isContentLocationSet;
74    private String contentMD5Raw;
75    private boolean isContentMD5Set;
76   
77    protected MaximalBodyDescriptor() {
78        this(null, null);
79    }
80
81    public MaximalBodyDescriptor(final BodyDescriptor parent, final DecodeMonitor monitor) {
82        super(parent, monitor);
83        isMimeVersionSet = false;
84        mimeMajorVersion = DEFAULT_MAJOR_VERSION;
85        mimeMinorVersion = DEFAULT_MINOR_VERSION;
86        this.contentId = null;
87        this.isContentIdSet = false;
88        this.contentDescription = null;
89        this.isContentDescriptionSet = false;
90        this.contentDispositionType = null;
91        this.contentDispositionParameters = Collections.emptyMap();
92        this.contentDispositionModificationDate = null;
93        this.contentDispositionModificationDateParseException = null;
94        this.contentDispositionCreationDate = null;
95        this.contentDispositionCreationDateParseException = null;
96        this.contentDispositionReadDate = null;
97        this.contentDispositionReadDateParseException = null;
98        this.contentDispositionSize = -1;
99        this.contentDispositionSizeParseException = null;
100        this.isContentDispositionSet = false;
101        this.contentLanguage = null;
102        this.contentLanguageParseException = null;
103        this.isContentIdSet = false;
104        this.contentLocation = null;
105        this.contentLocationParseException = null;
106        this.isContentLocationSet = false;
107        this.contentMD5Raw = null;
108        this.isContentMD5Set = false;
109    }
110
111    @Override
112    public MutableBodyDescriptor newChild() {
113        return new MaximalBodyDescriptor(this, getDecodeMonitor());
114    }
115
116    @Override
117    public void addField(RawField field) throws MimeException {
118        String name = field.getName();
119        String value = field.getBody();
120        name = name.trim().toLowerCase();
121        if (MimeUtil.MIME_HEADER_MIME_VERSION.equals(name) && !isMimeVersionSet) {
122            parseMimeVersion(value);
123        } else if (MimeUtil.MIME_HEADER_CONTENT_ID.equals(name) && !isContentIdSet) {
124            parseContentId(value);
125        } else if (MimeUtil.MIME_HEADER_CONTENT_DESCRIPTION.equals(name) && !isContentDescriptionSet) {
126            parseContentDescription(value);
127        } else if (MimeUtil.MIME_HEADER_CONTENT_DISPOSITION.equals(name) && !isContentDispositionSet) {
128            parseContentDisposition(value);
129        } else if (MimeUtil.MIME_HEADER_LANGAUGE.equals(name) && !isContentLanguageSet) {
130            parseLanguage(value);
131        } else if (MimeUtil.MIME_HEADER_LOCATION.equals(name) && !isContentLocationSet) {
132            parseLocation(value);
133        } else if (MimeUtil.MIME_HEADER_MD5.equals(name) && !isContentMD5Set) {
134            parseMD5(value);
135        } else {
136            super.addField(field);
137        }
138    }
139   
140    private void parseMD5(String value) {
141        isContentMD5Set = true;
142        if (value != null) {
143            contentMD5Raw = value.trim();
144        }
145    }
146
147    private void parseLocation(final String value) {
148        isContentLocationSet = true;
149        if (value != null) {
150            final StringReader stringReader = new StringReader(value);
151            final StructuredFieldParser parser = new StructuredFieldParser(stringReader);
152            try {
153                // From RFC2017 3.1
154                /*
155                 * Extraction of the URL string from the URL-parameter is even simpler:
156                 * The enclosing quotes and any linear whitespace are removed and the
157                 * remaining material is the URL string.
158                 * Read more: http://www.faqs.org/rfcs/rfc2017.html#ixzz0aufO9nRL
159                 */
160                contentLocation = parser.parse().replaceAll("\\s", "");
161            } catch (MimeException e) {
162                contentLocationParseException = e;
163            }
164        }
165    }
166   
167    private void parseLanguage(final String value) {
168        isContentLanguageSet = true;
169        if (value != null) {
170            try {
171                final ContentLanguageParser parser = new ContentLanguageParser(new StringReader(value));
172                contentLanguage = parser.parse();
173            } catch (MimeException e) {
174                contentLanguageParseException = e;
175            }
176        }
177    }
178
179    private void parseContentDisposition(final String value) throws MimeException {
180        isContentDispositionSet = true;
181        contentDispositionParameters = DefaultBodyDescriptor.getHeaderParams(value, getDecodeMonitor());
182        contentDispositionType = contentDispositionParameters.get("");
183       
184        final String contentDispositionModificationDate
185            = contentDispositionParameters.get(MimeUtil.PARAM_MODIFICATION_DATE);
186        if (contentDispositionModificationDate != null) {
187            try {
188                this.contentDispositionModificationDate = parseDate(contentDispositionModificationDate);
189            } catch (ParseException e) {
190                this.contentDispositionModificationDateParseException = e;
191            }
192        }
193       
194        final String contentDispositionCreationDate
195            = contentDispositionParameters.get(MimeUtil.PARAM_CREATION_DATE);
196        if (contentDispositionCreationDate != null) {
197            try {
198                this.contentDispositionCreationDate = parseDate(contentDispositionCreationDate);
199            } catch (ParseException e) {
200                this.contentDispositionCreationDateParseException = e;
201            }         
202        }
203       
204        final String contentDispositionReadDate
205            = contentDispositionParameters.get(MimeUtil.PARAM_READ_DATE);
206        if (contentDispositionReadDate != null) {
207            try {
208                this.contentDispositionReadDate = parseDate(contentDispositionReadDate);
209            } catch (ParseException e) {
210                this.contentDispositionReadDateParseException = e;
211            }         
212        }
213       
214        final String size = contentDispositionParameters.get(MimeUtil.PARAM_SIZE);
215        if (size != null) {
216            try {
217                contentDispositionSize = Long.parseLong(size);
218            } catch (NumberFormatException e) {
219                this.contentDispositionSizeParseException = (MimeException) new MimeException(e.getMessage(), e).fillInStackTrace();
220            }
221        }
222        contentDispositionParameters.remove("");
223    }
224
225    private DateTime parseDate(final String date) throws ParseException {
226        final StringReader stringReader = new StringReader(date);
227        final DateTimeParser parser = new DateTimeParser(stringReader);
228        DateTime result = parser.date_time();
229        return result;
230    }
231   
232    private void parseContentDescription(String value) {
233        if (value == null) {
234            contentDescription = "";
235        } else {
236            contentDescription = value.trim();
237        }
238        isContentDescriptionSet = true;
239    }
240
241    private void parseContentId(final String value) {
242        if (value == null) {
243            contentId = "";
244        } else {
245            contentId = value.trim();
246        }
247        isContentIdSet = true;
248    }
249
250    private void parseMimeVersion(String value) {
251        final StringReader reader = new StringReader(value);
252        final MimeVersionParser parser = new MimeVersionParser(reader);
253        try {
254            parser.parse();
255            final int major = parser.getMajorVersion();
256            if (major != MimeVersionParser.INITIAL_VERSION_VALUE) {
257                mimeMajorVersion = major;
258            }
259            final int minor = parser.getMinorVersion();
260            if (minor != MimeVersionParser.INITIAL_VERSION_VALUE) {
261                mimeMinorVersion = minor;
262            }
263        } catch (MimeException e) {
264            this.mimeVersionException = e;
265        }
266        isMimeVersionSet = true;
267    }
268   
269    /**
270     * Gets the MIME major version
271     * as specified by the <code>MIME-Version</code>
272     * header.
273     * Defaults to one.
274     * @return positive integer
275     */
276    public int getMimeMajorVersion() {
277        return mimeMajorVersion;
278    }
279   
280    /**
281     * Gets the MIME minor version
282     * as specified by the <code>MIME-Version</code>
283     * header.
284     * Defaults to zero.
285     * @return positive integer
286     */
287    public int getMimeMinorVersion() {
288        return mimeMinorVersion;
289    }
290   
291
292    /**
293     * When the MIME version header exists but cannot be parsed
294     * this field will be contain the exception.
295     * @return <code>MimeException</code> if the mime header cannot
296     * be parsed, null otherwise
297     */
298    public MimeException getMimeVersionParseException() {
299        return mimeVersionException;
300    }
301   
302    /**
303     * Gets the value of the <a href='http://www.faqs.org/rfcs/rfc2045'>RFC</a>
304     * <code>Content-Description</code> header.
305     * @return value of the <code>Content-Description</code> when present,
306     * null otherwise
307     */
308    public String getContentDescription() {
309        return contentDescription;
310    }
311   
312    /**
313     * Gets the value of the <a href='http://www.faqs.org/rfcs/rfc2045'>RFC</a>
314     * <code>Content-ID</code> header.
315     * @return value of the <code>Content-ID</code> when present,
316     * null otherwise
317     */
318    public String getContentId() {
319        return contentId;
320    }
321   
322    /**
323     * Gets the disposition type of the <code>content-disposition</code> field.
324     * The value is case insensitive and will be converted to lower case.
325     * See <a href='http://www.faqs.org/rfcs/rfc2183.html'>RFC2183</a>.
326     * @return content disposition type,
327     * or null when this has not been set
328     */
329    public String getContentDispositionType() {
330        return contentDispositionType;
331    }
332   
333    /**
334     * Gets the parameters of the <code>content-disposition</code> field.
335     * See <a href='http://www.faqs.org/rfcs/rfc2183.html'>RFC2183</a>.
336     * @return parameter value strings indexed by parameter name strings,
337     * not null
338     */
339    public Map<String, String> getContentDispositionParameters() {
340        return contentDispositionParameters;
341    }
342   
343    /**
344     * Gets the <code>filename</code> parameter value of the <code>content-disposition</code> field.
345     * See <a href='http://www.faqs.org/rfcs/rfc2183.html'>RFC2183</a>.
346     * @return filename parameter value,
347     * or null when it is not present
348     */
349    public String getContentDispositionFilename() {
350        return contentDispositionParameters.get(MimeUtil.PARAM_FILENAME);
351    }
352   
353    /**
354     * Gets the <code>modification-date</code> parameter value of the <code>content-disposition</code> field.
355     * See <a href='http://www.faqs.org/rfcs/rfc2183.html'>RFC2183</a>.
356     * @return modification-date parameter value,
357     * or null when this is not present
358     */
359    public DateTime getContentDispositionModificationDate() {
360        return contentDispositionModificationDate;
361    }
362   
363    /**
364     * Gets any exception thrown during the parsing of {@link #getContentDispositionModificationDate()}
365     * @return <code>ParseException</code> when the modification-date parse fails,
366     * null otherwise
367     */
368    public MimeException getContentDispositionModificationDateParseException() {
369        return contentDispositionModificationDateParseException;
370    }
371   
372    /**
373     * Gets the <code>creation-date</code> parameter value of the <code>content-disposition</code> field.
374     * See <a href='http://www.faqs.org/rfcs/rfc2183.html'>RFC2183</a>.
375     * @return creation-date parameter value,
376     * or null when this is not present
377     */
378    public DateTime getContentDispositionCreationDate() {
379        return contentDispositionCreationDate;
380    }
381   
382    /**
383     * Gets any exception thrown during the parsing of {@link #getContentDispositionCreationDate()}
384     * @return <code>ParseException</code> when the creation-date parse fails,
385     * null otherwise
386     */
387    public MimeException getContentDispositionCreationDateParseException() {
388        return contentDispositionCreationDateParseException;
389    }
390   
391    /**
392     * Gets the <code>read-date</code> parameter value of the <code>content-disposition</code> field.
393     * See <a href='http://www.faqs.org/rfcs/rfc2183.html'>RFC2183</a>.
394     * @return read-date parameter value,
395     * or null when this is not present
396     */
397    public DateTime getContentDispositionReadDate() {
398        return contentDispositionReadDate;
399    }
400   
401    /**
402     * Gets any exception thrown during the parsing of {@link #getContentDispositionReadDate()}
403     * @return <code>ParseException</code> when the read-date parse fails,
404     * null otherwise
405     */
406    public MimeException getContentDispositionReadDateParseException() {
407        return contentDispositionReadDateParseException;
408    }
409   
410    /**
411     * Gets the <code>size</code> parameter value of the <code>content-disposition</code> field.
412     * See <a href='http://www.faqs.org/rfcs/rfc2183.html'>RFC2183</a>.
413     * @return size parameter value,
414     * or -1 if this size has not been set
415     */
416    public long getContentDispositionSize() {
417        return contentDispositionSize;
418    }
419   
420    /**
421     * Gets any exception thrown during the parsing of {@link #getContentDispositionSize()}
422     * @return <code>ParseException</code> when the read-date parse fails,
423     * null otherwise
424     */
425    public MimeException getContentDispositionSizeParseException() {
426        return contentDispositionSizeParseException;
427    }
428   
429    /**
430     * Get the <code>content-language</code> header values.
431     * Each applicable language tag will be returned in order.
432     * See <a href='http://tools.ietf.org/html/rfc4646'>RFC4646</a>
433     * <cite>http://tools.ietf.org/html/rfc4646</cite>.
434     * @return list of language tag Strings,
435     * or null if no header exists
436     */
437    public List<String> getContentLanguage() {
438        return contentLanguage;
439    }
440
441    /**
442     * Gets any exception thrown during the parsing of {@link #getContentLanguage()}
443     * @return <code>ParseException</code> when the content-language parse fails,
444     * null otherwise
445     */
446    public MimeException getContentLanguageParseException() {
447        return contentLanguageParseException;
448    }
449   
450
451    /**
452     * Get the <code>content-location</code> header value.
453     * See <a href='http://tools.ietf.org/html/rfc2557'>RFC2557</a>
454     * @return the URL content-location
455     * or null if no header exists
456     */
457    public String getContentLocation() {
458        return contentLocation;
459    }
460   
461    /**
462     * Gets any exception thrown during the parsing of {@link #getContentLocation()}
463     * @return <code>ParseException</code> when the content-language parse fails,
464     * null otherwise
465     */
466    public MimeException getContentLocationParseException() {
467        return contentLocationParseException;
468    }
469   
470    /**
471     * Gets the raw, Base64 encoded value of the
472     * <code>Content-MD5</code> field.
473     * See <a href='http://tools.ietf.org/html/rfc1864'>RFC1864</a>.
474     * @return raw encoded content-md5
475     * or null if no header exists
476     */
477    public String getContentMD5Raw() {
478        return contentMD5Raw;
479    }
480   
481   
482}
Note: See TracBrowser for help on using the repository browser.