001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. You may obtain a copy of the License at * 006// * * 007// * http://www.apache.org/licenses/LICENSE-2.0 * 008// * * 009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau.http.header; 014 015import java.util.function.*; 016 017import org.apache.juneau.http.annotation.*; 018 019/** 020 * Represents a parsed <l>If-None-Match</l> HTTP request header. 021 * 022 * <p> 023 * Allows a 304 Not Modified to be returned if content is unchanged. 024 * 025 * <h5 class='figure'>Example</h5> 026 * <p class='bcode'> 027 * If-None-Match: "737060cd8c284d8af7ad3082f209582d" 028 * </p> 029 * 030 * <h5 class='topic'>RFC2616 Specification</h5> 031 * 032 * The If-None-Match request-header field is used with a method to make it conditional. 033 * A client that has one or more entities previously obtained from the resource can verify that none of those entities 034 * is current by including a list of their associated entity tags in the If-None-Match header field. 035 * The purpose of this feature is to allow efficient updates of cached information with a minimum amount of transaction 036 * overhead. 037 * It is also used to prevent a method (e.g. PUT) from inadvertently modifying an existing resource when the client 038 * believes that the resource does not exist. 039 * 040 * <p> 041 * As a special case, the value "*" matches any current entity of the resource. 042 * 043 * <p class='bcode'> 044 * If-None-Match = "If-None-Match" ":" ( "*" | 1#entity-tag ) 045 * </p> 046 * 047 * <p> 048 * If any of the entity tags match the entity tag of the entity that would have been returned in the response to a 049 * similar GET request (without the If-None-Match header) on that resource, or if "*" is given 050 * and any current entity exists for that resource, then the server MUST NOT perform the requested method, unless 051 * required to do so because the resource's modification date fails to match that supplied in an If-Modified-Since 052 * header field in the request. 053 * Instead, if the request method was GET or HEAD, the server SHOULD respond with a 304 (Not Modified) response, 054 * including the cache- related header fields (particularly ETag) of one of the entities that matched. 055 * For all other request methods, the server MUST respond with a status of 412 (Precondition Failed). 056 * 057 * <p> 058 * See section 13.3.3 for rules on how to determine if two entities tags match. 059 * The weak comparison function can only be used with GET or HEAD requests. 060 * 061 * <p> 062 * If none of the entity tags match, then the server MAY perform the requested method as if the If-None-Match header 063 * field did not exist, but MUST also ignore any If-Modified-Since header field(s) in the request. 064 * That is, if no entity tags match, then the server MUST NOT return a 304 (Not Modified) response. 065 * 066 * <p> 067 * If the request would, without the If-None-Match header field, result in anything other than a 2xx or 304 status, 068 * then the If-None-Match header MUST be ignored. 069 * (See section 13.3.4 for a discussion of server behavior when both If-Modified-Since and If-None-Match appear in the 070 * same request.) 071 * 072 * <p> 073 * The meaning of "If-None-Match: *" is that the method MUST NOT be performed if the representation selected by the 074 * origin server (or by a cache, possibly using the Vary mechanism, see section 14.44) exists, and SHOULD be performed 075 * if the representation does not exist. 076 * This feature is intended to be useful in preventing races between PUT operations. 077 * 078 * <p> 079 * Examples: 080 * <p class='bcode'> 081 * If-None-Match: "xyzzy" 082 * If-None-Match: W/"xyzzy" 083 * If-None-Match: "xyzzy", "r2d2xxxx", "c3piozzzz" 084 * If-None-Match: W/"xyzzy", W/"r2d2xxxx", W/"c3piozzzz" 085 * If-None-Match: * 086 * </p> 087 * 088 * <p> 089 * The result of a request having both an If-None-Match header field and either an If-Match or an If-Unmodified-Since 090 * header fields is undefined by this specification. 091 * 092 * <h5 class='section'>See Also:</h5><ul> 093 * <li class='link'><a class="doclink" href="../../../../../index.html#juneau-rest-common">juneau-rest-common</a> 094 * <li class='extlink'><a class="doclink" href="https://www.w3.org/Protocols/rfc2616/rfc2616.html">Hypertext Transfer Protocol -- HTTP/1.1</a> 095 * </ul> 096 * 097 * @serial exclude 098 */ 099@Header("If-None-Match") 100public class IfNoneMatch extends BasicEntityTagsHeader { 101 102 //----------------------------------------------------------------------------------------------------------------- 103 // Static 104 //----------------------------------------------------------------------------------------------------------------- 105 106 private static final long serialVersionUID = 1L; 107 private static final String NAME = "If-None-Match"; 108 109 /** 110 * Static creator. 111 * 112 * @param value 113 * The header value. 114 * <br>Must be a comma-delimited list of entity validator values (e.g. <js>"\"xyzzy\", \"r2d2xxxx\", \"c3piozzzz\""</js>). 115 * <br>Can be <jk>null</jk>. 116 * @return A new header bean, or <jk>null</jk> if the value is <jk>null</jk>. 117 */ 118 public static IfNoneMatch of(String value) { 119 return value == null ? null : new IfNoneMatch(value); 120 } 121 122 /** 123 * Static creator. 124 * 125 * @param value 126 * The header value. 127 * <br>Can be <jk>null</jk>. 128 * @return A new header bean, or <jk>null</jk> if the value is <jk>null</jk>. 129 */ 130 public static IfNoneMatch of(EntityTags value) { 131 return value == null ? null : new IfNoneMatch(value); 132 } 133 134 /** 135 * Static creator with delayed value. 136 * 137 * <p> 138 * Header value is re-evaluated on each call to {@link #getValue()}. 139 * 140 * @param value 141 * The supplier of the header value. 142 * <br>Can be <jk>null</jk>. 143 * @return A new header bean, or <jk>null</jk> if the value is <jk>null</jk>. 144 */ 145 public static IfNoneMatch of(Supplier<EntityTags> value) { 146 return value == null ? null : new IfNoneMatch(value); 147 } 148 149 //----------------------------------------------------------------------------------------------------------------- 150 // Instance 151 //----------------------------------------------------------------------------------------------------------------- 152 153 /** 154 * Constructor. 155 * 156 * @param value 157 * The header value. 158 * <br>Must be a comma-delimited list of entity validator values (e.g. <js>"\"xyzzy\", \"r2d2xxxx\", \"c3piozzzz\""</js>). 159 * <br>Can be <jk>null</jk>. 160 */ 161 public IfNoneMatch(String value) { 162 super(NAME, value); 163 } 164 165 /** 166 * Constructor. 167 * 168 * @param value 169 * The header value. 170 * <br>Can be <jk>null</jk>. 171 */ 172 public IfNoneMatch(EntityTags value) { 173 super(NAME, value); 174 } 175 176 /** 177 * Constructor with delayed value. 178 * 179 * <p> 180 * Header value is re-evaluated on each call to {@link #getValue()}. 181 * 182 * @param value 183 * The supplier of the header value. 184 * <br>Can be <jk>null</jk>. 185 */ 186 public IfNoneMatch(Supplier<EntityTags> value) { 187 super(NAME, value); 188 } 189}