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>If-Unmodified-Since</l> HTTP request header.
026 *
027 * <p>
028 * Only send the response if the entity has not been modified since a specific time.
029 *
030 * <h5 class='figure'>Example</h5>
031 * <p class='bcode'>
032 *    If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT
033 * </p>
034 *
035 * <h5 class='topic'>RFC2616 Specification</h5>
036 *
037 * The If-Unmodified-Since request-header field is used with a method to make it conditional.
038 * If the requested resource has not been modified since the time specified in this field, the server SHOULD perform the
039 * requested operation as if the If-Unmodified-Since header were not present.
040 *
041 * <p>
042 * If the requested variant has been modified since the specified time, the server MUST NOT perform the requested
043 * operation, and MUST return a 412 (Precondition Failed).
044 *
045 * <p class='bcode'>
046 *    If-Unmodified-Since = "If-Unmodified-Since" ":" HTTP-date
047 * </p>
048 *
049 * <p>
050 * An example of the field is:
051 * <p class='bcode'>
052 *    If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT
053 * </p>
054 *
055 * <p>
056 * If the request normally (i.e., without the If-Unmodified-Since header) would result in anything other than a 2xx or
057 * 412 status, the If-Unmodified-Since header SHOULD be ignored.
058 *
059 * <p>
060 * If the specified date is invalid, the header is ignored.
061 *
062 * <p>
063 * The result of a request having both an If-Unmodified-Since header field and either an If-None-Match or an
064 * If-Modified-Since header fields is undefined by this specification.
065 *
066 * <h5 class='section'>See Also:</h5><ul>
067 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauRestCommonBasics">juneau-rest-common Basics</a>
068 *    <li class='extlink'><a class="doclink" href="https://www.w3.org/Protocols/rfc2616/rfc2616.html">Hypertext Transfer Protocol -- HTTP/1.1</a>
069 * </ul>
070 *
071 * @serial exclude
072 */
073@Header("If-Unmodified-Since")
074public class IfUnmodifiedSince extends BasicDateHeader {
075
076   //-----------------------------------------------------------------------------------------------------------------
077   // Static
078   //-----------------------------------------------------------------------------------------------------------------
079
080   private static final long serialVersionUID = 1L;
081   private static final String NAME = "If-Unmodified-Since";
082
083   /**
084    * Static creator.
085    *
086    * @param value
087    *    The header value.
088    *    <br>Must be an RFC-1123 formated string (e.g. <js>"Sat, 29 Oct 1994 19:43:31 GMT"</js>).
089    *    <br>Can be <jk>null</jk>.
090    * @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>.
091    */
092   public static IfUnmodifiedSince of(String value) {
093      return value == null ? null : new IfUnmodifiedSince(value);
094   }
095
096   /**
097    * Static creator.
098    *
099    * @param value
100    *    The header value.
101    *    <br>Can be <jk>null</jk>.
102    * @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>.
103    */
104   public static IfUnmodifiedSince of(ZonedDateTime value) {
105      return value == null ? null : new IfUnmodifiedSince(value);
106   }
107
108   /**
109    * Static creator with delayed value.
110    *
111    * <p>
112    * Header value is re-evaluated on each call to {@link #getValue()}.
113    *
114    * @param value
115    *    The supplier of the header value.
116    *    <br>Can be <jk>null</jk>.
117    * @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>.
118    */
119   public static IfUnmodifiedSince of(Supplier<ZonedDateTime> value) {
120      return value == null ? null : new IfUnmodifiedSince(value);
121   }
122
123   //-----------------------------------------------------------------------------------------------------------------
124   // Instance
125   //-----------------------------------------------------------------------------------------------------------------
126
127   /**
128    * Constructor.
129    *
130    * @param value
131    *    The header value.
132    *    <br>Must be an RFC-1123 formated string (e.g. <js>"Sat, 29 Oct 1994 19:43:31 GMT"</js>).
133    *    <br>Can be <jk>null</jk>.
134    */
135   public IfUnmodifiedSince(String value) {
136      super(NAME, value);
137   }
138
139   /**
140    * Constructor.
141    *
142    * @param value
143    *    The header value.
144    *    <br>Can be <jk>null</jk>.
145    */
146   public IfUnmodifiedSince(ZonedDateTime value) {
147      super(NAME, value);
148   }
149
150   /**
151    * Constructor with delayed value.
152    *
153    * <p>
154    * Header value is re-evaluated on each call to {@link #getValue()}.
155    *
156    * @param value
157    *    The supplier of the header value.
158    *    <br>Can be <jk>null</jk>.
159    */
160   public IfUnmodifiedSince(Supplier<ZonedDateTime> value) {
161      super(NAME, value);
162   }
163}