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.classic.header; 018 019import java.util.function.*; 020 021import org.apache.juneau.http.*; 022import org.apache.juneau.http.header.*; 023 024/** 025 * Represents a parsed <l>If-Match</l> HTTP request header. 026 * 027 * <p> 028 * Only perform the action if the client supplied entity matches the same entity on the server. 029 * This is mainly for methods like PUT to only update a resource if it has not been modified since the user last 030 * updated it. 031 * 032 * <h5 class='figure'>Example</h5> 033 * <p class='bcode'> 034 * If-Match: "737060cd8c284d8af7ad3082f209582d" 035 * </p> 036 * 037 * <h5 class='topic'>RFC2616 Specification</h5> 038 * 039 * The If-Match request-header field is used with a method to make it conditional. 040 * A client that has one or more entities previously obtained from the resource can verify that one of those entities 041 * is current by including a list of their associated entity tags in the If-Match header field. 042 * Entity tags are defined in section 3.11. 043 * The purpose of this feature is to allow efficient updates of cached information with a minimum amount of transaction 044 * overhead. 045 * It is also used, on updating requests, to prevent inadvertent modification of the wrong version of a resource. 046 * As a special case, the value "*" matches any current entity of the resource. 047 * 048 * <p class='bcode'> 049 * If-Match = "If-Match" ":" ( "*" | 1#entity-tag ) 050 * </p> 051 * 052 * <p> 053 * If any of the entity tags match the entity tag of the entity that would have been returned in the response to a 054 * similar GET request (without the If-Match header) on that resource, or if "*" is given and any current entity exists 055 * for that resource, then the server MAY perform the requested method as if the If-Match header field did not exist. 056 * 057 * <p> 058 * A server MUST use the strong comparison function (see section 13.3.3) to compare the entity tags in If-Match. 059 * 060 * <p> 061 * If none of the entity tags match, or if "*" is given and no current entity exists, the server MUST NOT perform the 062 * requested method, and MUST return a 412 (Precondition Failed) response. 063 * This behavior is most useful when the client wants to prevent an updating method, such as PUT, from modifying a 064 * resource that has changed since the client last retrieved it. 065 * 066 * <p> 067 * If the request would, without the If-Match header field, result in anything other than a 2xx or 412 status, then the 068 * If-Match header MUST be ignored. 069 * 070 * <p> 071 * The meaning of "If-Match: *" is that the method SHOULD be performed if the representation selected by the origin 072 * server (or by a cache, possibly using the Vary mechanism, see section 14.44) exists, and MUST NOT be performed if the 073 * representation does not exist. 074 * 075 * <p> 076 * A request intended to update a resource (e.g., a PUT) MAY include an If-Match header field to signal that the request 077 * method MUST NOT be applied if the entity corresponding to the If-Match value (a single entity tag) is no longer a 078 * representation of that resource. 079 * This allows the user to indicate that they do not wish the request to be successful if the resource has been changed 080 * without their knowledge. 081 * 082 * <p> 083 * Examples: 084 * <p class='bcode'> 085 * If-Match: "xyzzy" 086 * If-Match: "xyzzy", "r2d2xxxx", "c3piozzzz" 087 * If-Match: * 088 * </p> 089 * 090 * <p> 091 * The result of a request having both an If-Match header field and either an If-None-Match or an If-Modified-Since 092 * header fields is undefined by this specification. 093 * 094 * <h5 class='section'>See Also:</h5><ul> 095 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauRestCommon">juneau-rest-common</a> 096 * <li class='extlink'><a class="doclink" href="https://www.w3.org/Protocols/rfc2616/rfc2616.html">Hypertext Transfer Protocol -- HTTP/1.1</a> 097 * </ul> 098 * 099 * @serial exclude 100 */ 101@Header("If-Match") 102public class IfMatch extends BasicEntityTagsHeader { 103 private static final long serialVersionUID = 1L; 104 private static final String NAME = "If-Match"; 105 106 /** 107 * Static creator. 108 * 109 * @param value 110 * The header value. 111 * <br>Can be <jk>null</jk>. 112 * @return A new header bean, or <jk>null</jk> if the value is <jk>null</jk>. 113 */ 114 public static IfMatch of(EntityTags value) { 115 return value == null ? null : new IfMatch(value); 116 } 117 118 /** 119 * Static creator. 120 * 121 * @param value 122 * The header value. 123 * <br>Must be a comma-delimited list of entity validator values (e.g. <js>"\"xyzzy\", \"r2d2xxxx\", \"c3piozzzz\""</js>). 124 * <br>Can be <jk>null</jk>. 125 * @return A new header bean, or <jk>null</jk> if the value is <jk>null</jk>. 126 */ 127 public static IfMatch of(String value) { 128 return value == null ? null : new IfMatch(value); 129 } 130 131 /** 132 * Static creator with delayed value. 133 * 134 * <p> 135 * Header value is re-evaluated on each call to {@link #getValue()}. 136 * 137 * @param value 138 * The supplier of the header value. 139 * <br>Can be <jk>null</jk>. 140 * @return A new header bean, or <jk>null</jk> if the value is <jk>null</jk>. 141 */ 142 public static IfMatch of(Supplier<EntityTags> value) { 143 return value == null ? null : new IfMatch(value); 144 } 145 146 /** 147 * Constructor. 148 * 149 * @param value 150 * The header value. 151 * <br>Can be <jk>null</jk> to create a header with no value. 152 */ 153 public IfMatch(EntityTags value) { 154 super(NAME, value); 155 } 156 157 /** 158 * Constructor. 159 * 160 * @param value 161 * The header value. 162 * <br>Must be a comma-delimited list of entity validator values (e.g. <js>"\"xyzzy\", \"r2d2xxxx\", \"c3piozzzz\""</js>). 163 * <br>Can be <jk>null</jk> to create a header with no value. 164 */ 165 public IfMatch(String value) { 166 super(NAME, value); 167 } 168 169 /** 170 * Constructor with delayed value. 171 * 172 * <p> 173 * Header value is re-evaluated on each call to {@link #getValue()}. 174 * 175 * @param value 176 * The supplier of the header value. 177 * <br>Can be <jk>null</jk> to create a header with no value. 178 */ 179 public IfMatch(Supplier<EntityTags> value) { 180 super(NAME, value); 181 } 182}