001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.http.header;
018
019import java.time.*;
020import java.util.function.*;
021
022import org.apache.juneau.http.annotation.*;
023
024/**
025 * Represents a parsed <l>Expires</l> HTTP response header.
026 *
027 * <p>
028 * Gives the date/time after which the response is considered stale (in "HTTP-date" format as defined by RFC 7231).
029 *
030 * <h5 class='figure'>Example</h5>
031 * <p class='bcode'>
032 *    Expires: Thu, 01 Dec 1994 16:00:00 GMT
033 * </p>
034 *
035 * <h5 class='topic'>RFC2616 Specification</h5>
036 *
037 * The Expires entity-header field gives the date/time after which the response is considered stale.
038 * A stale cache entry may not normally be returned by a cache (either a proxy cache or a user agent cache) unless it is
039 * first validated with the origin server
040 * (or with an intermediate cache that has a fresh copy of the entity).
041 * See section 13.2 for further discussion of the expiration model.
042 *
043 * <p>
044 * The presence of an Expires field does not imply that the original resource will change or cease to exist at, before,
045 * or after that time.
046 *
047 * <p>
048 * The format is an absolute date and time as defined by HTTP-date in section 3.3.1; it MUST be in RFC 1123 date format:
049 *
050 * <p class='bcode'>
051 *    Expires = "Expires" ":" HTTP-date
052 * </p>
053 *
054 * <p>
055 * An example of its use is...
056 * <p class='bcode'>
057 *    Expires: Thu, 01 Dec 1994 16:00:00 GMT
058 * </p>
059 *
060 * <p>
061 * Note: if a response includes a Cache-Control field with the max-age directive (see section 14.9.3), that directive
062 * overrides the Expires field.
063 *
064 * <p>
065 * HTTP/1.1 clients and caches MUST treat other invalid date formats, especially including the value "0", as in the past
066 * (i.e., "already expired").
067 *
068 * <p>
069 * To mark a response as "already expired," an origin server sends an Expires date that is equal to the Date header
070 * value.
071 * (See the rules for expiration calculations in section 13.2.4.)
072 *
073 * <p>
074 * To mark a response as "never expires," an origin server sends an Expires date approximately one year from the time
075 * the response is sent.
076 * HTTP/1.1 servers SHOULD NOT send Expires dates more than one year in the future.
077 *
078 * <p>
079 * The presence of an Expires header field with a date value of some time in the future on a response that otherwise
080 * would by default be non-cacheable indicates that the response is cacheable, unless indicated otherwise by a
081 * Cache-Control header field (section 14.9).
082 *
083 * <h5 class='section'>See Also:</h5><ul>
084 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauRestCommonBasics">juneau-rest-common Basics</a>
085 *    <li class='extlink'><a class="doclink" href="https://www.w3.org/Protocols/rfc2616/rfc2616.html">Hypertext Transfer Protocol -- HTTP/1.1</a>
086 * </ul>
087 *
088 * @serial exclude
089 */
090@Header("Expires")
091public class Expires extends BasicDateHeader {
092
093   //-----------------------------------------------------------------------------------------------------------------
094   // Static
095   //-----------------------------------------------------------------------------------------------------------------
096
097   private static final long serialVersionUID = 1L;
098   private static final String NAME = "Expires";
099
100   /**
101    * Static creator.
102    *
103    * @param value
104    *    The header value.
105    *    <br>Must be an RFC-1123 formated string (e.g. <js>"Sat, 29 Oct 1994 19:43:31 GMT"</js>).
106    *    <br>Can be <jk>null</jk>.
107    * @return A new header bean, or <jk>null</jk> if the name is <jk>null</jk> or empty or the value is <jk>null</jk>.
108    */
109   public static Expires of(String value) {
110      return value == null ? null : new Expires(value);
111   }
112
113   /**
114    * Static creator.
115    *
116    * @param value
117    *    The header value.
118    *    <br>Can be <jk>null</jk>.
119    * @return A new header bean, or <jk>null</jk> if the name is <jk>null</jk> or empty or the value is <jk>null</jk>.
120    */
121   public static Expires of(ZonedDateTime value) {
122      return value == null ? null : new Expires(value);
123   }
124
125   /**
126    * Static creator with delayed value.
127    *
128    * <p>
129    * Header value is re-evaluated on each call to {@link #getValue()}.
130    *
131    * @param value
132    *    The supplier of the header value.
133    *    <br>Can be <jk>null</jk>.
134    * @return A new header bean, or <jk>null</jk> if the name is <jk>null</jk> or empty or the value is <jk>null</jk>.
135    */
136   public static Expires of(Supplier<ZonedDateTime> value) {
137      return value == null ? null : new Expires(value);
138   }
139
140   //-----------------------------------------------------------------------------------------------------------------
141   // Instance
142   //-----------------------------------------------------------------------------------------------------------------
143
144   /**
145    * Constructor.
146    *
147    * @param value
148    *    The header value.
149    *    <br>Must be an RFC-1123 formated string (e.g. <js>"Sat, 29 Oct 1994 19:43:31 GMT"</js>).
150    *    <br>Can be <jk>null</jk>.
151    */
152   public Expires(String value) {
153      super(NAME, value);
154   }
155
156   /**
157    * Constructor.
158    *
159    * @param value
160    *    The header value.
161    *    <br>Can be <jk>null</jk>.
162    */
163   public Expires(ZonedDateTime value) {
164      super(NAME, value);
165   }
166
167   /**
168    * Constructor with delayed value.
169    *
170    * <p>
171    * Header value is re-evaluated on each call to {@link #getValue()}.
172    *
173    * @param value
174    *    The supplier of the header value.
175    *    <br>Can be <jk>null</jk>.
176    */
177   public Expires(Supplier<ZonedDateTime> value) {
178      super(NAME, value);
179   }
180}