1919import java .io .ByteArrayOutputStream ;
2020import java .nio .charset .Charset ;
2121import java .nio .charset .StandardCharsets ;
22+ import java .time .Instant ;
23+ import java .time .format .DateTimeFormatter ;
2224
2325import org .springframework .lang .Nullable ;
2426import org .springframework .util .Assert ;
@@ -45,16 +47,28 @@ public class ContentDisposition {
4547
4648 private final Long size ;
4749
50+ private final Instant creationDate ;
51+
52+ private final Instant modificationDate ;
53+
54+ private final Instant readDate ;
55+
4856
4957 /**
5058 * Private constructor. See static factory methods in this class.
5159 */
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+
5364 this .type = type ;
5465 this .name = name ;
5566 this .filename = filename ;
5667 this .charset = charset ;
5768 this .size = size ;
69+ this .creationDate = creationDate ;
70+ this .modificationDate = modificationDate ;
71+ this .readDate = readDate ;
5872 }
5973
6074
@@ -100,6 +114,30 @@ public Long getSize() {
100114 return this .size ;
101115 }
102116
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+
103141
104142 /**
105143 * Return a builder for a {@code ContentDisposition}.
@@ -115,11 +153,12 @@ public static Builder builder(String type) {
115153 * Return an empty content disposition.
116154 */
117155 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 );
119157 }
120158
121159 /**
122160 * Parse a {@literal Content-Disposition} header value as defined in RFC 2183.
161+ *
123162 * @param contentDisposition the {@literal Content-Disposition} header value
124163 * @return the parsed content disposition
125164 * @see #toString()
@@ -132,6 +171,9 @@ public static ContentDisposition parse(String contentDisposition) {
132171 String filename = null ;
133172 Charset charset = null ;
134173 Long size = null ;
174+ Instant creationDate = null ;
175+ Instant modificationDate = null ;
176+ Instant readDate = null ;
135177 for (int i = 1 ; i < parts .length ; i ++) {
136178 String part = parts [i ];
137179 int eqIndex = part .indexOf ('=' );
@@ -155,12 +197,21 @@ else if (attribute.equals("filename") && (filename == null)) {
155197 else if (attribute .equals ("size" ) ) {
156198 size = Long .parseLong (value );
157199 }
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+ }
158209 }
159210 else {
160211 throw new IllegalArgumentException ("Invalid content disposition format" );
161212 }
162213 }
163- return new ContentDisposition (type , name , filename , charset , size );
214+ return new ContentDisposition (type , name , filename , charset , size , creationDate , modificationDate , readDate );
164215 }
165216
166217 /**
@@ -229,7 +280,16 @@ public boolean equals(Object o) {
229280 if (charset != null ? !charset .equals (that .charset ) : that .charset != null ) {
230281 return false ;
231282 }
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 ;
233293 }
234294
235295 @ Override
@@ -239,6 +299,9 @@ public int hashCode() {
239299 result = 31 * result + (filename != null ? filename .hashCode () : 0 );
240300 result = 31 * result + (charset != null ? charset .hashCode () : 0 );
241301 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 );
242305 return result ;
243306 }
244307
@@ -267,6 +330,21 @@ public String toString() {
267330 builder .append ("; size=" );
268331 builder .append (this .size );
269332 }
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+ }
270348 return builder .toString ();
271349 }
272350
@@ -333,6 +411,21 @@ public interface Builder {
333411 */
334412 Builder size (Long size );
335413
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+
336429 /**
337430 * Build the content disposition
338431 */
@@ -352,6 +445,13 @@ private static class BuilderImpl implements Builder {
352445
353446 private Long size ;
354447
448+ private Instant creationDate ;
449+
450+ private Instant modificationDate ;
451+
452+ private Instant readDate ;
453+
454+
355455 public BuilderImpl (String type ) {
356456 Assert .hasText (type , "'type' must not be not empty" );
357457 this .type = type ;
@@ -382,9 +482,28 @@ public Builder size(Long size) {
382482 return this ;
383483 }
384484
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+
385503 @ Override
386504 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 );
388507 }
389508 }
390509
0 commit comments