diff options
author | Dmitry Puzikov <d.puzikov2@partner.samsung.com> | 2019-11-29 09:57:27 +0100 |
---|---|---|
committer | Ofir Sonsino <ofir.sonsino@intl.att.com> | 2020-01-29 09:48:59 +0000 |
commit | fe4623d1cddefe53df417d18115b69cc9265ec6e (patch) | |
tree | 0cb613d83bbbb0b1013cc05b98c3aad7dcd8e440 | |
parent | ceb5ab575aa49f4d082fe1e52cc1a3f8ff3ffd24 (diff) |
Fixed sonar issues
Refactored overcomplicated methods by splitting
into the more simple.
Remove redundant conditional checks.
Move common checks into the utils class.
Fixed raw types usage where it is possible.
Add some tests.
Fixed typos in test names.
Fixed lost switch branch.
Issue-ID: SDC-2698
Signed-off-by: Dmitry Puzikov <d.puzikov2@partner.samsung.com>
Change-Id: Ifb5887401be4b397267b2f922cc9ad3f01c757f6
3 files changed, 574 insertions, 357 deletions
diff --git a/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/ConfigurationUtils.java b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/ConfigurationUtils.java index 17e9ef048f..85698e89de 100644 --- a/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/ConfigurationUtils.java +++ b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/ConfigurationUtils.java @@ -45,6 +45,7 @@ import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; +import java.lang.reflect.Array; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; @@ -77,6 +78,7 @@ import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedTransferQueue; import java.util.concurrent.TransferQueue; +import java.util.function.Predicate; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -92,14 +94,14 @@ public class ConfigurationUtils { private static final String CONFIGURATION_TYPE_NOT_SUPPORTED = "Configuration type not supported:"; - private static final Map<Class, Class> ARRAY_CLASS_MAP; + private static final Map<Class<?>, Class<?>> ARRAY_CLASS_MAP; private static final String CONFIG_REGEX_TPL_OPT_1 = "CONFIG(-\\w*){0,1}(-(%s|%s|%s)){0,1}\\.(%s|%s|%s|%s)$"; private static final String CONFIG_REGEX_TPL_OPT_2 = "CONFIG(.)*\\.(%s|%s|%s|%s)$"; static { - Map<Class, Class> arrayTypes = new HashMap<>(); + Map<Class<?>, Class<?>> arrayTypes = new HashMap<>(); arrayTypes.put(Byte.class, Byte[].class); arrayTypes.put(Short.class, Short[].class); arrayTypes.put(Integer.class, Integer[].class); @@ -307,7 +309,7 @@ public class ConfigurationUtils { return Optional.ofNullable(configurationMode); } - public static Class getCollectionGenericType(Field field) { + public static Class<?> getCollectionGenericType(Field field) { Type type = field.getGenericType(); if (type instanceof ParameterizedType) { @@ -327,12 +329,74 @@ public class ConfigurationUtils { return String[].class; } - public static boolean isWrapperClass(Class clazz) { - return clazz == String.class || clazz == Boolean.class || clazz == Character.class - || Number.class.isAssignableFrom(clazz); + public static boolean isWrapperClass(Class<?> clazz) { + Predicate<Class<?>> predicateWrapper = type -> type == String.class || type == Boolean.class || type == Character.class + || Number.class.isAssignableFrom(type); + return isA(predicateWrapper, clazz); } - public static Class getArrayClass(Class clazz) { + public static boolean isAPrimitive(Class<?> clazz) { + return isA(Class::isPrimitive, clazz); + } + + /** + * Check if clazz implementing Map iface + */ + public static boolean isAMap(Class<?> clazz) { + Predicate<Class<?>> predicateMap = Map.class::isAssignableFrom; + return isA(predicateMap, clazz); + } + + /** + * Check if clazz implementing Collection iface + */ + public static boolean isACollection(Class<?> clazz) { + Predicate<Class<?>> predicateCollection = Collection.class::isAssignableFrom; + return isA(predicateCollection, clazz); + } + + /** + * Check if clazz is a primitive or primitive wrapper + */ + public static boolean isAPrimitiveOrWrapper(Class<?> clazz) { + Predicate<Class<?>> predicatePrimitive = Class::isPrimitive; + Predicate<Class<?>> predicateWrapper = ConfigurationUtils::isWrapperClass; + return isA(predicatePrimitive.or(predicateWrapper), clazz); + } + + /** + * Check if clazz is array of primitives or array of primitives wrappers + */ + public static boolean isAPrimitivesOrWrappersArray(Class<?> clazz) { + Predicate<Class<?>> predicatePrimitivesOrWrappersArray = + type -> ConfigurationUtils.isAWrappersArray(type) || ConfigurationUtils.isAPrimitivesArray(type); + return isA(predicatePrimitivesOrWrappersArray, clazz); + + } + + /** + * Check is clazz is array of primitives + */ + public static boolean isAPrimitivesArray(Class<?> clazz) { + Predicate<Class<?>> predicateArray = Class::isArray; + Predicate<Class<?>> predicateComponentPrimitive = type -> type.getComponentType().isPrimitive(); + return isA(predicateArray.and(predicateComponentPrimitive), clazz); + } + + /** + * Check is clazz is array of primitives wrappers + */ + public static boolean isAWrappersArray(Class<?> clazz) { + Predicate<Class<?>> predicateArray = Class::isArray; + Predicate<Class<?>> predicateComponentWrapper = type -> isWrapperClass(type.getComponentType()); + return isA(predicateArray.and(predicateComponentWrapper), clazz); + } + + private static boolean isA(Predicate<Class<?>> predicate, Class<?> clazz) { + return predicate.test(clazz); + } + + public static Class<?> getArrayClass(Class<?> clazz) { return ARRAY_CLASS_MAP.getOrDefault(clazz, null); } @@ -399,7 +463,7 @@ public class ConfigurationUtils { return objToReturn; } - public static Object getPrimitiveArray(Collection collection, Class clazz) { + public static Object getPrimitiveArray(Collection<?> collection, Class<?> clazz) { switch (clazz.getName()) { case "int": return getIntsPrimitiveArray(collection); @@ -415,11 +479,24 @@ public class ConfigurationUtils { return getDoublesPrimitiveArray(collection); case "boolean": return getBooleansPrimitiveArray(collection); + case "char": + return getCharsPrimitiveArray(collection); default: return null; } } + public static Object getWrappersArray(Collection<?> collection, Class<?> clazz) { + Object array = null; + if (isWrapperClass(clazz)){ + int collectionSize = collection.size(); + array = Array.newInstance(clazz, collection.size()); + Object[] objArray = collection.toArray(); + System.arraycopy(objArray, 0, array, 0, collectionSize); + } + return array; + } + public static String getCollectionString(String input) { Pattern pattern = Pattern.compile("^\\[(.*)\\]$"); Matcher matcher = pattern.matcher(input); @@ -473,7 +550,7 @@ public class ConfigurationUtils { return null; } - public static Object getDefaultFor(Class clazz) { + public static Object getDefaultFor(Class<?> clazz) { if (byte.class == clazz) { return new Byte("0"); } else if (short.class == clazz) { @@ -492,7 +569,7 @@ public class ConfigurationUtils { return (char) 0; } - public static Collection getCompatibleCollectionForAbstractDef(Class clazz) { + public static Collection getCompatibleCollectionForAbstractDef(Class<?> clazz) { if (TransferQueue.class.isAssignableFrom(clazz)) { return getConcreteCollection(TransferQueue.class); } @@ -518,7 +595,7 @@ public class ConfigurationUtils { + "assignable from TransferQueue, BlockingQueue, Deque, Queue, SortedSet, Set, List class"); } - public static Collection getConcreteCollection(Class clazz) { + public static Collection getConcreteCollection(Class<?> clazz) { switch (clazz.getName()) { case "java.util.Collection": case "java.util.List": @@ -639,8 +716,8 @@ public class ConfigurationUtils { return (hints & EXTERNAL_LOOKUP.value()) == EXTERNAL_LOOKUP.value(); } - public static boolean isZeroLengthArray(Class clazz, Object obj) { - if (clazz.isArray() && clazz.getComponentType().isPrimitive()) { + public static boolean isZeroLengthArray(Class<?> clazz, Object obj) { + if (isAPrimitivesArray(clazz)) { if (clazz.getComponentType() == int.class) { return ((int[]) obj).length == 0; } else if (clazz.getComponentType() == byte.class) { @@ -669,7 +746,7 @@ public class ConfigurationUtils { // private methods section starts here - private static int[] getIntsPrimitiveArray(Collection collection) { + private static int[] getIntsPrimitiveArray(Collection<?> collection) { int collectionSize = collection.size(); int[] array = new int[collectionSize]; Object[] objArray = collection.toArray(); @@ -679,7 +756,7 @@ public class ConfigurationUtils { return array; } - private static byte[] getBytesPrimitiveArray(Collection collection) { + private static byte[] getBytesPrimitiveArray(Collection<?> collection) { int collectionSize = collection.size(); byte[] array = new byte[collectionSize]; Object[] objArray = collection.toArray(); @@ -689,7 +766,7 @@ public class ConfigurationUtils { return array; } - private static short[] getShortsPrimitiveArray(Collection collection) { + private static short[] getShortsPrimitiveArray(Collection<?> collection) { int collectionSize = collection.size(); short[] array = new short[collectionSize]; Object[] objArray = collection.toArray(); @@ -699,7 +776,7 @@ public class ConfigurationUtils { return array; } - private static long[] getLongsPrimitiveArray(Collection collection) { + private static long[] getLongsPrimitiveArray(Collection<?> collection) { int collectionSize = collection.size(); long[] array = new long[collectionSize]; Object[] objArray = collection.toArray(); @@ -709,7 +786,7 @@ public class ConfigurationUtils { return array; } - private static float[] getFloatsPrimitiveArray(Collection collection) { + private static float[] getFloatsPrimitiveArray(Collection<?> collection) { int collectionSize = collection.size(); float[] array = new float[collectionSize]; Object[] objArray = collection.toArray(); @@ -719,7 +796,7 @@ public class ConfigurationUtils { return array; } - private static double[] getDoublesPrimitiveArray(Collection collection) { + private static double[] getDoublesPrimitiveArray(Collection<?> collection) { int collectionSize = collection.size(); double[] array = new double[collectionSize]; Object[] objArray = collection.toArray(); @@ -729,7 +806,7 @@ public class ConfigurationUtils { return array; } - private static boolean[] getBooleansPrimitiveArray(Collection collection) { + private static boolean[] getBooleansPrimitiveArray(Collection<?> collection) { int collectionSize = collection.size(); boolean[] array = new boolean[collectionSize]; Object[] objArray = collection.toArray(); @@ -738,4 +815,15 @@ public class ConfigurationUtils { } return array; } + + private static char[] getCharsPrimitiveArray(Collection<?> collection) { + int collectionSize = collection.size(); + char[] array = new char[collectionSize]; + Object[] objArray = collection.toArray(); + for (int i = 0; i < collectionSize; i++) { + array[i] = (char) objArray[i]; + } + return array; + } + } diff --git a/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ConfigurationImpl.java b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ConfigurationImpl.java index d13d5f7b92..0a5a141f09 100644 --- a/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ConfigurationImpl.java +++ b/common/onap-common-configuration-management/onap-configuration-management-core/src/main/java/org/onap/config/impl/ConfigurationImpl.java @@ -27,12 +27,16 @@ import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.atomic.AtomicReference; import java.util.function.Predicate; +import java.util.stream.Collectors; + import org.apache.commons.configuration2.ex.ConfigurationException; import org.onap.config.ConfigurationUtils; import org.onap.config.Constants; @@ -47,116 +51,21 @@ public class ConfigurationImpl implements org.onap.config.api.Configuration { private static final Logger LOGGER = LoggerFactory.getLogger(ConfigurationImpl.class); private static final String KEY_CANNOT_BE_NULL = "Key can't be null."; - private static final NonConfigResource NON_CONFIG_RESOURCE = new NonConfigResource(); + private static final Map<String, AggregateConfiguration> MODULE_CONFIG_STORE = new HashMap<>(); static { - - try { - init(); - } catch (ConfigurationException e) { - throw new IllegalStateException("Failed to initialize configuration", e); - } - } - - private static void init() throws ConfigurationException { - - Map<String, AggregateConfiguration> moduleConfigStore = new HashMap<>(); - List<URL> classpathResources = ConfigurationUtils.getAllClassPathResources(); - Predicate<URL> predicate = ConfigurationUtils::isConfig; - for (URL url : classpathResources) { - if (predicate.test(url)) { - String moduleName = ConfigurationUtils.getConfigurationRepositoryKey(url); - AggregateConfiguration moduleConfig = moduleConfigStore.get(moduleName); - if (moduleConfig == null) { - moduleConfig = new AggregateConfiguration(); - moduleConfigStore.put(moduleName, moduleConfig); - } - moduleConfig.addConfig(url); - } else { - NON_CONFIG_RESOURCE.add(url); - } - } - String configLocation = System.getProperty("config.location"); - if (!isBlank(configLocation)) { - File root = new File(configLocation); - Collection<File> filesystemResources = ConfigurationUtils.getAllFiles(root, true, false); - Predicate<File> filePredicate = ConfigurationUtils::isConfig; - for (File file : filesystemResources) { - if (filePredicate.test(file)) { - String moduleName = ConfigurationUtils.getConfigurationRepositoryKey(file); - AggregateConfiguration moduleConfig = moduleConfigStore.get(moduleName); - if (moduleConfig == null) { - moduleConfig = new AggregateConfiguration(); - moduleConfigStore.put(moduleName, moduleConfig); - } - moduleConfig.addConfig(file); - } else { - NON_CONFIG_RESOURCE.add(file); - } - } - } - String tenantConfigLocation = System.getProperty("tenant.config.location"); - if (!isBlank(tenantConfigLocation)) { - File root = new File(tenantConfigLocation); - Collection<File> tenantsRoot = ConfigurationUtils.getAllFiles(root, false, true); - Collection<File> filesystemResources = ConfigurationUtils.getAllFiles(root, true, false); - Predicate<File> filePredicate = ConfigurationUtils::isConfig; - for (File file : filesystemResources) { - if (filePredicate.test(file)) { - String moduleName = ConfigurationUtils.getNamespace(file); - for (File tenantFileRoot : tenantsRoot) { - if (file.getAbsolutePath().startsWith(tenantFileRoot.getAbsolutePath())) { - moduleName = ConfigurationUtils.getConfigurationRepositoryKey( - (tenantFileRoot.getName().toUpperCase() + Constants.TENANT_NAMESPACE_SEPARATOR - + moduleName).split(Constants.TENANT_NAMESPACE_SEPARATOR)); - } - } - AggregateConfiguration moduleConfig = moduleConfigStore.get(moduleName); - if (moduleConfig == null) { - moduleConfig = new AggregateConfiguration(); - moduleConfigStore.put(moduleName, moduleConfig); - } - moduleConfig.addConfig(file); - } - } - } - - populateFinalConfigurationIncrementally(moduleConfigStore); - String nodeConfigLocation = System.getProperty("node.config.location"); - if (!isBlank(nodeConfigLocation)) { - File root = new File(nodeConfigLocation); - Collection<File> filesystemResources = ConfigurationUtils.getAllFiles(root, true, false); - Predicate<File> filePredicate = ConfigurationUtils::isConfig; - for (File file : filesystemResources) { - if (filePredicate.test(file)) { - ConfigurationRepository.lookup().populateOverrideConfiguration( - ConfigurationUtils.getConfigurationRepositoryKey( - ConfigurationUtils.getNamespace(file).split(Constants.TENANT_NAMESPACE_SEPARATOR)), - file); - } - } - } - } - - private static void populateFinalConfigurationIncrementally(Map<String, AggregateConfiguration> configs) { - - if (configs.get(Constants.DEFAULT_TENANT + Constants.KEY_ELEMENTS_DELIMITER + Constants.DB_NAMESPACE) != null) { - ConfigurationRepository.lookup().populateConfiguration( - Constants.DEFAULT_TENANT + Constants.KEY_ELEMENTS_DELIMITER + Constants.DB_NAMESPACE, - configs.remove(Constants.DEFAULT_TENANT + Constants.KEY_ELEMENTS_DELIMITER + Constants.DB_NAMESPACE) - .getFinalConfiguration()); - } - - Set<String> modules = configs.keySet(); - for (String module : modules) { - ConfigurationRepository.lookup().populateConfiguration(module, configs.get(module).getFinalConfiguration()); + if (!loadClassPathConfigurationsAndResources() + || !loadAdditionalConfigurationsAndResources() + || !loadTenantConfigurations()) { + throw new IllegalStateException("Failed to initialize configuration"); } + populateFinalConfigurationIncrementally(MODULE_CONFIG_STORE); + loadNodeSpecificConfigurations(); } @Override public <T> T get(String tenant, String namespace, String key, Class<T> clazz, Hint... hints) { - String[] tenantNamespaceArray; if (tenant == null && namespace != null) { tenantNamespaceArray = namespace.split(Constants.TENANT_NAMESPACE_SEPARATOR); @@ -166,57 +75,46 @@ public class ConfigurationImpl implements org.onap.config.api.Configuration { } } - tenant = ConfigurationRepository.lookup().isValidTenant(tenant) ? tenant.toUpperCase() - : Constants.DEFAULT_TENANT; - namespace = ConfigurationRepository.lookup().isValidNamespace(namespace) ? namespace.toUpperCase() - : Constants.DEFAULT_NAMESPACE; + tenant = ConfigurationRepository.lookup().isValidTenant(tenant) ? tenant.toUpperCase() : Constants.DEFAULT_TENANT; + namespace = ConfigurationRepository.lookup().isValidNamespace(namespace) ? namespace.toUpperCase() : Constants.DEFAULT_NAMESPACE; + hints = hints == null || hints.length == 0 ? new Hint[]{Hint.EXTERNAL_LOOKUP, Hint.NODE_SPECIFIC} : hints; T returnValue; - returnValue = (T) getInternal(tenant, namespace, key, clazz.isPrimitive() ? getWrapperClass(clazz) : clazz, - hints == null || hints.length == 0 ? new Hint[] {Hint.EXTERNAL_LOOKUP, Hint.NODE_SPECIFIC} : hints); + returnValue = getInternal(tenant, namespace, key, clazz, hints); if ((returnValue == null || ConfigurationUtils.isZeroLengthArray(clazz, returnValue)) - && !Constants.DEFAULT_TENANT.equals(tenant)) { - returnValue = (T) getInternal(Constants.DEFAULT_TENANT, namespace, key, - clazz.isPrimitive() ? getWrapperClass(clazz) : clazz, - hints == null || hints.length == 0 ? new Hint[] {Hint.EXTERNAL_LOOKUP, Hint.NODE_SPECIFIC} : hints); + && !Constants.DEFAULT_TENANT.equals(tenant)) { + returnValue = getInternal(Constants.DEFAULT_TENANT, namespace, key, clazz, hints); } if ((returnValue == null || ConfigurationUtils.isZeroLengthArray(clazz, returnValue)) - && !Constants.DEFAULT_NAMESPACE.equals(namespace)) { - returnValue = (T) getInternal(tenant, Constants.DEFAULT_NAMESPACE, key, - clazz.isPrimitive() ? getWrapperClass(clazz) : clazz, - hints == null || hints.length == 0 ? new Hint[] {Hint.EXTERNAL_LOOKUP, Hint.NODE_SPECIFIC} : hints); + && !Constants.DEFAULT_NAMESPACE.equals(namespace)) { + returnValue = getInternal(tenant, Constants.DEFAULT_NAMESPACE, key, clazz, hints); } if ((returnValue == null || ConfigurationUtils.isZeroLengthArray(clazz, returnValue)) - && !Constants.DEFAULT_NAMESPACE.equals(namespace) && !Constants.DEFAULT_TENANT.equals(tenant)) { - returnValue = (T) getInternal(Constants.DEFAULT_TENANT, Constants.DEFAULT_NAMESPACE, key, - clazz.isPrimitive() ? getWrapperClass(clazz) : clazz, - hints == null || hints.length == 0 ? new Hint[] {Hint.EXTERNAL_LOOKUP, Hint.NODE_SPECIFIC} : hints); + && !Constants.DEFAULT_NAMESPACE.equals(namespace) && !Constants.DEFAULT_TENANT.equals(tenant)) { + returnValue = getInternal(Constants.DEFAULT_TENANT, Constants.DEFAULT_NAMESPACE, key, clazz, hints); } - if (returnValue == null && clazz.isPrimitive()) { - return (T) ConfigurationUtils.getDefaultFor(clazz); - } else { - return returnValue; + if (returnValue == null && ConfigurationUtils.isAPrimitive(clazz)) { + returnValue = (T) ConfigurationUtils.getDefaultFor(clazz); } + return returnValue; } @Override public <T> Map<String, T> populateMap(String tenantId, String namespace, String key, Class<T> clazz) { - - tenantId = calculateTenant(tenantId); - namespace = calculateNamespace(namespace); + final String calculatedTenantId = calculateTenant(tenantId); + final String calculatedNamespace = calculateNamespace(namespace); Map<String, T> map = new HashMap<>(); Iterator<String> keys; try { - keys = ConfigurationRepository.lookup().getConfigurationFor(tenantId, namespace).getKeys(key); - while (keys.hasNext()) { - String k = keys.next(); + keys = ConfigurationRepository.lookup().getConfigurationFor(calculatedTenantId, calculatedNamespace).getKeys(key); + keys.forEachRemaining(k -> { if (k.startsWith(key + ".")) { k = k.substring(key.length() + 1); String subkey = k.substring(0, k.indexOf('.')); if (!map.containsKey(subkey)) { - map.put(subkey, get(tenantId, namespace, key + "." + subkey, clazz)); + map.put(subkey, get(calculatedTenantId, calculatedNamespace, key + "." + subkey, clazz)); } } - } + }); } catch (Exception e) { LOGGER.warn( "Couldn't populate map fot tenant: {}, namespace: {}, key: {}, type: {}", @@ -231,47 +129,23 @@ public class ConfigurationImpl implements org.onap.config.api.Configuration { } @Override - public Map generateMap(String tenantId, String namespace, String key) { - - tenantId = calculateTenant(tenantId); - namespace = calculateNamespace(namespace); - - Map map; - Map parentMap = new HashMap<>(); - Iterator<String> keys; + public Map<Object, Object> generateMap(String tenantId, String namespace, String key) { + final String calculatedTenantId = calculateTenant(tenantId); + final String calculatedNamespace = calculateNamespace(namespace); + Map<Object, Object> parentMap = new HashMap<>(); + Iterator<String> configKeys; try { if (isBlank(key)) { - keys = ConfigurationRepository.lookup().getConfigurationFor(tenantId, namespace).getKeys(); + configKeys = ConfigurationRepository.lookup().getConfigurationFor(calculatedTenantId, calculatedNamespace).getKeys(); } else { - keys = ConfigurationRepository.lookup().getConfigurationFor(tenantId, namespace).getKeys(key); + configKeys = ConfigurationRepository.lookup().getConfigurationFor(calculatedTenantId, calculatedNamespace).getKeys(key); } - while (keys.hasNext()) { - map = parentMap; - String k = keys.next(); - - if (!isBlank(key) && !k.startsWith(key + ".")) { - continue; - } - String value = getAsString(tenantId, namespace, k); - if (!isBlank(key) && k.startsWith(key + ".")) { - k = k.substring(key.trim().length() + 1); + configKeys.forEachRemaining(subKey -> { + if (!isBlank(key) && !subKey.startsWith(key + ".")) { + configKeys.remove(); } - - while (k.contains(".")) { - if (k.contains(".")) { - String subkey = k.substring(0, k.indexOf('.')); - k = k.substring(k.indexOf('.') + 1); - if (!map.containsKey(subkey)) { - Map tmp = new HashMap(); - map.put(subkey, tmp); - map = tmp; - } else { - map = (Map) map.get(subkey); - } - } - } - map.put(k, value); - } + parseConfigSubKeys(subKey, key, calculatedTenantId, calculatedNamespace, parentMap); + }); } catch (Exception e) { LOGGER.warn( "Couldn't generate map fot tenant: {}, namespace: {}, key: {}", @@ -284,6 +158,159 @@ public class ConfigurationImpl implements org.onap.config.api.Configuration { return parentMap; } + private static boolean loadClassPathConfigurationsAndResources() { + List<URL> classpathResources = ConfigurationUtils.getAllClassPathResources(); + Predicate<URL> predicate = ConfigurationUtils::isConfig; + Map<Boolean, List<URL>> resources = classpathResources.stream().collect(Collectors.partitioningBy(predicate)); + List<URL> configResources = resources.get(true); + List<URL> nonConfigResources = resources.get(false); + AtomicReference<Boolean> successFlagHolder = new AtomicReference<>(true); + + configResources.forEach(url -> successFlagHolder.set(setUpdateModuleConfigStore(url))); + + nonConfigResources.forEach(NON_CONFIG_RESOURCE::add); + + return successFlagHolder.get(); + } + + private static boolean loadAdditionalConfigurationsAndResources() { + String configLocation = System.getProperty("config.location"); + AtomicReference<Boolean> successFlagHolder = new AtomicReference<>(true); + if (!isBlank(configLocation)) { + File root = new File(configLocation); + Collection<File> filesystemResources = ConfigurationUtils.getAllFiles(root, true, false); + Predicate<File> filePredicate = ConfigurationUtils::isConfig; + Map<Boolean, List<File>> resources = filesystemResources.stream().collect(Collectors.partitioningBy(filePredicate)); + List<File> configResources = resources.get(true); + List<File> nonConfigResources = resources.get(false); + + configResources.forEach(file -> successFlagHolder.set(setUpdateModuleConfigStore(file))); + + nonConfigResources.forEach(NON_CONFIG_RESOURCE::add); + } + return successFlagHolder.get(); + } + + private static boolean loadTenantConfigurations() { + String tenantConfigLocation = System.getProperty("tenant.config.location"); + AtomicReference<Boolean> successFlagHolder = new AtomicReference<>(true); + if (!isBlank(tenantConfigLocation)) { + File root = new File(tenantConfigLocation); + Collection<File> tenantsRoot = ConfigurationUtils.getAllFiles(root, false, true); + Collection<File> filesystemResources = ConfigurationUtils.getAllFiles(root, true, false); + + Map<Boolean, List<File>> resources = filesystemResources.stream().collect(Collectors.partitioningBy(ConfigurationUtils::isConfig)); + Collection<File> tenantResources = resources.get(true); + + tenantResources.forEach(configFile -> { + AtomicReference<String> moduleNameHolder = new AtomicReference<>(ConfigurationUtils.getNamespace(configFile)); + Predicate<File> startsWithRootPredicate = tenantRoot -> configFile.getAbsolutePath().startsWith(tenantRoot.getAbsolutePath()); + Collection<File> matchesTenantRoot = tenantsRoot.stream().filter(startsWithRootPredicate).collect(Collectors.toCollection(ArrayList::new)); + AtomicReference<String[]> altResource = new AtomicReference<>(); + matchesTenantRoot.forEach(file -> altResource.set( + (file.getName().toUpperCase() + Constants.TENANT_NAMESPACE_SEPARATOR + moduleNameHolder.get()) + .split(Constants.TENANT_NAMESPACE_SEPARATOR) + ) + ); + successFlagHolder.set(setUpdateModuleConfigStore(configFile, altResource.get())); + }); + } + return successFlagHolder.get(); + } + + private static void loadNodeSpecificConfigurations() { + String nodeConfigLocation = System.getProperty("node.config.location"); + if (!isBlank(nodeConfigLocation)) { + File root = new File(nodeConfigLocation); + Collection<File> filesystemResources = ConfigurationUtils.getAllFiles(root, true, false); + filesystemResources.stream().filter(ConfigurationUtils::isConfig).forEach( + file -> ConfigurationRepository.lookup().populateOverrideConfiguration( + ConfigurationUtils.getConfigurationRepositoryKey( + ConfigurationUtils.getNamespace(file).split(Constants.TENANT_NAMESPACE_SEPARATOR)), file) + ); + } + } + + private static void populateFinalConfigurationIncrementally(Map<String, AggregateConfiguration> configs) { + if (configs.get(Constants.DEFAULT_TENANT + Constants.KEY_ELEMENTS_DELIMITER + Constants.DB_NAMESPACE) != null) { + ConfigurationRepository.lookup().populateConfiguration( + Constants.DEFAULT_TENANT + Constants.KEY_ELEMENTS_DELIMITER + Constants.DB_NAMESPACE, + configs.remove(Constants.DEFAULT_TENANT + Constants.KEY_ELEMENTS_DELIMITER + Constants.DB_NAMESPACE) + .getFinalConfiguration()); + } + Set<String> modules = configs.keySet(); + modules.forEach( + m -> ConfigurationRepository.lookup().populateConfiguration(m, configs.get(m).getFinalConfiguration()) + ); + } + + private static <T> boolean setUpdateModuleConfigStore(T resource, String... namedResources) { + boolean success = true; + String moduleName; + try { + if (namedResources == null || namedResources.length == 0) { + moduleName = getConfigurationRepositoryKeyWrapper(resource); + } else { + moduleName = getConfigurationRepositoryKeyWrapper(namedResources); + } + moduleAddConfigWrapper(moduleName, resource); + } catch (Exception e) { + success = false; + LOGGER.error("Error occurred while processing config resource {}", resource, e); + } + return success; + } + + private static <T> String getConfigurationRepositoryKeyWrapper(T resource) throws ConfigurationException { + switch (resource.getClass().getSimpleName()) { + case "URL": + return ConfigurationUtils.getConfigurationRepositoryKey((URL) resource); + case "File": + return ConfigurationUtils.getConfigurationRepositoryKey((File) resource); + case "String[]": + return ConfigurationUtils.getConfigurationRepositoryKey((String[]) resource); + default: + throw new ConfigurationException("Unsupported resource type."); + } + } + + private static <T> void moduleAddConfigWrapper(String moduleName, T resource) throws ConfigurationException { + AggregateConfiguration moduleConfig = MODULE_CONFIG_STORE.get(moduleName); + if (moduleConfig == null) { + moduleConfig = new AggregateConfiguration(); + MODULE_CONFIG_STORE.put(moduleName, moduleConfig); + } + switch (resource.getClass().getSimpleName()) { + case "URL": + moduleConfig.addConfig((URL) resource); + break; + case "File": + moduleConfig.addConfig((File) resource); + break; + default: + throw new ConfigurationException("Unsupported resource type."); + } + } + + private void parseConfigSubKeys(String subKey, String keyPrefix, String tenantId, String namespace, Map<Object, Object> targetMap) { + String value = getAsString(tenantId, namespace, subKey); + if (!isBlank(keyPrefix) && subKey.startsWith(keyPrefix + ".")) { + subKey = subKey.substring(keyPrefix.trim().length() + 1); + } + while (subKey.contains(".")) { + String subSubKey = subKey.substring(0, subKey.indexOf('.')); + subKey = subKey.substring(subKey.indexOf('.') + 1); + if (!targetMap.containsKey(subSubKey)) { + Map<Object, Object> subMap = new HashMap<>(); + targetMap.put(subSubKey, subMap); + targetMap = subMap; + } else { + targetMap = (Map<Object, Object>) targetMap.get(subSubKey); + } + } + targetMap.put(subKey, value); + } + protected <T> T getInternal(String tenant, String namespace, String key, Class<T> clazz, Hint... hints) { int processingHints = Hint.DEFAULT.value(); if (hints != null) { @@ -303,50 +330,16 @@ public class ConfigurationImpl implements org.onap.config.api.Configuration { throw new IllegalArgumentException("clazz is null."); } - if (clazz.isPrimitive()) { + if (ConfigurationUtils.isAPrimitive(clazz)) { clazz = getWrapperClass(clazz); } try { - if (ConfigurationUtils.isWrapperClass(clazz) || clazz.isPrimitive()) { - Object obj = ConfigurationUtils.getProperty( - ConfigurationRepository.lookup().getConfigurationFor(tenant, namespace), key, processingHints); - if (obj != null) { - if (ConfigurationUtils.isCollection(obj.toString())) { - obj = ConfigurationUtils.getCollectionString(obj.toString()); - } - String value = obj.toString().split(",")[0]; - value = ConfigurationUtils.processVariablesIfPresent(tenant, namespace, value); - return (T) getValue(value, clazz.isPrimitive() ? getWrapperClass(clazz) : clazz, processingHints); - } else { - return null; - } - } else if (clazz.isArray() && (clazz.getComponentType().isPrimitive() || ConfigurationUtils.isWrapperClass( - clazz.getComponentType()))) { - Object obj = ConfigurationUtils.getProperty( - ConfigurationRepository.lookup().getConfigurationFor(tenant, namespace), key, processingHints); - if (obj != null) { - Class componentClass = clazz.getComponentType(); - if (clazz.getComponentType().isPrimitive()) { - componentClass = getWrapperClass(clazz.getComponentType()); - } - String collString = ConfigurationUtils.getCollectionString(obj.toString()); - ArrayList<String> tempCollection = new ArrayList<>(); - for (String itemValue : collString.split(",")) { - tempCollection.add(ConfigurationUtils.processVariablesIfPresent(tenant, namespace, itemValue)); - } - Collection<T> collection = - convert(ConfigurationUtils.getCollectionString(Arrays.toString(tempCollection.toArray())), - componentClass, processingHints); - if (clazz.getComponentType().isPrimitive()) { - return (T) ConfigurationUtils.getPrimitiveArray(collection, clazz.getComponentType()); - } else { - return (T) collection.toArray(getZeroLengthArrayFor(getWrapperClass(clazz.getComponentType()))); - } - } else { - return null; - } + if (ConfigurationUtils.isWrapperClass(clazz)) { + return getWrapperTypeValue(tenant, namespace, key, clazz, processingHints); + } else if (ConfigurationUtils.isAPrimitivesOrWrappersArray(clazz)) { + return getArrayTypeValue(tenant, namespace, key, clazz, processingHints); } else if (clazz.isAnnotationPresent(Config.class)) { - return read(tenant, namespace, clazz, isBlank(key) ? "" : (key + "."), hints); + return getAnnotatedTypeValue(tenant, namespace, clazz, isBlank(key) ? "" : (key + "."), hints); } else { throw new IllegalArgumentException( "Only primitive classes, wrapper classes, corresponding array classes and any " @@ -365,6 +358,51 @@ public class ConfigurationImpl implements org.onap.config.api.Configuration { return null; } + private <T> T getWrapperTypeValue(String tenant, String namespace, String key, Class<T> clazz, int processingHints) throws Exception { + Object obj = ConfigurationUtils.getProperty( + ConfigurationRepository.lookup().getConfigurationFor(tenant, namespace), key, processingHints); + if (obj != null) { + if (ConfigurationUtils.isCollection(obj.toString())) { + obj = ConfigurationUtils.getCollectionString(obj.toString()); + } + String value = ConfigurationUtils.processVariablesIfPresent( + tenant, + namespace, + obj.toString().split(",")[0] + ); + return (T) getTypeValue(value, clazz, processingHints); + } + return null; + } + + private <T> T getArrayTypeValue(String tenant, String namespace, String key, Class<T> clazz, int processingHints) throws Exception { + Object obj = ConfigurationUtils.getProperty( + ConfigurationRepository.lookup().getConfigurationFor(tenant, namespace), key, processingHints); + if (obj != null) { + Class componentType = clazz.getComponentType(); + if (ConfigurationUtils.isAPrimitivesArray(clazz)) { + componentType = getWrapperClass(componentType); + } + String collString = ConfigurationUtils.getCollectionString(obj.toString()); + ArrayList<String> tempCollection = new ArrayList<>(); + for (String itemValue : collString.split(",")) { + tempCollection.add(ConfigurationUtils.processVariablesIfPresent(tenant, namespace, itemValue)); + } + Collection<T> collection = convert( + ConfigurationUtils.getCollectionString(Arrays.toString(tempCollection.toArray())), + (Class<T>) componentType, + processingHints + ); + if (ConfigurationUtils.isAPrimitivesArray(clazz)) { + return (T) ConfigurationUtils.getPrimitiveArray(collection, componentType); + } else { + return (T) collection.toArray(getZeroLengthArrayFor(getWrapperClass(componentType))); + } + } else { + return null; + } + } + private static String calculateNamespace(String namespace) { if (isBlank(namespace)) { @@ -383,7 +421,7 @@ public class ConfigurationImpl implements org.onap.config.api.Configuration { return tenant.toUpperCase(); } - private <T> T read(String tenant, String namespace, Class<T> clazz, String keyPrefix, Hint... hints) + private <T> T getAnnotatedTypeValue(String tenant, String namespace, Class<T> clazz, String keyPrefix, Hint... hints) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { Config confAnnotation = clazz.getAnnotation(Config.class); @@ -396,53 +434,72 @@ public class ConfigurationImpl implements org.onap.config.api.Configuration { for (Field field : clazz.getDeclaredFields()) { field.setAccessible(true); Config fieldConfAnnotation = field.getAnnotation(Config.class); + Class<?> fieldType = field.getType(); if (fieldConfAnnotation != null) { - if (field.getType().isPrimitive() || ConfigurationUtils.isWrapperClass(field.getType()) || ( - field.getType().isArray() && (field.getType().getComponentType().isPrimitive() - || ConfigurationUtils.isWrapperClass( - field.getType().getComponentType()))) - || field.getType().getAnnotation(Config.class) != null) { - field.set(objToReturn, - get(tenant, namespace, keyPrefix + fieldConfAnnotation.key(), field.getType(), hints)); - } else if (Collection.class.isAssignableFrom(field.getType())) { - Object obj = get(tenant, namespace, keyPrefix + fieldConfAnnotation.key(), - ConfigurationUtils.getArrayClass(ConfigurationUtils.getCollectionGenericType(field)), - hints); - if (obj != null) { - List list = Arrays.asList((Object[]) obj); - Class clazzToInstantiate; - if (field.getType().isInterface()) { - clazzToInstantiate = ConfigurationUtils.getConcreteCollection(field.getType()).getClass(); - } else if (Modifier.isAbstract(field.getType().getModifiers())) { - clazzToInstantiate = - ConfigurationUtils.getCompatibleCollectionForAbstractDef(field.getType()) - .getClass(); - } else { - clazzToInstantiate = field.getType(); - } - Constructor construct = getConstructorWithArguments(clazzToInstantiate, Collection.class); - - if (construct != null) { - construct.setAccessible(true); - field.set(objToReturn, construct.newInstance(list)); - } else { - construct = getConstructorWithArguments(clazzToInstantiate, Integer.class, - Boolean.class, Collection.class); - if (construct != null) { - construct.setAccessible(true); - field.set(objToReturn, construct.newInstance(list.size(), true, list)); - } - } - } - } else if (Map.class.isAssignableFrom(field.getType())) { - field.set(objToReturn, generateMap(tenant, namespace, keyPrefix + fieldConfAnnotation.key())); + if (ConfigurationUtils.isAPrimitiveOrWrapper(fieldType) || + ConfigurationUtils.isAPrimitivesOrWrappersArray(fieldType)) { + setPrimitiveField(field, objToReturn, tenant, namespace, keyPrefix, hints); + } + if (ConfigurationUtils.isACollection(fieldType)) { + setCollectionField(field, objToReturn, tenant, namespace, keyPrefix, hints); + } + if (ConfigurationUtils.isAMap(fieldType)) { + setMapField(field, objToReturn, tenant, namespace, keyPrefix); } } } return objToReturn; } - private Constructor getConstructorWithArguments(Class clazz, Class... classes) { + private void setPrimitiveField(Field field, Object objToReturn, String tenant, String namespace, String keyPrefix, Hint[] hints) + throws IllegalAccessException { + String fieldConfAnnotationKey = field.getAnnotation(Config.class).key(); + Class<?> fieldType = field.getType(); + field.set(objToReturn, get(tenant, namespace, keyPrefix + fieldConfAnnotationKey, fieldType, hints)); + } + + private void setMapField(Field field, Object objToReturn, String tenant, String namespace, String keyPrefix) + throws IllegalAccessException { + String fieldConfAnnotationKey = field.getAnnotation(Config.class).key(); + field.set(objToReturn, generateMap(tenant, namespace, keyPrefix + fieldConfAnnotationKey)); + } + + private void setCollectionField(Field field, Object objToReturn, String tenant, String namespace, String keyPrefix, Hint[] hints) + throws IllegalAccessException, InvocationTargetException, InstantiationException { + String fieldConfAnnotationKey = field.getAnnotation(Config.class).key(); + Class<?> fieldType = field.getType(); + Object obj = get(tenant, namespace, keyPrefix + fieldConfAnnotationKey, + ConfigurationUtils.getArrayClass(ConfigurationUtils.getCollectionGenericType(field)), + hints); + if (obj != null) { + List<Object> list = Arrays.asList((Object[]) obj); + Class clazzToInstantiate; + if (fieldType.isInterface()) { + clazzToInstantiate = ConfigurationUtils.getConcreteCollection(fieldType).getClass(); + } else if (Modifier.isAbstract(fieldType.getModifiers())) { + clazzToInstantiate = + ConfigurationUtils.getCompatibleCollectionForAbstractDef(fieldType) + .getClass(); + } else { + clazzToInstantiate = fieldType; + } + Constructor construct = getConstructorWithArguments(clazzToInstantiate, Collection.class); + + if (construct != null) { + construct.setAccessible(true); + field.set(objToReturn, construct.newInstance(list)); + } else { + construct = getConstructorWithArguments(clazzToInstantiate, Integer.class, + Boolean.class, Collection.class); + if (construct != null) { + construct.setAccessible(true); + field.set(objToReturn, construct.newInstance(list.size(), true, list)); + } + } + } + } + + private Constructor getConstructorWithArguments(Class<?> clazz, Class<?>... classes) { try { return clazz.getDeclaredConstructor(classes); } catch (Exception exception) { @@ -451,7 +508,7 @@ public class ConfigurationImpl implements org.onap.config.api.Configuration { } } - private Class getWrapperClass(Class clazz) { + private Class getWrapperClass(Class<?> clazz) { if (byte.class == clazz) { return Byte.class; } else if (short.class == clazz) { @@ -472,101 +529,82 @@ public class ConfigurationImpl implements org.onap.config.api.Configuration { return clazz; } - private <T> T getValue(Object obj, Class<T> clazz, int processingHint) { - + private <T> T getTypeValue(Object obj, Class<T> clazz, int processingHint) { if (obj == null || obj.toString().trim().length() == 0) { return null; } else { obj = obj.toString().trim(); } - if (String.class.equals(clazz)) { - if (obj.toString().startsWith("@") && ConfigurationUtils.isExternalLookup(processingHint)) { - String contents = ConfigurationUtils.getFileContents( - NON_CONFIG_RESOURCE.locate(obj.toString().substring(1).trim())); - if (contents == null) { - contents = ConfigurationUtils.getFileContents(obj.toString().substring(1).trim()); - } - if (contents != null) { - obj = contents; - } - } - return (T) obj.toString(); - } else if (Number.class.isAssignableFrom(clazz)) { - Double doubleValue = Double.valueOf(obj.toString()); - switch (clazz.getName()) { - case "java.lang.Byte": - Byte byteVal = doubleValue.byteValue(); - return (T) byteVal; - case "java.lang.Short": - Short shortVal = doubleValue.shortValue(); - return (T) shortVal; - case "java.lang.Integer": - Integer intVal = doubleValue.intValue(); - return (T) intVal; - case "java.lang.Long": - Long longVal = doubleValue.longValue(); - return (T) longVal; - case "java.lang.Float": - Float floatVal = doubleValue.floatValue(); - return (T) floatVal; - case "java.lang.Double": - return (T) doubleValue; - default: - } - } else if (Boolean.class.equals(clazz)) { + return getValueForStringType(obj, processingHint); + } + if (Number.class.isAssignableFrom(clazz)) { + return getValueForNumbersType(obj, clazz); + } + if (Boolean.class.equals(clazz)) { return (T) Boolean.valueOf(obj.toString()); - } else if (Character.class.equals(clazz)) { + } + if (Character.class.equals(clazz)) { return (T) Character.valueOf(obj.toString().charAt(0)); } return null; } + private <T> T getValueForStringType(Object obj, int processingHint) { + if (obj.toString().startsWith("@") && ConfigurationUtils.isExternalLookup(processingHint)) { + String subString = obj.toString().substring(1).trim(); + String contents = ConfigurationUtils.getFileContents( + NON_CONFIG_RESOURCE.locate(subString)); + if (contents == null) { + contents = ConfigurationUtils.getFileContents(subString); + } + if (contents != null) { + obj = contents; + } + } + return (T) obj.toString(); + } + + private <T> T getValueForNumbersType(Object obj, Class<T> clazz) { + Double doubleValue = Double.valueOf(obj.toString()); + switch (clazz.getName()) { + case "java.lang.Byte": + Byte byteVal = doubleValue.byteValue(); + return (T) byteVal; + case "java.lang.Short": + Short shortVal = doubleValue.shortValue(); + return (T) shortVal; + case "java.lang.Integer": + Integer intVal = doubleValue.intValue(); + return (T) intVal; + case "java.lang.Long": + Long longVal = doubleValue.longValue(); + return (T) longVal; + case "java.lang.Float": + Float floatVal = doubleValue.floatValue(); + return (T) floatVal; + case "java.lang.Double": + return (T) doubleValue; + default: + return null; + } + } + private <T> T[] getZeroLengthArrayFor(Class<T> clazz) { - Object obj = null; - if (clazz == int.class) { - obj = new int[] {}; - } else if (clazz == byte.class) { - obj = new byte[] {}; - } else if (clazz == short.class) { - obj = new short[] {}; - } else if (clazz == long.class) { - obj = new long[] {}; - } else if (clazz == float.class) { - obj = new float[] {}; - } else if (clazz == double.class) { - obj = new double[] {}; - } else if (clazz == boolean.class) { - obj = new boolean[] {}; - } else if (clazz == char.class) { - obj = new char[] {}; - } else if (clazz == Byte.class) { - obj = new Byte[] {}; - } else if (clazz == Short.class) { - obj = new Short[] {}; - } else if (clazz == Integer.class) { - obj = new Integer[] {}; - } else if (clazz == Long.class) { - obj = new Long[] {}; - } else if (clazz == Float.class) { - obj = new Float[] {}; - } else if (clazz == Double.class) { - obj = new Double[] {}; - } else if (clazz == Boolean.class) { - obj = new Boolean[] {}; - } else if (clazz == Character.class) { - obj = new Character[] {}; - } else if (clazz == String.class) { - obj = new String[] {}; - } - return (T[]) obj; + Object objToReturn = null; + if (ConfigurationUtils.isAPrimitive(clazz)) { + objToReturn = ConfigurationUtils.getPrimitiveArray(Collections.emptyList(), clazz); + } else if (ConfigurationUtils.isWrapperClass(clazz)) { + objToReturn = ConfigurationUtils.getWrappersArray(Collections.emptyList(), clazz); + } + return (T[]) objToReturn; } private <T> Collection<T> convert(String commaSeparatedValues, Class<T> clazz, int processingHints) { ArrayList<T> collection = new ArrayList<>(); for (String value : commaSeparatedValues.split(",")) { try { - T type1 = getValue(value, clazz, processingHints); + T type1 = getTypeValue(value, clazz, processingHints); if (type1 != null) { collection.add(type1); } diff --git a/common/onap-common-configuration-management/onap-configuration-management-core/src/test/java/org/onap/config/ConfigurationUtilsTest.java b/common/onap-common-configuration-management/onap-configuration-management-core/src/test/java/org/onap/config/ConfigurationUtilsTest.java index dab8946883..cfb27d53db 100644 --- a/common/onap-common-configuration-management/onap-configuration-management-core/src/test/java/org/onap/config/ConfigurationUtilsTest.java +++ b/common/onap-common-configuration-management/onap-configuration-management-core/src/test/java/org/onap/config/ConfigurationUtilsTest.java @@ -20,6 +20,7 @@ package org.onap.config; import static java.util.stream.Collectors.toList; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNotNull; @@ -36,7 +37,9 @@ import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.Deque; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -77,7 +80,7 @@ public class ConfigurationUtilsTest { @Test public void testCommaListWithNullAndEmptyStrings() { - List list = Arrays.asList(null, "", " "); + List<String> list = Arrays.asList(null, "", " "); String commaSeparatedList = ConfigurationUtils.getCommaSeparatedList(list); assertTrue(commaSeparatedList.isEmpty()); } @@ -101,12 +104,12 @@ public class ConfigurationUtilsTest { @Test public void testCastingArray() { int arraySize = 2; - final Class[] primitiveType = new Class[]{boolean.class, byte.class, + final Class<?>[] primitiveType = new Class[]{boolean.class, byte.class, double.class, float.class, int.class, long.class, short.class}; - for (Class clazz: primitiveType) { - Class expectedResultClass = Array.newInstance(clazz, 0).getClass(); - List defaultCollection = IntStream.range(0, arraySize).mapToObj(i -> + for (Class<?> clazz : primitiveType) { + Class<?> expectedResultClass = Array.newInstance(clazz, 0).getClass(); + List<?> defaultCollection = IntStream.range(0, arraySize).mapToObj(i -> ConfigurationUtils.getDefaultFor(clazz)).collect(toList()); Object resultArray = ConfigurationUtils.getPrimitiveArray(defaultCollection, clazz); @@ -119,7 +122,7 @@ public class ConfigurationUtilsTest { @Test(expected = IllegalArgumentException.class) public void testGetCompatibleCollection() { - final Map<Class, Class> testClasses = Stream.of(new Class[][] { + final Map<Class<?>, Class<?>> testClasses = Stream.of(new Class<?>[][]{ {BlockingQueue.class, LinkedBlockingQueue.class}, {TransferQueue.class, LinkedTransferQueue.class}, {Deque.class, ArrayDeque.class}, @@ -130,9 +133,9 @@ public class ConfigurationUtilsTest { }).collect(Collectors.toMap(data -> data[0], data -> data[1])); testClasses.forEach((entryClass, expResultClass) -> { - Class resultClass = ConfigurationUtils.getCompatibleCollectionForAbstractDef(entryClass).getClass(); - assertEquals(expResultClass, resultClass); - } + Class<?> resultClass = ConfigurationUtils.getCompatibleCollectionForAbstractDef(entryClass).getClass(); + assertEquals(expResultClass, resultClass); + } ); ConfigurationUtils.getCompatibleCollectionForAbstractDef(Collection.class); @@ -140,6 +143,54 @@ public class ConfigurationUtilsTest { } @Test + public void testGetPrimitivesArrayZeroLength() { + assertArrayEquals(new int[0], (int[]) ConfigurationUtils.getPrimitiveArray(Collections.emptyList(), int.class)); + assertArrayEquals(new byte[0], (byte[]) ConfigurationUtils.getPrimitiveArray(Collections.emptyList(), byte.class)); + assertArrayEquals(new short[0], (short[]) ConfigurationUtils.getPrimitiveArray(Collections.emptyList(), short.class)); + assertArrayEquals(new long[0], (long[]) ConfigurationUtils.getPrimitiveArray(Collections.emptyList(), long.class)); + assertArrayEquals(new double[0], (double[]) ConfigurationUtils.getPrimitiveArray(Collections.emptyList(), double.class), 0); + assertArrayEquals(new float[0], (float[]) ConfigurationUtils.getPrimitiveArray(Collections.emptyList(), float.class), 0); + assertArrayEquals(new boolean[0], (boolean[]) ConfigurationUtils.getPrimitiveArray(Collections.emptyList(), boolean.class)); + assertArrayEquals(new char[0], (char[]) ConfigurationUtils.getPrimitiveArray(Collections.emptyList(), char.class)); + assertNull(ConfigurationUtils.getPrimitiveArray(Collections.emptyList(), Integer.class)); + } + + @Test + public void testGetWrappersArrayZeroLength() { + assertArrayEquals(new Integer[0], (Integer[]) ConfigurationUtils.getWrappersArray(Collections.emptyList(), Integer.class)); + assertArrayEquals(new Byte[0], (Byte[]) ConfigurationUtils.getWrappersArray(Collections.emptyList(), Byte.class)); + assertArrayEquals(new Short[0], (Short[]) ConfigurationUtils.getWrappersArray(Collections.emptyList(), Short.class)); + assertArrayEquals(new Long[0], (Long[]) ConfigurationUtils.getWrappersArray(Collections.emptyList(), Long.class)); + assertArrayEquals(new Double[0], (Double[]) ConfigurationUtils.getWrappersArray(Collections.emptyList(), Double.class)); + assertArrayEquals(new Float[0], (Float[]) ConfigurationUtils.getWrappersArray(Collections.emptyList(), Float.class)); + assertArrayEquals(new Boolean[0], (Boolean[]) ConfigurationUtils.getWrappersArray(Collections.emptyList(), Boolean.class)); + assertArrayEquals(new Character[0], (Character[]) ConfigurationUtils.getWrappersArray(Collections.emptyList(), Character.class)); + assertNull(ConfigurationUtils.getWrappersArray(Collections.emptyList(), boolean.class)); + } + + @Test + public void testPrimitivesArrayNonZeroLength() { + List<Integer> list = new ArrayList<>(); + list.add(1); + list.add(2); + list.add(3); + list.add(4); + list.add(5); + assertArrayEquals(new int[]{1, 2, 3, 4, 5}, (int[]) ConfigurationUtils.getPrimitiveArray(list, int.class)); + } + + @Test + public void testWrappersArrayNonZeroLength() { + List<Integer> list = new ArrayList<>(); + list.add(1); + list.add(2); + list.add(3); + list.add(4); + list.add(5); + assertArrayEquals(new Integer[]{1, 2, 3, 4, 5}, (Integer[]) ConfigurationUtils.getWrappersArray(list, Integer.class)); + } + + @Test public void testGetAllFilesRecursiveIncludeAll() throws IOException { Path tmpRoot = TestUtil.createTestDirsStructure(TMP_DIR_PREFIX); Collection<File> allFiles = ConfigurationUtils.getAllFiles(tmpRoot.toFile(), true, false); @@ -207,6 +258,46 @@ public class ConfigurationUtilsTest { assertEquals(TEST_NAME_SPACE, ConfigurationUtils.getProperty(config, Constants.NAMESPACE_KEY, Hint.NODE_SPECIFIC.value())); } + @Test + public void testIsAMap() { + assertTrue(ConfigurationUtils.isAMap(HashMap.class)); + assertFalse(ConfigurationUtils.isAMap(ArrayList.class)); + } + + @Test + public void testIsACollection() { + assertTrue(ConfigurationUtils.isACollection(ArrayList.class)); + assertFalse(ConfigurationUtils.isACollection(HashMap.class)); + } + + @Test + public void testIsAPrimitiveOrWrapper() { + assertTrue(ConfigurationUtils.isAPrimitiveOrWrapper(int.class)); + assertTrue(ConfigurationUtils.isAPrimitiveOrWrapper(Integer.class)); + assertFalse(ConfigurationUtils.isAPrimitiveOrWrapper(HashMap.class)); + } + + @Test + public void testIsAPrimitivesArray() { + assertTrue(ConfigurationUtils.isAPrimitivesArray(int[].class)); + assertFalse(ConfigurationUtils.isAPrimitivesArray(Integer[].class)); + assertFalse(ConfigurationUtils.isAPrimitivesArray(HashMap[].class)); + } + + @Test + public void testIsAWrapperArray() { + assertTrue(ConfigurationUtils.isAWrappersArray(Integer[].class)); + assertFalse(ConfigurationUtils.isAWrappersArray(int[].class)); + assertFalse(ConfigurationUtils.isAWrappersArray(HashMap[].class)); + } + + @Test + public void testIsAPrimitivesOrWrapperArray() { + assertTrue(ConfigurationUtils.isAPrimitivesOrWrappersArray(int[].class)); + assertTrue(ConfigurationUtils.isAPrimitivesOrWrappersArray(Integer[].class)); + assertFalse(ConfigurationUtils.isAPrimitivesOrWrappersArray(HashMap[].class)); + } + private ConfigurationRepository populateTestBaseConfig() { BaseConfiguration inputConfig = new PropertiesConfiguration(); inputConfig.setProperty(Constants.NAMESPACE_KEY, TEST_NAME_SPACE); @@ -220,8 +311,8 @@ public class ConfigurationUtilsTest { private ConfigurationRepository populateTestCompositeConfig() { CompositeConfiguration inputCompositeConfig = new CompositeConfiguration(); - Configuration inputConfig1= new BaseConfiguration(); - Configuration inputConfig2= new BaseConfiguration(); + Configuration inputConfig1 = new BaseConfiguration(); + Configuration inputConfig2 = new BaseConfiguration(); inputConfig1.setProperty(Constants.NAMESPACE_KEY, TEST_NAME_SPACE); inputCompositeConfig.addConfiguration(inputConfig1); inputCompositeConfig.addConfigurationFirst(inputConfig2); |