19
19
import java .io .ByteArrayOutputStream ;
20
20
import java .nio .charset .Charset ;
21
21
import java .nio .charset .StandardCharsets ;
22
+ import java .time .Instant ;
23
+ import java .time .format .DateTimeFormatter ;
22
24
23
25
import org .springframework .lang .Nullable ;
24
26
import org .springframework .util .Assert ;
@@ -45,16 +47,28 @@ public class ContentDisposition {
45
47
46
48
private final Long size ;
47
49
50
+ private final Instant creationDate ;
51
+
52
+ private final Instant modificationDate ;
53
+
54
+ private final Instant readDate ;
55
+
48
56
49
57
/**
50
58
* Private constructor. See static factory methods in this class.
51
59
*/
52
- private ContentDisposition (@ Nullable String type , @ Nullable String name , @ Nullable String filename , @ Nullable Charset charset , @ Nullable Long size ) {
60
+ private ContentDisposition (@ Nullable String type , @ Nullable String name ,
61
+ @ Nullable String filename , @ Nullable Charset charset , @ Nullable Long size ,
62
+ @ Nullable Instant creationDate , @ Nullable Instant modificationDate , @ Nullable Instant readDate ) {
63
+
53
64
this .type = type ;
54
65
this .name = name ;
55
66
this .filename = filename ;
56
67
this .charset = charset ;
57
68
this .size = size ;
69
+ this .creationDate = creationDate ;
70
+ this .modificationDate = modificationDate ;
71
+ this .readDate = readDate ;
58
72
}
59
73
60
74
@@ -100,6 +114,30 @@ public Long getSize() {
100
114
return this .size ;
101
115
}
102
116
117
+ /**
118
+ * Return the value of the {@literal creation-date} parameter, or {@code null} if not defined.
119
+ */
120
+ @ Nullable
121
+ public Instant getCreationDate () {
122
+ return this .creationDate ;
123
+ }
124
+
125
+ /**
126
+ * Return the value of the {@literal modification-date} parameter, or {@code null} if not defined.
127
+ */
128
+ @ Nullable
129
+ public Instant getModificationDate () {
130
+ return this .modificationDate ;
131
+ }
132
+
133
+ /**
134
+ * Return the value of the {@literal read-date} parameter, or {@code null} if not defined.
135
+ */
136
+ @ Nullable
137
+ public Instant getReadDate () {
138
+ return this .readDate ;
139
+ }
140
+
103
141
104
142
/**
105
143
* Return a builder for a {@code ContentDisposition}.
@@ -115,11 +153,12 @@ public static Builder builder(String type) {
115
153
* Return an empty content disposition.
116
154
*/
117
155
public static ContentDisposition empty () {
118
- return new ContentDisposition (null , null , null , null , null );
156
+ return new ContentDisposition (null , null , null , null , null , null , null , null );
119
157
}
120
158
121
159
/**
122
160
* Parse a {@literal Content-Disposition} header value as defined in RFC 2183.
161
+ *
123
162
* @param contentDisposition the {@literal Content-Disposition} header value
124
163
* @return the parsed content disposition
125
164
* @see #toString()
@@ -132,6 +171,9 @@ public static ContentDisposition parse(String contentDisposition) {
132
171
String filename = null ;
133
172
Charset charset = null ;
134
173
Long size = null ;
174
+ Instant creationDate = null ;
175
+ Instant modificationDate = null ;
176
+ Instant readDate = null ;
135
177
for (int i = 1 ; i < parts .length ; i ++) {
136
178
String part = parts [i ];
137
179
int eqIndex = part .indexOf ('=' );
@@ -155,12 +197,21 @@ else if (attribute.equals("filename") && (filename == null)) {
155
197
else if (attribute .equals ("size" ) ) {
156
198
size = Long .parseLong (value );
157
199
}
200
+ else if (attribute .equals ("creation-date" )) {
201
+ creationDate = DateTimeFormatter .RFC_1123_DATE_TIME .parse (value , Instant ::from );
202
+ }
203
+ else if (attribute .equals ("modification-date" )) {
204
+ modificationDate = DateTimeFormatter .RFC_1123_DATE_TIME .parse (value , Instant ::from );
205
+ }
206
+ else if (attribute .equals ("read-date" )) {
207
+ readDate = DateTimeFormatter .RFC_1123_DATE_TIME .parse (value , Instant ::from );
208
+ }
158
209
}
159
210
else {
160
211
throw new IllegalArgumentException ("Invalid content disposition format" );
161
212
}
162
213
}
163
- return new ContentDisposition (type , name , filename , charset , size );
214
+ return new ContentDisposition (type , name , filename , charset , size , creationDate , modificationDate , readDate );
164
215
}
165
216
166
217
/**
@@ -229,7 +280,16 @@ public boolean equals(Object o) {
229
280
if (charset != null ? !charset .equals (that .charset ) : that .charset != null ) {
230
281
return false ;
231
282
}
232
- return size != null ? size .equals (that .size ) : that .size == null ;
283
+ if (size != null ? !size .equals (that .size ) : that .size != null ) {
284
+ return false ;
285
+ }
286
+ if (creationDate != null ? !creationDate .equals (that .creationDate ) : that .creationDate != null ) {
287
+ return false ;
288
+ }
289
+ if (modificationDate != null ? !modificationDate .equals (that .modificationDate ) : that .modificationDate != null ) {
290
+ return false ;
291
+ }
292
+ return readDate != null ? readDate .equals (that .readDate ) : that .readDate == null ;
233
293
}
234
294
235
295
@ Override
@@ -239,6 +299,9 @@ public int hashCode() {
239
299
result = 31 * result + (filename != null ? filename .hashCode () : 0 );
240
300
result = 31 * result + (charset != null ? charset .hashCode () : 0 );
241
301
result = 31 * result + (size != null ? size .hashCode () : 0 );
302
+ result = 31 * result + (creationDate != null ? creationDate .hashCode () : 0 );
303
+ result = 31 * result + (modificationDate != null ? modificationDate .hashCode () : 0 );
304
+ result = 31 * result + (readDate != null ? readDate .hashCode () : 0 );
242
305
return result ;
243
306
}
244
307
@@ -267,6 +330,21 @@ public String toString() {
267
330
builder .append ("; size=" );
268
331
builder .append (this .size );
269
332
}
333
+ if (this .creationDate != null ) {
334
+ builder .append ("; creation-date=\" " );
335
+ builder .append (DateTimeFormatter .RFC_1123_DATE_TIME .format (this .creationDate ));
336
+ builder .append ('\"' );
337
+ }
338
+ if (this .modificationDate != null ) {
339
+ builder .append ("; modification-date=\" " );
340
+ builder .append (DateTimeFormatter .RFC_1123_DATE_TIME .format (this .modificationDate ));
341
+ builder .append ('\"' );
342
+ }
343
+ if (this .readDate != null ) {
344
+ builder .append ("; read-date=\" " );
345
+ builder .append (DateTimeFormatter .RFC_1123_DATE_TIME .format (this .readDate ));
346
+ builder .append ('\"' );
347
+ }
270
348
return builder .toString ();
271
349
}
272
350
@@ -333,6 +411,21 @@ public interface Builder {
333
411
*/
334
412
Builder size (Long size );
335
413
414
+ /**
415
+ * Set the value of the {@literal creation-date} parameter.
416
+ */
417
+ Builder creationDate (Instant creationDate );
418
+
419
+ /**
420
+ * Set the value of the {@literal modification-date} parameter.
421
+ */
422
+ Builder modificationDate (Instant modificationDate );
423
+
424
+ /**
425
+ * Set the value of the {@literal read-date} parameter.
426
+ */
427
+ Builder readDate (Instant readDate );
428
+
336
429
/**
337
430
* Build the content disposition
338
431
*/
@@ -352,6 +445,13 @@ private static class BuilderImpl implements Builder {
352
445
353
446
private Long size ;
354
447
448
+ private Instant creationDate ;
449
+
450
+ private Instant modificationDate ;
451
+
452
+ private Instant readDate ;
453
+
454
+
355
455
public BuilderImpl (String type ) {
356
456
Assert .hasText (type , "'type' must not be not empty" );
357
457
this .type = type ;
@@ -382,9 +482,28 @@ public Builder size(Long size) {
382
482
return this ;
383
483
}
384
484
485
+ @ Override
486
+ public Builder creationDate (Instant creationDate ) {
487
+ this .creationDate = creationDate ;
488
+ return this ;
489
+ }
490
+
491
+ @ Override
492
+ public Builder modificationDate (Instant modificationDate ) {
493
+ this .modificationDate = modificationDate ;
494
+ return this ;
495
+ }
496
+
497
+ @ Override
498
+ public Builder readDate (Instant readDate ) {
499
+ this .readDate = readDate ;
500
+ return this ;
501
+ }
502
+
385
503
@ Override
386
504
public ContentDisposition build () {
387
- return new ContentDisposition (this .type , this .name , this .filename , this .charset , this .size );
505
+ return new ContentDisposition (this .type , this .name , this .filename , this .charset ,
506
+ this .size , this .creationDate , this .modificationDate , this .readDate );
388
507
}
389
508
}
390
509
0 commit comments