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.internal; 014 015import static org.apache.juneau.internal.StringUtils.*; 016 017import java.lang.reflect.*; 018import java.util.*; 019 020import org.apache.juneau.*; 021import org.apache.juneau.parser.*; 022 023/** 024 * Utility methods when working with setting of bean properties. 025 */ 026public final class BeanPropertyUtils { 027 028 /** 029 * Converts a value to a String. 030 * 031 * @param o The value to convert. 032 * @return The converted value, or <jk>null</jk> if the input was null. 033 */ 034 public static String toStringVal(Object o) { 035 return StringUtils.asString(o); 036 } 037 038 /** 039 * Converts a value to a Boolean. 040 * 041 * @param o The value to convert. 042 * @return The converted value, or <jk>null</jk> if the input was null. 043 */ 044 public static Boolean toBoolean(Object o) { 045 return ObjectUtils.toBoolean(o); 046 } 047 048 /** 049 * Converts a value to a Number. 050 * 051 * @param o The value to convert. 052 * @return The converted value, or <jk>null</jk> if the input was null. 053 */ 054 public static Number toNumber(Object o) { 055 return ObjectUtils.toNumber(o); 056 } 057 058 /** 059 * Converts a value to an Integer. 060 * 061 * @param o The value to convert. 062 * @return The converted value, or <jk>null</jk> if the input was null. 063 */ 064 public static Integer toInteger(Object o) { 065 return ObjectUtils.toInteger(o); 066 } 067 068 /** 069 * Converts a value to a URI. 070 * 071 * @param o The value to convert. 072 * @return The converted value, or <jk>null</jk> if the input was null. 073 */ 074 public static java.net.URI toURI(Object o) { 075 return StringUtils.toURI(o); 076 } 077 078 /** 079 * Adds a set of values to an existing list. 080 * 081 * @param appendTo 082 * The list to append to. 083 * <br>If <jk>null</jk>, a new {@link ArrayList} will be created. 084 * @param values The values to add. 085 * @param type The data type of the elements. 086 * @param args The generic type arguments of the data type. 087 * @return The converted value, or <jk>null</jk> if the input was null. 088 */ 089 public static <T> List<T> addToList(List<T> appendTo, Object[] values, Class<T> type, Type...args) { 090 if (values == null) 091 return appendTo; 092 try { 093 List<T> l = appendTo; 094 if (appendTo == null) 095 l = new ArrayList<>(); 096 for (Object o : values) { 097 if (o != null) { 098 if (isObjectList(o, false)) { 099 for (Object o2 : new ObjectList(o.toString())) 100 l.add(toType(o2, type, args)); 101 } else if (o instanceof Collection) { 102 for (Object o2 : (Collection<?>)o) 103 l.add(toType(o2, type, args)); 104 } else if (o.getClass().isArray()) { 105 for (int i = 0; i < Array.getLength(o); i++) 106 l.add(toType(Array.get(o, i), type, args)); 107 } else { 108 l.add(toType(o, type, args)); 109 } 110 } 111 } 112 return l.isEmpty() ? null : l; 113 } catch (ParseException e) { 114 throw new RuntimeException(e); 115 } 116 } 117 118 /** 119 * Adds a set of values to an existing map. 120 * 121 * @param appendTo 122 * The map to append to. 123 * <br>If <jk>null</jk>, a new {@link LinkedHashMap} will be created. 124 * @param values The values to add. 125 * @param keyType The data type of the keys. 126 * @param valueType The data type of the values. 127 * @param valueTypeArgs The generic type arguments of the data type of the values. 128 * @return The converted value, or <jk>null</jk> if the input was null. 129 */ 130 @SuppressWarnings("unchecked") 131 public static <K,V> Map<K,V> addToMap(Map<K,V> appendTo, Object[] values, Class<K> keyType, Class<V> valueType, Type...valueTypeArgs) { 132 if (values == null) 133 return appendTo; 134 try { 135 Map<K,V> m = appendTo; 136 if (m == null) 137 m = new LinkedHashMap<>(); 138 for (Object o : values) { 139 if (o != null) { 140 if (isObjectMap(o, false)) { 141 for (Map.Entry<String,Object> e : new ObjectMap(o.toString()).entrySet()) 142 m.put(toType(e.getKey(), keyType), toType(e.getValue(), valueType, valueTypeArgs)); 143 } else if (o instanceof Map) { 144 for (Map.Entry<Object,Object> e : ((Map<Object,Object>)o).entrySet()) 145 m.put(toType(e.getKey(), keyType), toType(e.getValue(), valueType, valueTypeArgs)); 146 } else { 147 throw new FormattedRuntimeException("Invalid object type {0} passed to addToMap()", o.getClass().getName()); 148 } 149 } 150 } 151 return m.isEmpty() ? null : m; 152 } catch (ParseException e) { 153 throw new RuntimeException(e); 154 } 155 } 156 157 /** 158 * Converts an object to the specified type. 159 * 160 * @param o The object to convert. 161 * @param type The type to covert to. 162 * @param args The type arguments for types of map or collection. 163 * @return The converted object. 164 */ 165 public static <T> T toType(Object o, Class<T> type, Type...args) { 166 return ObjectUtils.toType(o, type, args); 167 } 168 169 /** 170 * Creates a new list from the specified collection. 171 * 172 * @param val The value to copy from. 173 * @return A new {@link ArrayList}, or <jk>null</jk> if the input was null. 174 */ 175 public static <T> List<T> newList(Collection<T> val) { 176 if (val == null) 177 return null; 178 return new ArrayList<>(val); 179 } 180 181 /** 182 * Copies the specified values into an existing list. 183 * 184 * @param l 185 * The list to add to. 186 * <br>If <jk>null</jk>, a new {@link ArrayList} will be created. 187 * @param val The values to add. 188 * @return The list with values copied into it. 189 */ 190 public static <T> List<T> addToList(List<T> l, Collection<T> val) { 191 if (val != null) { 192 if (l == null) 193 l = new ArrayList<>(val); 194 else 195 l.addAll(val); 196 } 197 return l; 198 } 199 200 /** 201 * Creates a new map from the specified map. 202 * 203 * @param val The value to copy from. 204 * @return A new {@link LinkedHashMap}, or <jk>null</jk> if the input was null. 205 */ 206 public static <K,V> Map<K,V> newMap(Map<K,V> val) { 207 if (val == null) 208 return null; 209 return new LinkedHashMap<>(val); 210 } 211 212 /** 213 * Copies the specified values into an existing map. 214 * 215 * @param m 216 * The map to add to. 217 * <br>If <jk>null</jk>, a new {@link LinkedHashMap} will be created. 218 * @param val The values to add. 219 * @return The list with values copied into it. 220 */ 221 public static <K,V> Map<K,V> addToMap(Map<K,V> m, Map<K,V> val) { 222 if (val != null) { 223 if (m == null) 224 m = new LinkedHashMap<>(val); 225 else 226 m.putAll(val); 227 } 228 return m; 229 } 230 231 /** 232 * Adds a single entry into an existing map. 233 * 234 * @param m 235 * The map to add to. 236 * <br>If <jk>null</jk>, a new {@link LinkedHashMap} will be created. 237 * @param key The entry key. 238 * @param value The entry value. 239 * @return The list with values copied into it. 240 */ 241 public static <K,V> Map<K,V> addToMap(Map<K,V> m, K key, V value) { 242 if (m == null) 243 m = new LinkedHashMap<>(); 244 m.put(key, value); 245 return m; 246 } 247 248 /** 249 * Creates a new map from the specified map. 250 * 251 * @param val The value to copy from. 252 * @param comparator The key comparator to use, or <jk>null</jk> to use natural ordering. 253 * @return A new {@link LinkedHashMap}, or <jk>null</jk> if the input was null. 254 */ 255 public static <K,V> Map<K,V> newSortedMap(Map<K,V> val, Comparator<K> comparator) { 256 if (val == null) 257 return null; 258 Map<K,V> m = new TreeMap<>(comparator); 259 m.putAll(val); 260 return m; 261 } 262 263 /** 264 * Copies the specified values into an existing map. 265 * 266 * @param m 267 * The map to add to. 268 * <br>If <jk>null</jk>, a new {@link LinkedHashMap} will be created. 269 * @param val The values to add. 270 * @param comparator The key comparator to use, or <jk>null</jk> to use natural ordering. 271 * @return The list with values copied into it. 272 */ 273 public static <K,V> Map<K,V> addToSortedMap(Map<K,V> m, Map<K,V> val, Comparator<K> comparator) { 274 if (val != null) { 275 if (m == null) { 276 m = new TreeMap<>(comparator); 277 m.putAll(val); 278 } else { 279 m.putAll(val); 280 } 281 } 282 return m; 283 } 284 285 /** 286 * Adds a single entry into an existing map. 287 * 288 * @param m 289 * The map to add to. 290 * <br>If <jk>null</jk>, a new {@link LinkedHashMap} will be created. 291 * @param key The entry key. 292 * @param value The entry value. 293 * @param comparator The key comparator to use, or <jk>null</jk> to use natural ordering. 294 * @return The list with values copied into it. 295 */ 296 public static <K,V> Map<K,V> addToSortedMap(Map<K,V> m, K key, V value, Comparator<K> comparator) { 297 if (m == null) 298 m = new TreeMap<>(comparator); 299 m.put(key, value); 300 return m; 301 } 302}