001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.juneau.http.classic.part; 018 019import static org.apache.juneau.commons.utils.Shorts.*; 020import static org.apache.juneau.commons.utils.StringUtils.*; 021import static org.apache.juneau.commons.utils.StringUtils.isEmpty; 022 023import java.util.*; 024import java.util.function.*; 025 026import org.apache.http.*; 027import org.apache.juneau.bct.assertions.*; 028 029/** 030 * A {@link NameValuePair} that consists of a comma-delimited list of string values. 031 * 032 * <h5 class='section'>See Also:</h5><ul> 033 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauRestCommon">juneau-rest-common</a> 034 * </ul> 035 */ 036@SuppressWarnings({ 037 "java:S2160" // equals() inherited from BasicPart compares name+value; typed field is accessed via getValue() 038}) 039public class BasicCsvArrayPart extends BasicPart { 040 private static final String[] EMPTY = {}; 041 042 /** 043 * Static creator. 044 * 045 * @param name The part name. 046 * @param value The part value. 047 * @return A new {@link BasicCsvArrayPart} object, or <jk>null</jk> if the name or value is <jk>null</jk>. 048 */ 049 public static BasicCsvArrayPart of(String name, String...value) { 050 if (isEmpty(name) || value == null) 051 return null; 052 return new BasicCsvArrayPart(name, value); 053 } 054 055 /** 056 * Static creator with delayed value. 057 * 058 * <p> 059 * Part value is re-evaluated on each call to {@link NameValuePair#getValue()}. 060 * 061 * @param name The part name. 062 * @param value The part value supplier. 063 * @return A new {@link BasicCsvArrayPart} object, or <jk>null</jk> if the name or supplier is <jk>null</jk>. 064 */ 065 public static BasicCsvArrayPart of(String name, Supplier<String[]> value) { 066 if (isEmpty(name) || value == null) 067 return null; 068 return new BasicCsvArrayPart(name, value); 069 } 070 071 private final String[] value; 072 private final Supplier<String[]> supplier; 073 private String stringValue; 074 075 /** 076 * Constructor. 077 * 078 * @param name The part name. Must not be <jk>null</jk>. 079 * @param value The part value. Can be <jk>null</jk>. 080 */ 081 public BasicCsvArrayPart(String name, String...value) { 082 super(name, value); 083 this.value = value; 084 this.supplier = null; 085 this.stringValue = null; 086 } 087 088 /** 089 * Constructor. 090 * 091 * <p> 092 * <jk>null</jk> values are treated as <jk>null</jk>. 093 * Otherwise parses as a comma-delimited list with whitespace trimmed. 094 * 095 * @param name The part name. Must not be <jk>null</jk>. 096 * @param value The part value. Can be <jk>null</jk>. 097 */ 098 public BasicCsvArrayPart(String name, String value) { 099 super(name, value); 100 this.value = splita(value); 101 this.supplier = null; 102 stringValue = value; 103 } 104 105 /** 106 * Constructor. 107 * 108 * @param name The part name. Must not be <jk>null</jk>. 109 * @param value The part value supplier. Can be <jk>null</jk> or supply <jk>null</jk>. 110 */ 111 public BasicCsvArrayPart(String name, Supplier<String[]> value) { 112 super(name, value); 113 this.value = null; 114 supplier = value; 115 this.stringValue = null; 116 } 117 118 /** 119 * Returns The part value as an array wrapped in an {@link Optional}. 120 * 121 * <p> 122 * Array is a copy of the value of this part. 123 * 124 * @return The part value as an array wrapped in an {@link Optional}. Never <jk>null</jk>. 125 */ 126 public Optional<String[]> asArray() { 127 return o(cp(value())); 128 } 129 130 /** 131 * Returns The part value as a {@link List} wrapped in an {@link Optional}. 132 * 133 * <p> 134 * The list is unmodifiable. 135 * 136 * @return The part value as a {@link List} wrapped in an {@link Optional}. Never <jk>null</jk>. 137 */ 138 public Optional<List<String>> asList() { 139 return o(toList()); 140 } 141 142 /** 143 * Provides the ability to perform fluent-style assertions on this part. 144 * 145 * @return A new fluent assertion object. 146 * @throws AssertionError If assertion failed. 147 */ 148 public FluentListAssertion<String,BasicCsvArrayPart> assertList() { 149 return new FluentListAssertion<>(u(l(value())), this); 150 } 151 152 /** 153 * Returns <jk>true</jk> if this part contains the specified value. 154 * 155 * @param val The value to check for. 156 * @return <jk>true</jk> if this part contains the specified value. 157 */ 158 public boolean contains(String val) { 159 if (nn(val)) 160 for (var v : value()) 161 if (eq(v, val)) 162 return true; 163 return false; 164 } 165 166 /** 167 * Returns <jk>true</jk> if this part contains the specified value using {@link String#equalsIgnoreCase(String)}. 168 * 169 * @param val The value to check for. 170 * @return <jk>true</jk> if this part contains the specified value. 171 */ 172 public boolean containsIgnoreCase(String val) { 173 if (nn(val)) 174 for (var v : value()) 175 if (eqic(v, val)) 176 return true; 177 return false; 178 } 179 180 @Override /* Overridden from Header */ 181 public String getValue() { 182 if (nn(supplier)) 183 return join(supplier.get(), ','); 184 if (!nn(stringValue)) 185 stringValue = join(value, ','); 186 return stringValue; 187 } 188 189 /** 190 * Return the value if present, otherwise return <c>other</c>. 191 * 192 * <p> 193 * This is a shortened form for calling <c>asArray().orElse(<jv>other</jv>)</c>. 194 * 195 * @param other The value to be returned if there is no value present, can be <jk>null</jk>. 196 * @return The value, if present, otherwise <c>other</c>. 197 */ 198 public String[] orElse(String[] other) { 199 String[] x = value(); 200 return nn(x) ? cp(x) : other; 201 } 202 203 /** 204 * Returns The part value as an array. 205 * 206 * <p> 207 * The array is a copy of the value of this part. 208 * 209 * @return The part value as an array, or <jk>null</jk> if the value <jk>null</jk>. 210 */ 211 public String[] toArray() { 212 return cp(value()); 213 } 214 215 /** 216 * Returns The part value as a {@link List}. 217 * 218 * <p> 219 * The list is unmodifiable. 220 * 221 * @return The part value as a {@link List}, or <jk>null</jk> if the value <jk>null</jk>. 222 */ 223 public List<String> toList() { 224 return u(l(value())); 225 } 226 227 private String[] value() { 228 if (nn(supplier)) { 229 String[] v = supplier.get(); 230 return nn(v) ? v : EMPTY; 231 } 232 return value; 233 } 234}