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.part; 014 015import static org.apache.juneau.common.internal.StringUtils.*; 016import static org.apache.juneau.internal.ArrayUtils.copyOf; 017import static org.apache.juneau.internal.CollectionUtils.*; 018 019import java.util.*; 020import java.util.function.*; 021 022import org.apache.http.*; 023import org.apache.juneau.assertions.*; 024 025/** 026 * A {@link NameValuePair} that consists of a comma-delimited list of string values. 027 * 028 * <h5 class='section'>See Also:</h5><ul> 029 * <li class='link'><a class="doclink" href="../../../../../index.html#juneau-rest-common">juneau-rest-common</a> 030 * </ul> 031 */ 032public class BasicCsvArrayPart extends BasicPart { 033 034 //----------------------------------------------------------------------------------------------------------------- 035 // Static 036 //----------------------------------------------------------------------------------------------------------------- 037 038 private static final String[] EMPTY = new String[0]; 039 040 /** 041 * Static creator. 042 * 043 * @param name The part name. 044 * @param value The part value. 045 * @return A new {@link BasicCsvArrayPart} object, or <jk>null</jk> if the name or value is <jk>null</jk>. 046 */ 047 public static BasicCsvArrayPart of(String name, String...value) { 048 if (isEmpty(name) || value == null) 049 return null; 050 return new BasicCsvArrayPart(name, value); 051 } 052 053 /** 054 * Static creator with delayed value. 055 * 056 * <p> 057 * Part value is re-evaluated on each call to {@link NameValuePair#getValue()}. 058 * 059 * @param name The part name. 060 * @param value The part value supplier. 061 * @return A new {@link BasicCsvArrayPart} object, or <jk>null</jk> if the name or supplier is <jk>null</jk>. 062 */ 063 public static BasicCsvArrayPart of(String name, Supplier<String[]> value) { 064 if (isEmpty(name) || value == null) 065 return null; 066 return new BasicCsvArrayPart(name, value); 067 } 068 069 //----------------------------------------------------------------------------------------------------------------- 070 // Instance 071 //----------------------------------------------------------------------------------------------------------------- 072 073 private final String[] value; 074 private final Supplier<String[]> supplier; 075 private String stringValue; 076 077 /** 078 * Constructor. 079 * 080 * @param name The part name. Must not be <jk>null</jk>. 081 * @param value The part value. Can be <jk>null</jk>. 082 */ 083 public BasicCsvArrayPart(String name, String...value) { 084 super(name, value); 085 this.value = value; 086 this.supplier = null; 087 this.stringValue = null; 088 } 089 090 /** 091 * Constructor. 092 * 093 * @param name The part name. Must not be <jk>null</jk>. 094 * @param value The part value supplier. Can be <jk>null</jk> or supply <jk>null</jk>. 095 */ 096 public BasicCsvArrayPart(String name, Supplier<String[]> value) { 097 super(name, value); 098 this.value = null; 099 this.supplier = value; 100 this.stringValue = null; 101 } 102 103 /** 104 * Constructor. 105 * 106 * <p> 107 * <jk>null</jk> values are treated as <jk>null</jk>. 108 * Otherwise parses as a comma-delimited list with whitespace trimmed. 109 * 110 * @param name The part name. Must not be <jk>null</jk>. 111 * @param value The part value. Can be <jk>null</jk>. 112 */ 113 public BasicCsvArrayPart(String name, String value) { 114 super(name, value); 115 this.value = split(value); 116 this.supplier = null; 117 this.stringValue = value; 118 } 119 120 @Override /* Header */ 121 public String getValue() { 122 if (supplier != null) 123 return join(supplier.get(), ','); 124 if (stringValue != null) 125 stringValue = join(value, ','); 126 return stringValue; 127 } 128 129 /** 130 * Returns <jk>true</jk> if this part contains the specified value. 131 * 132 * @param val The value to check for. 133 * @return <jk>true</jk> if this part contains the specified value. 134 */ 135 public boolean contains(String val) { 136 if (val != null) 137 for (String v : value()) 138 if (eq(v, val)) 139 return true; 140 return false; 141 } 142 143 /** 144 * Returns <jk>true</jk> if this part contains the specified value using {@link String#equalsIgnoreCase(String)}. 145 * 146 * @param val The value to check for. 147 * @return <jk>true</jk> if this part contains the specified value. 148 */ 149 public boolean containsIgnoreCase(String val) { 150 if (val != null) 151 for (String v : value()) 152 if (eqic(v, val)) 153 return true; 154 return false; 155 } 156 157 /** 158 * Provides the ability to perform fluent-style assertions on this part. 159 * 160 * @return A new fluent assertion object. 161 * @throws AssertionError If assertion failed. 162 */ 163 public FluentListAssertion<String,BasicCsvArrayPart> assertList() { 164 return new FluentListAssertion<>(ulist(value()), this); 165 } 166 167 /** 168 * Returns The part value as a {@link List}. 169 * 170 * <p> 171 * The list is unmodifiable. 172 * 173 * @return The part value as a {@link List}, or <jk>null</jk> if the value <jk>null</jk>. 174 */ 175 public List<String> toList() { 176 return ulist(value()); 177 } 178 179 /** 180 * Returns The part value as a {@link List} wrapped in an {@link Optional}. 181 * 182 * <p> 183 * The list is unmodifiable. 184 * 185 * @return The part value as a {@link List} wrapped in an {@link Optional}. Never <jk>null</jk>. 186 */ 187 public Optional<List<String>> asList() { 188 return optional(toList()); 189 } 190 191 /** 192 * Returns The part value as an array. 193 * 194 * <p> 195 * The array is a copy of the value of this part. 196 * 197 * @return The part value as an array, or <jk>null</jk> if the value <jk>null</jk>. 198 */ 199 public String[] toArray() { 200 return copyOf(value()); 201 } 202 203 /** 204 * Returns The part value as an array wrapped in an {@link Optional}. 205 * 206 * <p> 207 * Array is a copy of the value of this part. 208 * 209 * @return The part value as an array wrapped in an {@link Optional}. Never <jk>null</jk>. 210 */ 211 public Optional<String[]> asArray() { 212 return optional(copyOf(value())); 213 } 214 215 /** 216 * Return the value if present, otherwise return <c>other</c>. 217 * 218 * <p> 219 * This is a shortened form for calling <c>asArray().orElse(<jv>other</jv>)</c>. 220 * 221 * @param other The value to be returned if there is no value present, can be <jk>null</jk>. 222 * @return The value, if present, otherwise <c>other</c>. 223 */ 224 public String[] orElse(String[] other) { 225 String[] x = value(); 226 return x != null ? x : other; 227 } 228 229 private String[] value() { 230 if (supplier != null) { 231 String[] v = supplier.get(); 232 return v != null ? v : EMPTY; 233 } 234 return value; 235 } 236}