1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.james.mime4j.descriptor;
21
22 import java.io.StringReader;
23 import java.util.Collections;
24 import java.util.List;
25 import java.util.Map;
26
27 import org.apache.james.mime4j.MimeException;
28 import org.apache.james.mime4j.field.datetime.DateTime;
29 import org.apache.james.mime4j.field.datetime.parser.DateTimeParser;
30 import org.apache.james.mime4j.field.datetime.parser.ParseException;
31 import org.apache.james.mime4j.field.language.parser.ContentLanguageParser;
32 import org.apache.james.mime4j.field.mimeversion.parser.MimeVersionParser;
33 import org.apache.james.mime4j.field.structured.parser.StructuredFieldParser;
34 import org.apache.james.mime4j.parser.Field;
35 import org.apache.james.mime4j.util.MimeUtil;
36
37
38
39
40
41 public class MaximalBodyDescriptor extends DefaultBodyDescriptor {
42
43 private static final int DEFAULT_MINOR_VERSION = 0;
44 private static final int DEFAULT_MAJOR_VERSION = 1;
45 private boolean isMimeVersionSet;
46 private int mimeMinorVersion;
47 private int mimeMajorVersion;
48 private MimeException mimeVersionException;
49 private String contentId;
50 private boolean isContentIdSet;
51 private String contentDescription;
52 private boolean isContentDescriptionSet;
53 private String contentDispositionType;
54 private Map<String, String> contentDispositionParameters;
55 private DateTime contentDispositionModificationDate;
56 private MimeException contentDispositionModificationDateParseException;
57 private DateTime contentDispositionCreationDate;
58 private MimeException contentDispositionCreationDateParseException;
59 private DateTime contentDispositionReadDate;
60 private MimeException contentDispositionReadDateParseException;
61 private long contentDispositionSize;
62 private MimeException contentDispositionSizeParseException;
63 private boolean isContentDispositionSet;
64 private List<String> contentLanguage;
65 private MimeException contentLanguageParseException;
66 private boolean isContentLanguageSet;
67 private MimeException contentLocationParseException;
68 private String contentLocation;
69 private boolean isContentLocationSet;
70 private String contentMD5Raw;
71 private boolean isContentMD5Set;
72
73 protected MaximalBodyDescriptor() {
74 this(null);
75 }
76
77 public MaximalBodyDescriptor(BodyDescriptor parent) {
78 super(parent);
79 isMimeVersionSet = false;
80 mimeMajorVersion = DEFAULT_MAJOR_VERSION;
81 mimeMinorVersion = DEFAULT_MINOR_VERSION;
82 this.contentId = null;
83 this.isContentIdSet = false;
84 this.contentDescription = null;
85 this.isContentDescriptionSet = false;
86 this.contentDispositionType = null;
87 this.contentDispositionParameters = Collections.emptyMap();
88 this.contentDispositionModificationDate = null;
89 this.contentDispositionModificationDateParseException = null;
90 this.contentDispositionCreationDate = null;
91 this.contentDispositionCreationDateParseException = null;
92 this.contentDispositionReadDate = null;
93 this.contentDispositionReadDateParseException = null;
94 this.contentDispositionSize = -1;
95 this.contentDispositionSizeParseException = null;
96 this.isContentDispositionSet = false;
97 this.contentLanguage = null;
98 this.contentLanguageParseException = null;
99 this.isContentIdSet = false;
100 this.contentLocation = null;
101 this.contentLocationParseException = null;
102 this.isContentLocationSet = false;
103 this.contentMD5Raw = null;
104 this.isContentMD5Set = false;
105 }
106
107 @Override
108 public void addField(Field field) {
109 String name = field.getName();
110 String value = field.getBody();
111 name = name.trim().toLowerCase();
112 if (MimeUtil.MIME_HEADER_MIME_VERSION.equals(name) && !isMimeVersionSet) {
113 parseMimeVersion(value);
114 } else if (MimeUtil.MIME_HEADER_CONTENT_ID.equals(name) && !isContentIdSet) {
115 parseContentId(value);
116 } else if (MimeUtil.MIME_HEADER_CONTENT_DESCRIPTION.equals(name) && !isContentDescriptionSet) {
117 parseContentDescription(value);
118 } else if (MimeUtil.MIME_HEADER_CONTENT_DISPOSITION.equals(name) && !isContentDispositionSet) {
119 parseContentDisposition(value);
120 } else if (MimeUtil.MIME_HEADER_LANGAUGE.equals(name) && !isContentLanguageSet) {
121 parseLanguage(value);
122 } else if (MimeUtil.MIME_HEADER_LOCATION.equals(name) && !isContentLocationSet) {
123 parseLocation(value);
124 } else if (MimeUtil.MIME_HEADER_MD5.equals(name) && !isContentMD5Set) {
125 parseMD5(value);
126 } else {
127 super.addField(field);
128 }
129 }
130
131 private void parseMD5(String value) {
132 isContentMD5Set = true;
133 if (value != null) {
134 contentMD5Raw = value.trim();
135 }
136 }
137
138 private void parseLocation(final String value) {
139 isContentLocationSet = true;
140 if (value != null) {
141 final StringReader stringReader = new StringReader(value);
142 final StructuredFieldParser parser = new StructuredFieldParser(stringReader);
143 parser.setFoldingPreserved(false);
144 try {
145 contentLocation = parser.parse();
146 } catch (MimeException e) {
147 contentLocationParseException = e;
148 }
149 }
150 }
151
152 private void parseLanguage(final String value) {
153 isContentLanguageSet = true;
154 if (value != null) {
155 try {
156 final ContentLanguageParser parser = new ContentLanguageParser(new StringReader(value));
157 contentLanguage = parser.parse();
158 } catch (MimeException e) {
159 contentLanguageParseException = e;
160 }
161 }
162 }
163
164 private void parseContentDisposition(final String value) {
165 isContentDispositionSet = true;
166 contentDispositionParameters = MimeUtil.getHeaderParams(value);
167 contentDispositionType = contentDispositionParameters.get("");
168
169 final String contentDispositionModificationDate
170 = contentDispositionParameters.get(MimeUtil.PARAM_MODIFICATION_DATE);
171 if (contentDispositionModificationDate != null) {
172 try {
173 this.contentDispositionModificationDate = parseDate(contentDispositionModificationDate);
174 } catch (ParseException e) {
175 this.contentDispositionModificationDateParseException = e;
176 }
177 }
178
179 final String contentDispositionCreationDate
180 = contentDispositionParameters.get(MimeUtil.PARAM_CREATION_DATE);
181 if (contentDispositionCreationDate != null) {
182 try {
183 this.contentDispositionCreationDate = parseDate(contentDispositionCreationDate);
184 } catch (ParseException e) {
185 this.contentDispositionCreationDateParseException = e;
186 }
187 }
188
189 final String contentDispositionReadDate
190 = contentDispositionParameters.get(MimeUtil.PARAM_READ_DATE);
191 if (contentDispositionReadDate != null) {
192 try {
193 this.contentDispositionReadDate = parseDate(contentDispositionReadDate);
194 } catch (ParseException e) {
195 this.contentDispositionReadDateParseException = e;
196 }
197 }
198
199 final String size = contentDispositionParameters.get(MimeUtil.PARAM_SIZE);
200 if (size != null) {
201 try {
202 contentDispositionSize = Long.parseLong(size);
203 } catch (NumberFormatException e) {
204 this.contentDispositionSizeParseException = (MimeException) new MimeException(e.getMessage(), e).fillInStackTrace();
205 }
206 }
207 contentDispositionParameters.remove("");
208 }
209
210 private DateTime parseDate(final String date) throws ParseException {
211 final StringReader stringReader = new StringReader(date);
212 final DateTimeParser parser = new DateTimeParser(stringReader);
213 DateTime result = parser.date_time();
214 return result;
215 }
216
217 private void parseContentDescription(String value) {
218 if (value == null) {
219 contentDescription = "";
220 } else {
221 contentDescription = value.trim();
222 }
223 isContentDescriptionSet = true;
224 }
225
226 private void parseContentId(final String value) {
227 if (value == null) {
228 contentId = "";
229 } else {
230 contentId = value.trim();
231 }
232 isContentIdSet = true;
233 }
234
235 private void parseMimeVersion(String value) {
236 final StringReader reader = new StringReader(value);
237 final MimeVersionParser parser = new MimeVersionParser(reader);
238 try {
239 parser.parse();
240 final int major = parser.getMajorVersion();
241 if (major != MimeVersionParser.INITIAL_VERSION_VALUE) {
242 mimeMajorVersion = major;
243 }
244 final int minor = parser.getMinorVersion();
245 if (minor != MimeVersionParser.INITIAL_VERSION_VALUE) {
246 mimeMinorVersion = minor;
247 }
248 } catch (MimeException e) {
249 this.mimeVersionException = e;
250 }
251 isMimeVersionSet = true;
252 }
253
254
255
256
257
258
259
260
261 public int getMimeMajorVersion() {
262 return mimeMajorVersion;
263 }
264
265
266
267
268
269
270
271
272 public int getMimeMinorVersion() {
273 return mimeMinorVersion;
274 }
275
276
277
278
279
280
281
282
283 public MimeException getMimeVersionParseException() {
284 return mimeVersionException;
285 }
286
287
288
289
290
291
292
293 public String getContentDescription() {
294 return contentDescription;
295 }
296
297
298
299
300
301
302
303 public String getContentId() {
304 return contentId;
305 }
306
307
308
309
310
311
312
313
314 public String getContentDispositionType() {
315 return contentDispositionType;
316 }
317
318
319
320
321
322
323
324 public Map<String, String> getContentDispositionParameters() {
325 return contentDispositionParameters;
326 }
327
328
329
330
331
332
333
334 public String getContentDispositionFilename() {
335 return contentDispositionParameters.get(MimeUtil.PARAM_FILENAME);
336 }
337
338
339
340
341
342
343
344 public DateTime getContentDispositionModificationDate() {
345 return contentDispositionModificationDate;
346 }
347
348
349
350
351
352
353 public MimeException getContentDispositionModificationDateParseException() {
354 return contentDispositionModificationDateParseException;
355 }
356
357
358
359
360
361
362
363 public DateTime getContentDispositionCreationDate() {
364 return contentDispositionCreationDate;
365 }
366
367
368
369
370
371
372 public MimeException getContentDispositionCreationDateParseException() {
373 return contentDispositionCreationDateParseException;
374 }
375
376
377
378
379
380
381
382 public DateTime getContentDispositionReadDate() {
383 return contentDispositionReadDate;
384 }
385
386
387
388
389
390
391 public MimeException getContentDispositionReadDateParseException() {
392 return contentDispositionReadDateParseException;
393 }
394
395
396
397
398
399
400
401 public long getContentDispositionSize() {
402 return contentDispositionSize;
403 }
404
405
406
407
408
409
410 public MimeException getContentDispositionSizeParseException() {
411 return contentDispositionSizeParseException;
412 }
413
414
415
416
417
418
419
420
421
422 public List<String> getContentLanguage() {
423 return contentLanguage;
424 }
425
426
427
428
429
430
431 public MimeException getContentLanguageParseException() {
432 return contentLanguageParseException;
433 }
434
435
436
437
438
439
440
441
442 public String getContentLocation() {
443 return contentLocation;
444 }
445
446
447
448
449
450
451 public MimeException getContentLocationParseException() {
452 return contentLocationParseException;
453 }
454
455
456
457
458
459
460
461
462 public String getContentMD5Raw() {
463 return contentMD5Raw;
464 }
465
466
467 }