001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.eclipse.aether.util; 020 021import java.util.ArrayList; 022import java.util.Arrays; 023import java.util.Collection; 024import java.util.Collections; 025import java.util.List; 026import java.util.Map; 027 028import org.eclipse.aether.RepositorySystemSession; 029 030import static java.util.stream.Collectors.toList; 031 032/** 033 * A utility class to read configuration properties from a repository system session. 034 * 035 * @see RepositorySystemSession#getConfigProperties() 036 */ 037public final class ConfigUtils { 038 039 private ConfigUtils() { 040 // hide constructor 041 } 042 043 /** 044 * Gets the specified configuration property. 045 * 046 * @param properties the configuration properties to read, must not be {@code null} 047 * @param defaultValue the default value to return in case none of the property keys are set, may be {@code null} 048 * @param keys the property keys to read, must not be {@code null}. The specified keys are read one after one until 049 * a valid value is found. 050 * @return the property value or {@code null} if none 051 */ 052 public static Object getObject(Map<?, ?> properties, Object defaultValue, String... keys) { 053 for (String key : keys) { 054 Object value = properties.get(key); 055 056 if (value != null) { 057 return value; 058 } 059 } 060 061 return defaultValue; 062 } 063 064 /** 065 * Gets the specified configuration property. 066 * 067 * @param session the repository system session from which to read the configuration property, must not be 068 * {@code null} 069 * @param defaultValue the default value to return in case none of the property keys are set, may be {@code null} 070 * @param keys the property keys to read, must not be {@code null}. The specified keys are read one after one until 071 * a valid value is found. 072 * @return the property value or {@code null} if none 073 */ 074 public static Object getObject(RepositorySystemSession session, Object defaultValue, String... keys) { 075 return getObject(session.getConfigProperties(), defaultValue, keys); 076 } 077 078 /** 079 * Gets the specified configuration property. 080 * 081 * @param properties the configuration properties to read, must not be {@code null} 082 * @param defaultValue the default value to return in case none of the property keys is set to a string, may be 083 * {@code null} 084 * @param keys the property keys to read, must not be {@code null}. The specified keys are read one after one until 085 * a string value is found. 086 * @return the property value or {@code null} if none 087 */ 088 public static String getString(Map<?, ?> properties, String defaultValue, String... keys) { 089 for (String key : keys) { 090 Object value = properties.get(key); 091 092 if (value instanceof String) { 093 return (String) value; 094 } 095 } 096 097 return defaultValue; 098 } 099 100 /** 101 * Gets the specified configuration property. 102 * 103 * @param session the repository system session from which to read the configuration property, must not be 104 * {@code null} 105 * @param defaultValue the default value to return in case none of the property keys is set to a string, may be 106 * {@code null} 107 * @param keys the property keys to read, must not be {@code null}. The specified keys are read one after one until 108 * a string value is found. 109 * @return the property value or {@code null} if none 110 */ 111 public static String getString(RepositorySystemSession session, String defaultValue, String... keys) { 112 return getString(session.getConfigProperties(), defaultValue, keys); 113 } 114 115 /** 116 * Gets the specified configuration property. 117 * 118 * @param properties the configuration properties to read, must not be {@code null} 119 * @param defaultValue the default value to return in case none of the property keys is set to a number 120 * @param keys the property keys to read, must not be {@code null}. The specified keys are read one after one until 121 * a {@link Number} or a string representation of an {@link Integer} is found. 122 * @return the property value 123 */ 124 public static int getInteger(Map<?, ?> properties, int defaultValue, String... keys) { 125 for (String key : keys) { 126 Object value = properties.get(key); 127 128 if (value instanceof Number) { 129 return ((Number) value).intValue(); 130 } else if (value instanceof String) { 131 try { 132 return Integer.parseInt((String) value); 133 } catch (NumberFormatException e) { 134 // try next key 135 } 136 } 137 } 138 139 return defaultValue; 140 } 141 142 /** 143 * Gets the specified configuration property. 144 * 145 * @param session the repository system session from which to read the configuration property, must not be 146 * {@code null} 147 * @param defaultValue the default value to return in case none of the property keys is set to a number 148 * @param keys the property keys to read, must not be {@code null}. The specified keys are read one after one until 149 * a {@link Number} or a string representation of an {@link Integer} is found. 150 * @return the property value 151 */ 152 public static int getInteger(RepositorySystemSession session, int defaultValue, String... keys) { 153 return getInteger(session.getConfigProperties(), defaultValue, keys); 154 } 155 156 /** 157 * Gets the specified configuration property. 158 * 159 * @param properties the configuration properties to read, must not be {@code null} 160 * @param defaultValue the default value to return in case none of the property keys is set to a number 161 * @param keys the property keys to read, must not be {@code null}. The specified keys are read one after one until 162 * a {@link Number} or a string representation of a {@link Long} is found. 163 * @return the property value 164 */ 165 public static long getLong(Map<?, ?> properties, long defaultValue, String... keys) { 166 for (String key : keys) { 167 Object value = properties.get(key); 168 169 if (value instanceof Number) { 170 return ((Number) value).longValue(); 171 } else if (value instanceof String) { 172 try { 173 return Long.parseLong((String) value); 174 } catch (NumberFormatException e) { 175 // try next key 176 } 177 } 178 } 179 180 return defaultValue; 181 } 182 183 /** 184 * Gets the specified configuration property. 185 * 186 * @param session the repository system session from which to read the configuration property, must not be 187 * {@code null} 188 * @param defaultValue the default value to return in case none of the property keys is set to a number 189 * @param keys the property keys to read, must not be {@code null}. The specified keys are read one after one until 190 * a {@link Number} or a string representation of a {@link Long} is found. 191 * @return the property value 192 */ 193 public static long getLong(RepositorySystemSession session, long defaultValue, String... keys) { 194 return getLong(session.getConfigProperties(), defaultValue, keys); 195 } 196 197 /** 198 * Gets the specified configuration property. 199 * 200 * @param properties the configuration properties to read, must not be {@code null} 201 * @param defaultValue the default value to return in case none of the property keys is set to a number 202 * @param keys the property keys to read, must not be {@code null}. The specified keys are read one after one until 203 * a {@link Number} or a string representation of a {@link Float} is found. 204 * @return the property value 205 */ 206 public static float getFloat(Map<?, ?> properties, float defaultValue, String... keys) { 207 for (String key : keys) { 208 Object value = properties.get(key); 209 210 if (value instanceof Number) { 211 return ((Number) value).floatValue(); 212 } else if (value instanceof String) { 213 try { 214 return Float.parseFloat((String) value); 215 } catch (NumberFormatException e) { 216 // try next key 217 } 218 } 219 } 220 221 return defaultValue; 222 } 223 224 /** 225 * Gets the specified configuration property. 226 * 227 * @param session the repository system session from which to read the configuration property, must not be 228 * {@code null} 229 * @param defaultValue the default value to return in case none of the property keys is set to a number 230 * @param keys the property keys to read, must not be {@code null}. The specified keys are read one after one until 231 * a {@link Number} or a string representation of a {@link Float} is found. 232 * @return the property value 233 */ 234 public static float getFloat(RepositorySystemSession session, float defaultValue, String... keys) { 235 return getFloat(session.getConfigProperties(), defaultValue, keys); 236 } 237 238 /** 239 * Gets the specified configuration property. 240 * 241 * @param properties the configuration properties to read, must not be {@code null} 242 * @param defaultValue the default value to return in case none of the property keys is set to a boolean 243 * @param keys the property keys to read, must not be {@code null}. The specified keys are read one after one until 244 * a {@link Boolean} or a string (to be {@link Boolean#parseBoolean(String) parsed as boolean}) is found. 245 * @return the property value 246 */ 247 public static boolean getBoolean(Map<?, ?> properties, boolean defaultValue, String... keys) { 248 for (String key : keys) { 249 Object value = properties.get(key); 250 251 if (value instanceof Boolean) { 252 return (Boolean) value; 253 } else if (value instanceof String) { 254 return Boolean.parseBoolean((String) value); 255 } 256 } 257 258 return defaultValue; 259 } 260 261 /** 262 * Gets the specified configuration property. 263 * 264 * @param session the repository system session from which to read the configuration property, must not be 265 * {@code null} 266 * @param defaultValue the default value to return in case none of the property keys is set to a boolean 267 * @param keys the property keys to read, must not be {@code null}. The specified keys are read one after one until 268 * a {@link Boolean} or a string (to be {@link Boolean#parseBoolean(String) parsed as boolean}) is found. 269 * @return the property value 270 */ 271 public static boolean getBoolean(RepositorySystemSession session, boolean defaultValue, String... keys) { 272 return getBoolean(session.getConfigProperties(), defaultValue, keys); 273 } 274 275 /** 276 * Gets the specified configuration property. 277 * 278 * @param properties the configuration properties to read, must not be {@code null} 279 * @param defaultValue the default value to return in case none of the property keys is set to a collection 280 * @param keys the property keys to read, must not be {@code null}. The specified keys are read one after one until 281 * a collection is found. 282 * @return the property value or {@code null} if none 283 */ 284 public static List<?> getList(Map<?, ?> properties, List<?> defaultValue, String... keys) { 285 for (String key : keys) { 286 Object value = properties.get(key); 287 288 if (value instanceof List) { 289 return (List<?>) value; 290 } else if (value instanceof Collection) { 291 return Collections.unmodifiableList(new ArrayList<>((Collection<?>) value)); 292 } 293 } 294 295 return defaultValue; 296 } 297 298 /** 299 * Gets the specified configuration property. 300 * 301 * @param session the repository system session from which to read the configuration property, must not be 302 * {@code null} 303 * @param defaultValue the default value to return in case none of the property keys is set to a collection 304 * @param keys the property keys to read, must not be {@code null}. The specified keys are read one after one until 305 * a collection is found. 306 * @return the property value or {@code null} if none 307 */ 308 public static List<?> getList(RepositorySystemSession session, List<?> defaultValue, String... keys) { 309 return getList(session.getConfigProperties(), defaultValue, keys); 310 } 311 312 /** 313 * Gets the specified configuration property. 314 * 315 * @param properties the configuration properties to read, must not be {@code null} 316 * @param defaultValue the default value to return in case none of the property keys is set to a map 317 * @param keys the property keys to read, must not be {@code null}. The specified keys are read one after one until 318 * a map is found. 319 * @return the property value or {@code null} if none 320 */ 321 public static Map<?, ?> getMap(Map<?, ?> properties, Map<?, ?> defaultValue, String... keys) { 322 for (String key : keys) { 323 Object value = properties.get(key); 324 325 if (value instanceof Map) { 326 return (Map<?, ?>) value; 327 } 328 } 329 330 return defaultValue; 331 } 332 333 /** 334 * Gets the specified configuration property. 335 * 336 * @param session the repository system session from which to read the configuration property, must not be 337 * {@code null} 338 * @param defaultValue the default value to return in case none of the property keys is set to a map 339 * @param keys the property keys to read, must not be {@code null}. The specified keys are read one after one until 340 * a map is found. 341 * @return the property value or {@code null} if none 342 */ 343 public static Map<?, ?> getMap(RepositorySystemSession session, Map<?, ?> defaultValue, String... keys) { 344 return getMap(session.getConfigProperties(), defaultValue, keys); 345 } 346 347 /** 348 * Gets the specified configuration property. 349 * @param <T> the enum type 350 * 351 * @param properties the configuration properties to read, must not be {@code null} 352 * @param enumClass the enum class to read, must not be {@code null} 353 * @param defaultValue the default value to return in case none of the property keys is set to a convertible String or T. 354 * @param keys the property keys to read, must not be {@code null}. The specified keys are read one after one until 355 * a enum type {@code T} or a string (parsed using {@link Enum#valueOf(Class, String)} is found. 356 * @return the property value or {@code defaultValue} if none found 357 * @since 2.0.21 358 */ 359 public static <T extends Enum<T>> T getEnum( 360 Map<?, ?> properties, Class<T> enumClass, T defaultValue, String... keys) { 361 for (String key : keys) { 362 Object value = properties.get(key); 363 364 if (enumClass.isInstance(value)) { // validate type 365 return enumClass.cast(value); 366 } else if (value instanceof String) { 367 return Enum.valueOf(enumClass, (String) value); 368 } 369 } 370 return defaultValue; 371 } 372 373 /** 374 * Gets the specified configuration property. 375 * @param <T> the enum type 376 * 377 * @param session the repository system session from which to read the configuration property, must not be 378 * {@code null} 379 * @param enumClass the enum class to read, must not be {@code null} 380 * @param defaultValue the default value to return in case none of the property keys is set to a convertible String or T. 381 * @param keys the property keys to read, must not be {@code null}. The specified keys are read one after one until 382 * a enum type {@code T} or a string (parsed using {@link Enum#valueOf(Class, String)} is found. 383 * @return the property value or {@code defaultValue} if none found 384 * @since 2.0.21 385 */ 386 public static <T extends Enum<T>> T getEnum( 387 RepositorySystemSession session, Class<T> enumClass, T defaultValue, String... keys) { 388 return getEnum(session.getConfigProperties(), enumClass, defaultValue, keys); 389 } 390 391 /** 392 * Utility method to parse configuration string that contains comma separated list of names into 393 * {@code List<String>}, never returns {@code null}. 394 * 395 * @since 1.9.0 396 */ 397 public static List<String> parseCommaSeparatedNames(String commaSeparatedNames) { 398 if (commaSeparatedNames == null || commaSeparatedNames.trim().isEmpty()) { 399 return Collections.emptyList(); 400 } 401 return Arrays.stream(commaSeparatedNames.split(",")) 402 .filter(s -> !s.trim().isEmpty()) 403 .collect(toList()); 404 } 405 406 /** 407 * Utility method to parse configuration string that contains comma separated list of names into 408 * {@code List<String>} with unique elements (duplicates, if any, are discarded), never returns {@code null}. 409 * 410 * @since 1.9.0 411 */ 412 public static List<String> parseCommaSeparatedUniqueNames(String commaSeparatedNames) { 413 return parseCommaSeparatedNames(commaSeparatedNames).stream().distinct().collect(toList()); 414 } 415}