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.internal.StringUtils.*; 016 017import java.util.*; 018import java.util.function.*; 019 020import org.apache.juneau.http.*; 021 022/** 023 * Category of headers that consist of simple comma-delimited lists of strings with q-values. 024 * 025 * <p> 026 * <h5 class='figure'>Example</h5> 027 * <p class='bcode w800'> 028 * Accept-Encoding: compress;q=0.5, gzip;q=1.0 029 * </p> 030 * 031 * <ul class='seealso'> 032 * <li class='extlink'>{@doc ExtRFC2616} 033 * </ul> 034 */ 035public class BasicStringRangeArrayHeader extends BasicHeader { 036 037 private static final long serialVersionUID = 1L; 038 039 /** 040 * Convenience creator. 041 * 042 * @param value 043 * The parameter value. 044 * <br>Can be any of the following: 045 * <ul> 046 * <li>{@link String} - Converted using {@link StringRanges#of(String)}. 047 * <li>{@link StringRanges} - Left as-is. 048 * <li>Anything else - Converted to <c>String</c> then parsed. 049 * </ul> 050 * @return A new {@link BasicLongHeader} object. 051 */ 052 public static BasicStringRangeArrayHeader of(String name, Object value) { 053 if (isEmpty(name) || value == null) 054 return null; 055 return new BasicStringRangeArrayHeader(name, value); 056 } 057 058 /** 059 * Convenience creator using supplier. 060 * 061 * <p> 062 * Header value is re-evaluated on each call to {@link #getValue()}. 063 * 064 * @param value 065 * The parameter value supplier. 066 * <br>Can be any of the following: 067 * <ul> 068 * <li>{@link String} - Converted using {@link StringRanges#of(String)}. 069 * <li>{@link StringRanges} - Left as-is. 070 * <li>Anything else - Converted to <c>String</c> then parsed. 071 * </ul> 072 * @return A new {@link BasicLongHeader} object. 073 */ 074 public static BasicStringRangeArrayHeader of(String name, Supplier<?> value) { 075 if (isEmpty(name) || value == null) 076 return null; 077 return new BasicStringRangeArrayHeader(name, value); 078 } 079 080 private StringRanges parsed; 081 082 /** 083 * Constructor. 084 * 085 * @param name The parameter name. 086 * @param value 087 * The parameter value. 088 * <br>Can be any of the following: 089 * <ul> 090 * <li>{@link String} - Converted using {@link StringRanges#of(String)}. 091 * <li>Anything else - Converted to <c>String</c> then parsed. 092 * <li>A {@link Supplier} of anything on this list. 093 * </ul> 094 */ 095 public BasicStringRangeArrayHeader(String name, Object value) { 096 super(name, value); 097 if (! isSupplier(value)) 098 parsed = parse(); 099 } 100 101 @Override /* Header */ 102 public String getValue() { 103 Object o = getRawValue(); 104 if (o == null) 105 return null; 106 return stringify(asRanges()); 107 } 108 109 /** 110 * Returns the list of the types ranges that make up this header. 111 * 112 * <p> 113 * The types ranges in the list are sorted by their q-value in descending order. 114 * 115 * @return An unmodifiable list of type ranges. 116 */ 117 public StringRanges asRanges() { 118 return parse(); 119 } 120 121 /** 122 * Given a list of media types, returns the best match for this string range header. 123 * 124 * <p> 125 * Note that fuzzy matching is allowed on the media types where the string range header may 126 * contain additional subtype parts. 127 * <br>For example, given identical q-values and an string range value of <js>"text/json+activity"</js>, 128 * the media type <js>"text/json"</js> will match if <js>"text/json+activity"</js> or <js>"text/activity+json"</js> 129 * isn't found. 130 * <br>The purpose for this is to allow serializers to match when artifacts such as <c>id</c> properties are 131 * present in the header. 132 * 133 * <p> 134 * See {@doc https://www.w3.org/TR/activitypub/#retrieving-objects ActivityPub / Retrieving Objects} 135 * 136 * @param names The names to match against. 137 * @return The index into the array of the best match, or <c>-1</c> if no suitable matches could be found. 138 */ 139 public int match(List<String> names) { 140 return asRanges().match(names); 141 } 142 143 /** 144 * Returns the {@link MediaRange} at the specified index. 145 * 146 * @param index The index position of the media range. 147 * @return The {@link MediaRange} at the specified index or <jk>null</jk> if the index is out of range. 148 */ 149 public StringRange getRange(int index) { 150 return asRanges().getRange(index); 151 } 152 153 /** 154 * Returns the string ranges that make up this object. 155 * 156 * @return The string ranges that make up this object. 157 */ 158 public List<StringRange> getRanges() { 159 return asRanges().getRanges(); 160 } 161 162 private StringRanges parse() { 163 if (parsed != null) 164 return parsed; 165 Object o = getRawValue(); 166 if (o == null) 167 o = ""; 168 return StringRanges.of(o.toString()); 169 } 170}