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.http.Constants.*;
016
017import java.util.function.*;
018
019import org.apache.juneau.http.*;
020import org.apache.juneau.http.annotation.*;
021import org.apache.juneau.internal.*;
022
023
024/**
025 * Represents a parsed <l>Accept-Charset</l> HTTP request header.
026 *
027 * <p>
028 * Character sets that are acceptable.
029 *
030 * <h5 class='figure'>Example</h5>
031 * <p class='bcode w800'>
032 *    Accept-Charset: utf-8
033 * </p>
034 *
035 * <h5 class='topic'>RFC2616 Specification</h5>
036 *
037 * The Accept-Charset request-header field can be used to indicate what character sets are acceptable for the response.
038 *
039 * <p>
040 * This field allows clients capable of understanding more comprehensive or special- purpose character sets to signal
041 * that capability to a server which is capable of representing documents in those character sets.
042 * <p class='bcode w800'>
043 *    Accept-Charset = "Accept-Charset" ":"
044 *                     1#( ( charset | "*" )[ ";" "q" "=" qvalue ] )
045 * </p>
046 *
047 * <p>
048 * Character set values are described in section 3.4. Each charset MAY be given an associated quality value which
049 * represents the user's preference for that charset.
050 * The default value is q=1.
051 * An example is...
052 * <p class='bcode w800'>
053 *    Accept-Charset: iso-8859-5, unicode-1-1;q=0.8
054 * </p>
055 *
056 * <p>
057 * The special value "*", if present in the Accept-Charset field, matches every character set (including ISO-8859-1)
058 * which is not mentioned elsewhere in the Accept-Charset field.
059 *
060 * <p>
061 * If no "*" is present in an Accept-Charset field, then all character sets not explicitly mentioned get a quality
062 * value of 0, except for ISO-8859-1, which gets a quality value of 1 if not explicitly mentioned.
063 *
064 * <p>
065 * If no Accept-Charset header is present, the default is that any character set is acceptable.
066 *
067 * <p>
068 * If an Accept-Charset header is present, and if the server cannot send a response which is acceptable according to
069 * the Accept-Charset header, then the server SHOULD send an error response with the 406 (not acceptable) status code,
070 * though the sending of an unacceptable response is also allowed.
071 *
072 * <ul class='seealso'>
073 *    <li class='extlink'>{@doc ExtRFC2616}
074 * </ul>
075 */
076@Header("Accept-Charset")
077public class AcceptCharset extends BasicStringRangeArrayHeader {
078
079   private static final long serialVersionUID = 1L;
080
081   private static final Cache<String,AcceptCharset> CACHE = new Cache<>(NOCACHE, CACHE_MAX_SIZE);
082
083   /**
084    * Returns a parsed and cached header.
085    *
086    * @param value
087    *    The header value.
088    * @return A cached {@link AcceptCharset} object.
089    */
090   public static AcceptCharset of(String value) {
091      if (value == null)
092         return null;
093      AcceptCharset x = CACHE.get(value);
094      if (x == null)
095         x = CACHE.put(value, new AcceptCharset(value));
096      return x;
097   }
098
099   /**
100    * Convenience creator.
101    *
102    * @param value
103    *    The header value.
104    *    <br>Can be any of the following:
105    *    <ul>
106    *       <li>{@link String} - Converted using {@link StringRanges#of(String)}.
107    *       <li><c>StringRange[]</c> - Left as-is.
108    *       <li>Anything else - Converted to <c>String</c> then parsed.
109    *    </ul>
110    * @return A new {@link AcceptCharset} object.
111    */
112   public static AcceptCharset of(Object value) {
113      if (value == null)
114         return null;
115      return new AcceptCharset(value);
116   }
117
118   /**
119    * Convenience creator using supplier.
120    *
121    * <p>
122    * Header value is re-evaluated on each call to {@link #getValue()}.
123    *
124    * @param value
125    *    The header value supplier.
126    *    <br>Can be any of the following:
127    *    <ul>
128    *       <li>{@link String} - Converted using {@link StringRanges#of(String)}.
129    *       <li><c>StringRange[]</c> - Left as-is.
130    *       <li>Anything else - Converted to <c>String</c> then parsed.
131    *    </ul>
132    * @return A new {@link AcceptCharset} object.
133    */
134   public static AcceptCharset of(Supplier<?> value) {
135      if (value == null)
136         return null;
137      return new AcceptCharset(value);
138   }
139
140   /**
141    * Constructor
142    *
143    * @param value
144    *    The header value.
145    *    <br>Can be any of the following:
146    *    <ul>
147    *       <li>{@link String} - Converted using {@link StringRanges#of(String)}.
148    *       <li><c>StringRange[]</c> - Left as-is.
149    *       <li>Anything else - Converted to <c>String</c> then parsed.
150    *       <li>A {@link Supplier} of anything on this list.
151    *    </ul>
152    */
153   public AcceptCharset(Object value) {
154      super("Accept-Charset", value);
155   }
156
157   /**
158    * Constructor
159    *
160    * @param value
161    *    The header value.
162    */
163   public AcceptCharset(String value) {
164      this((Object)value);
165   }
166}