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 static org.apache.juneau.common.internal.StringUtils.*;
016import static org.apache.juneau.internal.CollectionUtils.*;
017
018import java.util.*;
019import java.util.function.*;
020
021/**
022 * Category of headers that consist of a comma-delimited list of entity validator values.
023 *
024 * <p>
025 * <h5 class='figure'>Example</h5>
026 * <p class='bcode'>
027 *    If-Match: "xyzzy"
028 *    If-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"
029 *    If-Match: *
030 * </p>
031 *
032 * <h5 class='section'>See Also:</h5><ul>
033 *    <li class='link'><a class="doclink" href="../../../../../index.html#juneau-rest-common">juneau-rest-common</a>
034 *    <li class='extlink'><a class="doclink" href="https://www.w3.org/Protocols/rfc2616/rfc2616.html">Hypertext Transfer Protocol -- HTTP/1.1</a>
035 * </ul>
036 *
037 * @serial exclude
038 */
039public class BasicEntityTagsHeader extends BasicHeader {
040
041   //-----------------------------------------------------------------------------------------------------------------
042   // Static
043   //-----------------------------------------------------------------------------------------------------------------
044
045   private static final long serialVersionUID = 1L;
046
047   /**
048    * Static creator.
049    *
050    * @param name The header name.
051    * @param value
052    *    The header value.
053    *    <br>Must be a comma-delimited list of entity validator values (e.g. <js>"\"xyzzy\", \"r2d2xxxx\", \"c3piozzzz\""</js>).
054    *    <br>Can be <jk>null</jk>.
055    * @return A new header bean, or <jk>null</jk> if the value is <jk>null</jk>.
056    * @throws IllegalArgumentException If name is <jk>null</jk> or empty.
057    */
058   public static BasicEntityTagsHeader of(String name, String value) {
059      return value == null ? null : new BasicEntityTagsHeader(name, value);
060   }
061
062   /**
063    * Static creator.
064    *
065    * @param name The header name.
066    * @param value
067    *    The header value.
068    *    <br>Can be <jk>null</jk>.
069    * @return A new header bean, or <jk>null</jk> if the value is <jk>null</jk>.
070    * @throws IllegalArgumentException If name is <jk>null</jk> or empty.
071    */
072   public static BasicEntityTagsHeader of(String name, EntityTags value) {
073      return value == null ? null : new BasicEntityTagsHeader(name, value);
074   }
075
076   /**
077    * Static creator with delayed value.
078    *
079    * <p>
080    * Header value is re-evaluated on each call to {@link #getValue()}.
081    *
082    * @param name The header name.
083    * @param value
084    *    The supplier of the header value.
085    *    <br>Can be <jk>null</jk>.
086    * @return A new header bean, or <jk>null</jk> if the value is <jk>null</jk>.
087    * @throws IllegalArgumentException If name is <jk>null</jk> or empty.
088    */
089   public static BasicEntityTagsHeader of(String name, Supplier<EntityTags> value) {
090      return value == null ? null : new BasicEntityTagsHeader(name, value);
091   }
092
093   //-----------------------------------------------------------------------------------------------------------------
094   // Instance
095   //-----------------------------------------------------------------------------------------------------------------
096
097   private final EntityTags value;
098   private final Supplier<EntityTags> supplier;
099
100   /**
101    * Constructor.
102    *
103    * @param name The header name.
104    * @param value
105    *    The header value.
106    *    <br>Must be a comma-delimited list of entity validator values (e.g. <js>"\"xyzzy\", \"r2d2xxxx\", \"c3piozzzz\""</js>).
107    *    <br>Can be <jk>null</jk>.
108    * @throws IllegalArgumentException If name is <jk>null</jk> or empty.
109    */
110   public BasicEntityTagsHeader(String name, String value) {
111      super(name, value);
112      this.value = EntityTags.of(value);
113      this.supplier = null;
114   }
115
116   /**
117    * Constructor.
118    *
119    * @param name The header name.
120    * @param value
121    *    The header value.
122    *    <br>Can be <jk>null</jk>.
123    * @throws IllegalArgumentException If name is <jk>null</jk> or empty.
124    */
125   public BasicEntityTagsHeader(String name, EntityTags value) {
126      super(name, value);
127      this.value = value;
128      this.supplier = null;
129   }
130
131   /**
132    * Constructor with delayed value.
133    *
134    * <p>
135    * Header value is re-evaluated on each call to {@link #getValue()}.
136    *
137    * @param name The header name.
138    * @param value
139    *    The supplier of the header value.
140    *    <br>Can be <jk>null</jk>.
141    * @throws IllegalArgumentException If name is <jk>null</jk> or empty.
142    */
143   public BasicEntityTagsHeader(String name, Supplier<EntityTags> value) {
144      super(name, null);
145      this.value = null;
146      this.supplier = value;
147   }
148
149   @Override /* Header */
150   public String getValue() {
151      return stringify(value());
152   }
153
154   /**
155    * Returns the header value as an {@link EntityTags} wrapped in an {@link Optional}.
156    *
157    * @return The header value as an {@link EntityTags} wrapped in an {@link Optional}.  Never <jk>null</jk>.
158    */
159   public Optional<EntityTags> asEntityTags() {
160      return optional(value());
161   }
162
163   /**
164    * Returns the header value as an {@link EntityTags} wrapped in an {@link Optional}.
165    *
166    * @return The header value as an {@link EntityTags} wrapped in an {@link Optional}.  Never <jk>null</jk>.
167    */
168   public EntityTags toEntityTags() {
169      return value();
170   }
171
172   /**
173    * Return the value if present, otherwise return <c>other</c>.
174    *
175    * <p>
176    * This is a shortened form for calling <c>asEntityTags().orElse(<jv>other</jv>)</c>.
177    *
178    * @param other The value to be returned if there is no value present, can be <jk>null</jk>.
179    * @return The value, if present, otherwise <c>other</c>.
180    */
181   public EntityTags orElse(EntityTags other) {
182      EntityTags x = value();
183      return x != null ? x : other;
184   }
185
186   private EntityTags value() {
187      if (supplier != null)
188         return supplier.get();
189      return value;
190   }
191}