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.field;
21
22 import java.io.StringReader;
23 import java.util.Collections;
24 import java.util.Date;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Locale;
28 import java.util.Map;
29
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.apache.james.mime4j.field.contentdisposition.parser.ContentDispositionParser;
33 import org.apache.james.mime4j.field.contentdisposition.parser.TokenMgrError;
34 import org.apache.james.mime4j.field.datetime.parser.DateTimeParser;
35 import org.apache.james.mime4j.util.ByteSequence;
36
37
38
39
40 public class ContentDispositionField extends AbstractField {
41 private static Log log = LogFactory.getLog(ContentDispositionField.class);
42
43
44 public static final String DISPOSITION_TYPE_INLINE = "inline";
45
46
47 public static final String DISPOSITION_TYPE_ATTACHMENT = "attachment";
48
49
50 public static final String PARAM_FILENAME = "filename";
51
52
53 public static final String PARAM_CREATION_DATE = "creation-date";
54
55
56 public static final String PARAM_MODIFICATION_DATE = "modification-date";
57
58
59 public static final String PARAM_READ_DATE = "read-date";
60
61
62 public static final String PARAM_SIZE = "size";
63
64 private boolean parsed = false;
65
66 private String dispositionType = "";
67 private Map<String, String> parameters = new HashMap<String, String>();
68 private ParseException parseException;
69
70 private boolean creationDateParsed;
71 private Date creationDate;
72
73 private boolean modificationDateParsed;
74 private Date modificationDate;
75
76 private boolean readDateParsed;
77 private Date readDate;
78
79 ContentDispositionField(String name, String body, ByteSequence raw) {
80 super(name, body, raw);
81 }
82
83
84
85
86
87 @Override
88 public ParseException getParseException() {
89 if (!parsed)
90 parse();
91
92 return parseException;
93 }
94
95
96
97
98
99
100 public String getDispositionType() {
101 if (!parsed)
102 parse();
103
104 return dispositionType;
105 }
106
107
108
109
110
111
112
113
114 public String getParameter(String name) {
115 if (!parsed)
116 parse();
117
118 return parameters.get(name.toLowerCase());
119 }
120
121
122
123
124
125
126 public Map<String, String> getParameters() {
127 if (!parsed)
128 parse();
129
130 return Collections.unmodifiableMap(parameters);
131 }
132
133
134
135
136
137
138
139
140
141 public boolean isDispositionType(String dispositionType) {
142 if (!parsed)
143 parse();
144
145 return this.dispositionType.equalsIgnoreCase(dispositionType);
146 }
147
148
149
150
151
152
153
154
155 public boolean isInline() {
156 if (!parsed)
157 parse();
158
159 return dispositionType.equals(DISPOSITION_TYPE_INLINE);
160 }
161
162
163
164
165
166
167
168
169 public boolean isAttachment() {
170 if (!parsed)
171 parse();
172
173 return dispositionType.equals(DISPOSITION_TYPE_ATTACHMENT);
174 }
175
176
177
178
179
180
181
182 public String getFilename() {
183 return getParameter(PARAM_FILENAME);
184 }
185
186
187
188
189
190
191
192
193 public Date getCreationDate() {
194 if (!creationDateParsed) {
195 creationDate = parseDate(PARAM_CREATION_DATE);
196 creationDateParsed = true;
197 }
198
199 return creationDate;
200 }
201
202
203
204
205
206
207
208
209 public Date getModificationDate() {
210 if (!modificationDateParsed) {
211 modificationDate = parseDate(PARAM_MODIFICATION_DATE);
212 modificationDateParsed = true;
213 }
214
215 return modificationDate;
216 }
217
218
219
220
221
222
223
224
225 public Date getReadDate() {
226 if (!readDateParsed) {
227 readDate = parseDate(PARAM_READ_DATE);
228 readDateParsed = true;
229 }
230
231 return readDate;
232 }
233
234
235
236
237
238
239
240 public long getSize() {
241 String value = getParameter(PARAM_SIZE);
242 if (value == null)
243 return -1;
244
245 try {
246 long size = Long.parseLong(value);
247 return size < 0 ? -1 : size;
248 } catch (NumberFormatException e) {
249 return -1;
250 }
251 }
252
253 private Date parseDate(String paramName) {
254 String value = getParameter(paramName);
255 if (value == null) {
256 if (log.isDebugEnabled()) {
257 log.debug("Parsing " + paramName + " null");
258 }
259 return null;
260 }
261
262 try {
263 return new DateTimeParser(new StringReader(value)).parseAll()
264 .getDate();
265 } catch (ParseException e) {
266 if (log.isDebugEnabled()) {
267 log.debug("Parsing " + paramName + " '" + value + "': "
268 + e.getMessage());
269 }
270 return null;
271 } catch (org.apache.james.mime4j.field.datetime.parser.TokenMgrError e) {
272 if (log.isDebugEnabled()) {
273 log.debug("Parsing " + paramName + " '" + value + "': "
274 + e.getMessage());
275 }
276 return null;
277 }
278 }
279
280 private void parse() {
281 String body = getBody();
282
283 ContentDispositionParser parser = new ContentDispositionParser(
284 new StringReader(body));
285 try {
286 parser.parseAll();
287 } catch (ParseException e) {
288 if (log.isDebugEnabled()) {
289 log.debug("Parsing value '" + body + "': " + e.getMessage());
290 }
291 parseException = e;
292 } catch (TokenMgrError e) {
293 if (log.isDebugEnabled()) {
294 log.debug("Parsing value '" + body + "': " + e.getMessage());
295 }
296 parseException = new ParseException(e.getMessage());
297 }
298
299 final String dispositionType = parser.getDispositionType();
300
301 if (dispositionType != null) {
302 this.dispositionType = dispositionType.toLowerCase(Locale.US);
303
304 List<String> paramNames = parser.getParamNames();
305 List<String> paramValues = parser.getParamValues();
306
307 if (paramNames != null && paramValues != null) {
308 final int len = Math.min(paramNames.size(), paramValues.size());
309 for (int i = 0; i < len; i++) {
310 String paramName = paramNames.get(i).toLowerCase(Locale.US);
311 String paramValue = paramValues.get(i);
312 parameters.put(paramName, paramValue);
313 }
314 }
315 }
316
317 parsed = true;
318 }
319
320 static final FieldParser PARSER = new FieldParser() {
321 public ParsedField parse(final String name, final String body,
322 final ByteSequence raw) {
323 return new ContentDispositionField(name, body, raw);
324 }
325 };
326 }