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.*; 018import org.apache.juneau.http.annotation.*; 019import org.apache.juneau.internal.*; 020 021/** 022 * Represents a parsed <l>Accept-Language</l> HTTP request header. 023 * 024 * <p> 025 * List of acceptable human languages for response. 026 * 027 * <h5 class='figure'>Example</h5> 028 * <p class='bcode'> 029 * Accept-Language: en-US 030 * </p> 031 * 032 * <h5 class='topic'>RFC2616 Specification</h5> 033 * 034 * The Accept-Language request-header field is similar to Accept, but restricts the set of natural languages that are 035 * preferred as a response to the request. 036 * Language tags are defined in section 3.10. 037 * 038 * <p class='bcode'> 039 * Accept-Language = "Accept-Language" ":" 040 * 1#( language-range [ ";" "q" "=" qvalue ] ) 041 * language-range = ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) | "*" ) 042 * </p> 043 * 044 * <p> 045 * Each language-range MAY be given an associated quality value which represents an estimate of the user's preference 046 * for the languages specified by that range. 047 * The quality value defaults to "q=1". 048 * For example... 049 * <p class='bcode'> 050 * Accept-Language: da, en-gb;q=0.8, en;q=0.7 051 * </p> 052 * <p> 053 * ...would mean: "I prefer Danish, but will accept British English and other types of English." 054 * 055 * <p> 056 * A language-range matches a language-tag if it exactly equals the tag, or if it exactly equals a prefix of the tag 057 * such that the first tag character following the prefix is "-". 058 * 059 * <p> 060 * The special range "*", if present in the Accept-Language field, matches every tag not matched by any other range 061 * present in the Accept-Language field. 062 * 063 * <p> 064 * Note: This use of a prefix matching rule does not imply that language tags are assigned to languages in such a way 065 * that it is always true that if a user understands a language with a certain 066 * tag, then this user will also understand all languages with tags for which this tag is a prefix. 067 * The prefix rule simply allows the use of prefix tags if this is the case. 068 * 069 * <p> 070 * The language quality factor assigned to a language-tag by the Accept-Language field is the quality value of the 071 * longest language- range in the field that matches the language-tag. 072 * 073 * <p> 074 * If no language- range in the field matches the tag, the language quality factor assigned is 0. 075 * 076 * <p> 077 * If no Accept-Language header is present in the request, the server SHOULD assume that all languages are equally 078 * acceptable. 079 * 080 * <p> 081 * If an Accept-Language header is present, then all languages which are assigned a quality factor greater than 0 are 082 * acceptable. 083 * 084 * <p> 085 * It might be contrary to the privacy expectations of the user to send an Accept-Language header with the complete 086 * linguistic preferences of the user in every request. 087 * For a discussion of this issue, see section 15.1.4. 088 * 089 * <p> 090 * As intelligibility is highly dependent on the individual user, it is recommended that client applications make the 091 * choice of linguistic preference available to the user. 092 * If the choice is not made available, then the Accept-Language header field MUST NOT be given in the request. 093 * 094 * <p> 095 * Note: When making the choice of linguistic preference available to the user, we remind implementors of the fact that 096 * users are not familiar with the details of language matching as described above, and should provide appropriate 097 * guidance. 098 * As an example, users might assume that on selecting "en-gb", they will be served any kind of English document if 099 * British English is not available. 100 * A user agent might suggest in such a case to add "en" to get the best matching behavior. 101 * 102 * <h5 class='section'>See Also:</h5><ul> 103 * <li class='link'><a class="doclink" href="../../../../../index.html#juneau-rest-common">juneau-rest-common</a> 104 * <li class='extlink'><a class="doclink" href="https://www.w3.org/Protocols/rfc2616/rfc2616.html">Hypertext Transfer Protocol -- HTTP/1.1</a> 105 * </ul> 106 * 107 * @serial exclude 108 */ 109@Header("Accept-Language") 110public class AcceptLanguage extends BasicStringRangesHeader { 111 112 //----------------------------------------------------------------------------------------------------------------- 113 // Static 114 //----------------------------------------------------------------------------------------------------------------- 115 116 private static final long serialVersionUID = 1L; 117 private static final String NAME = "Accept-Language"; 118 119 private static final Cache<String,AcceptLanguage> CACHE = Cache.of(String.class, AcceptLanguage.class).build(); 120 121 /** 122 * Static creator. 123 * 124 * @param value 125 * The header value. 126 * <br>Must be parsable by {@link StringRanges#of(String)}. 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 AcceptLanguage of(String value) { 131 return value == null ? null : CACHE.get(value, ()->new AcceptLanguage(value)); 132 } 133 134 /** 135 * Static creator. 136 * 137 * @param value 138 * 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 AcceptLanguage of(StringRanges value) { 143 return value == null ? null : new AcceptLanguage(value); 144 } 145 146 /** 147 * Static creator with delayed value. 148 * 149 * <p> 150 * Header value is re-evaluated on each call to {@link #getValue()}. 151 * 152 * @param value 153 * The supplier of the header value. 154 * <br>Can be <jk>null</jk>. 155 * @return A new header bean, or <jk>null</jk> if the value is <jk>null</jk>. 156 */ 157 public static AcceptLanguage of(Supplier<StringRanges> value) { 158 return value == null ? null : new AcceptLanguage(value); 159 } 160 161 //----------------------------------------------------------------------------------------------------------------- 162 // Instance 163 //----------------------------------------------------------------------------------------------------------------- 164 165 /** 166 * Constructor. 167 * 168 * @param value 169 * The header value. 170 * <br>Must be parsable by {@link StringRanges#of(String)}. 171 * <br>Can be <jk>null</jk>. 172 */ 173 public AcceptLanguage(String value) { 174 super(NAME, value); 175 } 176 177 /** 178 * Constructor. 179 * 180 * @param value 181 * The header value. 182 * <br>Can be <jk>null</jk>. 183 */ 184 public AcceptLanguage(StringRanges value) { 185 super(NAME, value); 186 } 187 188 /** 189 * Constructor with delayed value. 190 * 191 * <p> 192 * Header value is re-evaluated on each call to {@link #getValue()}. 193 * 194 * @param value 195 * The supplier of the header value. 196 * <br>Can be <jk>null</jk>. 197 */ 198 public AcceptLanguage(Supplier<StringRanges> value) { 199 super(NAME, value); 200 } 201}