2 * Copyright © 2016-2018 European Support Limited
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package org.onap.config;
19 import static java.util.Optional.ofNullable;
20 import static org.onap.config.api.Hint.EXTERNAL_LOOKUP;
21 import static org.onap.config.api.Hint.LATEST_LOOKUP;
22 import static org.onap.config.api.Hint.NODE_SPECIFIC;
24 import com.virtlink.commons.configuration2.jackson.JsonConfiguration;
26 import java.lang.reflect.Field;
27 import java.lang.reflect.ParameterizedType;
28 import java.lang.reflect.Type;
30 import java.nio.file.Files;
31 import java.nio.file.Path;
32 import java.util.ArrayDeque;
33 import java.util.ArrayList;
34 import java.util.Arrays;
35 import java.util.Collection;
36 import java.util.Collections;
37 import java.util.Deque;
38 import java.util.HashMap;
39 import java.util.HashSet;
40 import java.util.Iterator;
41 import java.util.LinkedHashMap;
42 import java.util.List;
44 import java.util.Optional;
45 import java.util.Queue;
47 import java.util.SortedSet;
48 import java.util.TreeSet;
49 import java.util.concurrent.BlockingQueue;
50 import java.util.concurrent.ConcurrentLinkedQueue;
51 import java.util.concurrent.Executors;
52 import java.util.concurrent.LinkedBlockingQueue;
53 import java.util.concurrent.LinkedTransferQueue;
54 import java.util.concurrent.ThreadFactory;
55 import java.util.concurrent.TransferQueue;
56 import java.util.regex.Matcher;
57 import java.util.regex.Pattern;
58 import java.util.stream.Collectors;
59 import java.util.stream.Stream;
60 import net.sf.corn.cps.CPScanner;
61 import net.sf.corn.cps.ResourceFilter;
62 import org.apache.commons.configuration2.CompositeConfiguration;
63 import org.apache.commons.configuration2.Configuration;
64 import org.apache.commons.configuration2.FileBasedConfiguration;
65 import org.apache.commons.configuration2.PropertiesConfiguration;
66 import org.apache.commons.configuration2.XMLConfiguration;
67 import org.apache.commons.configuration2.builder.BasicConfigurationBuilder;
68 import org.apache.commons.configuration2.builder.ReloadingFileBasedConfigurationBuilder;
69 import org.apache.commons.configuration2.builder.fluent.Configurations;
70 import org.apache.commons.configuration2.builder.fluent.Parameters;
71 import org.apache.commons.configuration2.convert.DefaultListDelimiterHandler;
72 import org.apache.commons.configuration2.ex.ConfigurationException;
73 import org.apache.commons.io.IOUtils;
74 import org.onap.config.api.Config;
75 import org.onap.config.api.ConfigurationManager;
76 import org.onap.config.impl.AgglomerateConfiguration;
77 import org.onap.config.impl.ConfigurationRepository;
78 import org.onap.config.impl.YamlConfiguration;
79 import org.onap.config.type.ConfigurationMode;
80 import org.onap.config.type.ConfigurationType;
81 import org.slf4j.Logger;
82 import org.slf4j.LoggerFactory;
85 * The type Configuration utils.
87 public class ConfigurationUtils {
88 private static final Logger LOGGER = LoggerFactory.getLogger(ConfigurationUtils.class);
89 private static final String CONFIGURATION_TYPE_NOT_SUPPORTED = "Configuration type not supported:";
91 private ConfigurationUtils() {
94 private static final Map<Class, Class> ARRAY_CLASS_MAP;
97 Map<Class, Class> arrayTypes = new HashMap<>();
98 arrayTypes.put(Byte.class, Byte[].class);
99 arrayTypes.put(Short.class, Short[].class);
100 arrayTypes.put(Integer.class, Integer[].class);
101 arrayTypes.put(Long.class, Long[].class);
102 arrayTypes.put(Float.class, Float[].class);
103 arrayTypes.put(Double.class, Double[].class);
104 arrayTypes.put(Boolean.class, Boolean[].class);
105 arrayTypes.put(Character.class, Character[].class);
106 arrayTypes.put(String.class, String[].class);
107 ARRAY_CLASS_MAP = Collections.unmodifiableMap(arrayTypes);
111 * Gets thread factory.
113 * @return the thread factory
115 public static ThreadFactory getThreadFactory() {
117 Thread thread = Executors.privilegedThreadFactory().newThread(r1);
118 thread.setDaemon(true);
126 * @param file the file
127 * @param recursive the recursive
128 * @param onlyDirectory the only directory
129 * @return the all files
131 public static Collection<File> getAllFiles(File file, boolean recursive, boolean onlyDirectory) {
132 ArrayList<File> collection = new ArrayList<>();
133 if (file.isDirectory() && file.exists()) {
134 File[] files = file.listFiles();
135 for (File innerFile : files) {
136 if (innerFile.isFile() && !onlyDirectory) {
137 collection.add(innerFile);
138 } else if (innerFile.isDirectory()) {
139 collection.add(innerFile);
141 collection.addAll(getAllFiles(innerFile, recursive, onlyDirectory));
150 * Gets comma saperated list.
152 * @param list the list
153 * @return the comma separated list
155 public static String getCommaSeparatedList(List list) {
156 return ((Stream<String>) list.stream().filter(o -> o != null && !o.toString().trim().isEmpty()).map(o -> o.toString().trim())).collect(Collectors.joining(","));
160 * Gets comma saperated list.
162 * @param list the list
163 * @return the comma saperated list
165 public static String getCommaSeparatedList(String[] list) {
166 return getCommaSeparatedList(list == null ? Arrays.asList() : Arrays.asList(list));
173 * @return the config type
175 public static ConfigurationType getConfigType(URL url) {
176 return Enum.valueOf(ConfigurationType.class,
177 url.getFile().substring(url.getFile().lastIndexOf('.') + 1).toUpperCase());
183 * @param file the file
184 * @return the config type
186 public static ConfigurationType getConfigType(File file) {
187 return Enum.valueOf(ConfigurationType.class,
188 file.getAbsolutePath().substring(file.getAbsolutePath().lastIndexOf('.') + 1)
196 * @return the boolean
198 public static boolean isConfig(URL url) {
199 return isConfig(url.getFile());
205 * @param file the file
206 * @return the boolean
208 public static boolean isConfig(File file) {
209 return file != null && file.exists() && isConfig(file.getName());
215 * @param file the file
216 * @return the boolean
218 public static boolean isConfig(String file) {
219 file = file.toUpperCase().substring(file.lastIndexOf('!') + 1);
220 file = file.substring(file.lastIndexOf('/') + 1);
222 "CONFIG(-\\w*){0,1}(-" + "(" + ConfigurationMode.OVERRIDE + "|" + ConfigurationMode.MERGE
223 + "|" + ConfigurationMode.UNION + ")){0,1}" + "\\.("
224 + ConfigurationType.PROPERTIES.name() + "|" + ConfigurationType.XML.name() + "|"
225 + ConfigurationType.JSON.name() + "|" + ConfigurationType.YAML.name() + ")$")
226 || file.matches("CONFIG(.)*\\.(" + ConfigurationType.PROPERTIES.name() + "|"
227 + ConfigurationType.XML.name() + "|" + ConfigurationType.JSON.name() + "|"
228 + ConfigurationType.YAML.name() + ")$");
235 * @return the namespace
237 public static String getNamespace(URL url) {
239 Optional<String> namespace = getConfiguration(url).flatMap(ConfigurationUtils::getNamespace).map(String::toUpperCase);
241 return namespace.orElseGet(() -> getNamespace(url.getFile().toUpperCase()));
247 * @param file the file
248 * @return the namespace
250 public static String getNamespace(File file) {
251 Optional<String> namespace = getConfiguration(file)
252 .flatMap(ConfigurationUtils::getNamespace)
253 .map(String::toUpperCase);
254 return namespace.orElseGet(() -> getNamespace(file.getName().toUpperCase()));
257 private static Optional<String> getNamespace(Configuration config) {
258 return ofNullable(config)
259 .flatMap(configuration -> ofNullable(configuration.getString(Constants.NAMESPACE_KEY)))
260 .map(String::toUpperCase);
266 * @param file the file
267 * @return the namespace
269 public static String getNamespace(String file) {
270 file = file.toUpperCase().substring(file.lastIndexOf('!') + 1);
271 file = file.substring(file.lastIndexOf('/') + 1);
272 Pattern pattern = Pattern.compile(
273 "CONFIG(-\\w*){0,1}(-" + "(" + ConfigurationMode.OVERRIDE + "|" + ConfigurationMode.MERGE
274 + "|" + ConfigurationMode.UNION + ")){0,1}" + "\\.("
275 + ConfigurationType.PROPERTIES.name() + "|" + ConfigurationType.XML.name() + "|"
276 + ConfigurationType.JSON.name() + "|" + ConfigurationType.YAML.name() + ")$");
277 Matcher matcher = pattern.matcher(file);
278 boolean b1 = matcher.matches();
280 if (matcher.group(1) != null) {
281 String moduleName = matcher.group(1).substring(1);
282 return moduleName.equalsIgnoreCase(ConfigurationMode.OVERRIDE.name())
283 || moduleName.equalsIgnoreCase(ConfigurationMode.UNION.name())
284 || moduleName.equalsIgnoreCase(ConfigurationMode.MERGE.name())
285 ? Constants.DEFAULT_NAMESPACE : moduleName;
287 return Constants.DEFAULT_NAMESPACE;
289 } else if (isConfig(file)) {
290 return Constants.DEFAULT_NAMESPACE;
297 * Gets merge strategy.
300 * @return the merge strategy
302 public static ConfigurationMode getMergeStrategy(URL url) {
303 Optional<ConfigurationMode> configurationMode = getConfiguration(url).flatMap(ConfigurationUtils::getMergeStrategy).flatMap(ConfigurationUtils::convertConfigurationMode);
304 return configurationMode.orElseGet(() -> getMergeStrategy(url.getFile().toUpperCase()));
307 private static Optional<ConfigurationMode> convertConfigurationMode(String configMode) {
308 ConfigurationMode configurationMode = null;
310 configurationMode = ConfigurationMode.valueOf(configMode);
311 } catch (Exception exception) {
312 LOGGER.error("Could not find convert {} into configuration mode", configMode);
314 return Optional.ofNullable(configurationMode);
317 private static Optional<String> getMergeStrategy(Configuration config) {
318 return ofNullable(config)
319 .flatMap(configuration -> ofNullable(configuration.getString(Constants.MODE_KEY)))
320 .map(String::toUpperCase);
325 * Gets merge strategy.
327 * @param file the file
328 * @return the merge strategy
330 public static ConfigurationMode getMergeStrategy(File file) {
331 Optional<ConfigurationMode> configurationMode = getConfiguration(file).flatMap(ConfigurationUtils::getMergeStrategy).flatMap(ConfigurationUtils::convertConfigurationMode);
332 return configurationMode.orElseGet(() -> getMergeStrategy(file.getName().toUpperCase()));
336 * Gets merge strategy.
338 * @param file the file
339 * @return the merge strategy
341 public static ConfigurationMode getMergeStrategy(String file) {
342 file = file.toUpperCase().substring(file.lastIndexOf('!') + 1);
343 file = file.substring(file.lastIndexOf('/') + 1);
344 Pattern pattern = Pattern.compile(
345 "CONFIG(-\\w*){0,1}(-" + "(" + ConfigurationMode.OVERRIDE + "|" + ConfigurationMode.MERGE
346 + "|" + ConfigurationMode.UNION + ")){0,1}" + "\\.("
347 + ConfigurationType.PROPERTIES.name() + "|" + ConfigurationType.XML.name() + "|"
348 + ConfigurationType.JSON.name() + "|" + ConfigurationType.YAML.name() + ")$");
349 Matcher matcher = pattern.matcher(file);
350 boolean b1 = matcher.matches();
352 for (int i = 1; i <= matcher.groupCount(); i++) {
353 String modeName = matcher.group(i);
354 if (modeName != null) {
355 modeName = modeName.substring(1);
358 return Enum.valueOf(ConfigurationMode.class, modeName);
359 } catch (Exception exception) {
369 * Gets configuration.
372 * @return the configuration
374 public static Optional<FileBasedConfiguration> getConfiguration(URL url) {
375 FileBasedConfiguration builder = null;
377 ConfigurationType configType = ConfigurationUtils.getConfigType(url);
378 switch (configType) {
380 builder = new Configurations().fileBased(PropertiesConfiguration.class, url);
383 builder = new Configurations().fileBased(XMLConfiguration.class, url);
386 builder = new Configurations().fileBased(JsonConfiguration.class, url);
389 builder = new Configurations().fileBased(YamlConfiguration.class, url);
392 throw new ConfigurationException(CONFIGURATION_TYPE_NOT_SUPPORTED + configType);
394 } catch (ConfigurationException exception) {
395 exception.printStackTrace();
397 return ofNullable(builder);
401 * Gets configuration.
403 * @param file the file
404 * @return the configuration
406 public static Optional<FileBasedConfiguration> getConfiguration(File file) {
407 FileBasedConfiguration builder = null;
409 ConfigurationType configType = ConfigurationUtils.getConfigType(file);
410 switch (configType) {
412 builder = new Configurations().fileBased(PropertiesConfiguration.class, file);
415 builder = new Configurations().fileBased(XMLConfiguration.class, file);
418 builder = new Configurations().fileBased(JsonConfiguration.class, file);
421 builder = new Configurations().fileBased(YamlConfiguration.class, file);
424 throw new ConfigurationException(CONFIGURATION_TYPE_NOT_SUPPORTED + configType);
426 } catch (ConfigurationException exception) {
427 exception.printStackTrace();
429 return ofNullable(builder);
433 * Gets collection generic type.
435 * @param field the field
436 * @return the collection generic type
438 public static Class getCollectionGenericType(Field field) {
439 Type type = field.getGenericType();
441 if (type instanceof ParameterizedType) {
443 ParameterizedType paramType = (ParameterizedType) type;
444 Type[] arr = paramType.getActualTypeArguments();
446 for (Type tp : arr) {
447 Class<?> clzz = (Class<?>) tp;
448 if (isWrapperClass(clzz)) {
451 throw new RuntimeException("Collection of type " + clzz.getName() + " not supported.");
455 return String[].class;
462 * @param clazz the clazz
463 * @return the array class
465 public static Class getArrayClass(Class clazz) {
466 return ARRAY_CLASS_MAP.getOrDefault(clazz, null);
470 * Gets all class path resources.
472 * @return the all class path resources
474 public static List<URL> getAllClassPathResources() {
475 return CPScanner.scanResources(new ResourceFilter());
479 * Gets configuration builder.
482 * @return the configuration builder
484 public static BasicConfigurationBuilder<FileBasedConfiguration> getConfigurationBuilder(URL url) {
485 ConfigurationType configType = ConfigurationUtils.getConfigType(url);
486 ReloadingFileBasedConfigurationBuilder<FileBasedConfiguration> builder = getFileBasedConfigurationReloadingFileBasedConfigurationBuilder(
488 builder.configure(new Parameters().fileBased().setURL(url)
489 .setListDelimiterHandler(new DefaultListDelimiterHandler(',')));
494 * Gets configuration builder.
496 * @param file the file
497 * @param autoSave the auto save
498 * @return the configuration builder
500 public static BasicConfigurationBuilder<FileBasedConfiguration> getConfigurationBuilder(File file,
502 ReloadingFileBasedConfigurationBuilder<FileBasedConfiguration> builder;
503 ConfigurationType configType = ConfigurationUtils.getConfigType(file);
504 builder = getFileBasedConfigurationReloadingFileBasedConfigurationBuilder(configType);
505 builder.configure(new Parameters().fileBased().setFile(file)
506 .setListDelimiterHandler(new DefaultListDelimiterHandler(',')));
507 builder.setAutoSave(autoSave);
511 private static ReloadingFileBasedConfigurationBuilder<FileBasedConfiguration> getFileBasedConfigurationReloadingFileBasedConfigurationBuilder(
512 ConfigurationType configType) {
513 ReloadingFileBasedConfigurationBuilder<FileBasedConfiguration> builder;
514 switch (configType) {
516 builder = new ReloadingFileBasedConfigurationBuilder<>(PropertiesConfiguration.class);
519 builder = new ReloadingFileBasedConfigurationBuilder<>(XMLConfiguration.class);
522 builder = new ReloadingFileBasedConfigurationBuilder<>(JsonConfiguration.class);
525 builder = new ReloadingFileBasedConfigurationBuilder<>(YamlConfiguration.class);
528 throw new IllegalArgumentException(CONFIGURATION_TYPE_NOT_SUPPORTED + configType);
536 * @param <T> the type parameter
537 * @param config the config
538 * @param clazz the clazz
539 * @param keyPrefix the key prefix
541 * @throws Exception the exception
543 public static <T> T read(Configuration config, Class<T> clazz, String keyPrefix)
546 clazz.getAnnotation(Config.class);
547 if (confAnnot != null) {
548 keyPrefix += (confAnnot.key() + ".");
550 T objToReturn = clazz.newInstance();
551 for (Field field : clazz.getDeclaredFields()) {
552 Config fieldConfAnnot =
553 field.getAnnotation(Config.class);
554 if (fieldConfAnnot != null) {
555 field.setAccessible(true);
556 field.set(objToReturn, config.getProperty(keyPrefix + fieldConfAnnot.key()));
557 } else if (field.getType().getAnnotation(Config.class) != null) {
558 field.set(objToReturn, read(config, field.getType(), keyPrefix));
567 * @param config the config
569 * @param processingHints the processing hints
570 * @return the property
572 public static Object getProperty(Configuration config, String key, int processingHints) {
573 if (!isDirectLookup(processingHints)) {
574 if (config instanceof AgglomerateConfiguration) {
575 return ((AgglomerateConfiguration) config).getPropertyValue(key);
576 } else if (config instanceof CompositeConfiguration) {
577 CompositeConfiguration conf = (CompositeConfiguration) config;
578 for (int i = 0; i < conf.getNumberOfConfigurations(); i++) {
579 if (conf.getConfiguration(i) instanceof AgglomerateConfiguration) {
580 return ((AgglomerateConfiguration) conf.getConfiguration(i)).getPropertyValue(key);
581 } else if (isNodeSpecific(processingHints)) {
582 Object obj = conf.getConfiguration(i).getProperty(key);
590 return config.getProperty(key);
594 * Gets primitive array.
596 * @param collection the collection
597 * @param clazz the clazz
598 * @return the primitive array
600 public static Object getPrimitiveArray(Collection collection, Class clazz) {
601 if (clazz == int.class) {
602 int[] array = new int[collection.size()];
603 Object[] objArray = collection.toArray();
604 for (int i = 0; i < collection.size(); i++) {
605 array[i] = (int) objArray[i];
609 if (clazz == byte.class) {
610 byte[] array = new byte[collection.size()];
611 Object[] objArray = collection.toArray();
612 for (int i = 0; i < collection.size(); i++) {
613 array[i] = (byte) objArray[i];
617 if (clazz == short.class) {
618 short[] array = new short[collection.size()];
619 Object[] objArray = collection.toArray();
620 for (int i = 0; i < collection.size(); i++) {
621 array[i] = (short) objArray[i];
625 if (clazz == long.class) {
626 long[] array = new long[collection.size()];
627 Object[] objArray = collection.toArray();
628 for (int i = 0; i < collection.size(); i++) {
629 array[i] = (long) objArray[i];
633 if (clazz == float.class) {
634 float[] array = new float[collection.size()];
635 Object[] objArray = collection.toArray();
636 for (int i = 0; i < collection.size(); i++) {
637 array[i] = (float) objArray[i];
641 if (clazz == double.class) {
642 double[] array = new double[collection.size()];
643 Object[] objArray = collection.toArray();
644 for (int i = 0; i < collection.size(); i++) {
645 array[i] = (double) objArray[i];
649 if (clazz == boolean.class) {
650 boolean[] array = new boolean[collection.size()];
651 Object[] objArray = collection.toArray();
652 for (int i = 0; i < collection.size(); i++) {
653 array[i] = (boolean) objArray[i];
661 * Is wrapper class boolean.
663 * @param clazz the clazz
664 * @return the boolean
666 public static boolean isWrapperClass(Class clazz) {
667 return clazz == String.class || clazz == Boolean.class || clazz == Character.class
668 || Number.class.isAssignableFrom(clazz);
672 * Gets collection string.
674 * @param input the input
675 * @return the collection string
677 public static String getCollectionString(String input) {
678 Pattern pattern = Pattern.compile("^\\[(.*)\\]$");
679 Matcher matcher = pattern.matcher(input);
680 if (matcher.matches()) {
681 input = matcher.group(1);
687 * Is collection boolean.
689 * @param input the input
690 * @return the boolean
692 public static boolean isCollection(String input) {
693 Pattern pattern = Pattern.compile("^\\[(.*)\\]$");
694 Matcher matcher = pattern.matcher(input);
695 return matcher.matches();
699 * Process variables if present string.
701 * @param tenant the tenant
702 * @param namespace the namespace
703 * @param data the data
706 public static String processVariablesIfPresent(String tenant, String namespace, String data) {
707 Pattern pattern = Pattern.compile("^.*\\$\\{(.*)\\}.*");
708 Matcher matcher = pattern.matcher(data);
709 if (matcher.matches()) {
710 String key = matcher.group(1);
711 if (key.toUpperCase().startsWith("ENV:")) {
712 String envValue = System.getenv(key.substring(4));
713 return processVariablesIfPresent(tenant, namespace, data.replaceAll("\\$\\{" + key + "\\}",
714 envValue == null ? "" : envValue.replace("\\", "\\\\")));
715 } else if (key.toUpperCase().startsWith("SYS:")) {
716 String sysValue = System.getProperty(key.substring(4));
717 return processVariablesIfPresent(tenant, namespace, data.replaceAll("\\$\\{" + key + "\\}",
718 sysValue == null ? "" : sysValue.replace("\\", "\\\\")));
720 String propertyValue = ConfigurationUtils.getCollectionString(
721 ConfigurationManager.lookup().getAsStringValues(tenant, namespace, key).toString());
722 return processVariablesIfPresent(tenant, namespace, data.replaceAll("\\$\\{" + key + "\\}",
723 propertyValue == null ? "" : propertyValue.replace("\\", "\\\\")));
731 * Gets file contents.
733 * @param path the path
734 * @return the file contents
736 public static String getFileContents(String path) {
739 return IOUtils.toString(new URL(path));
741 } catch (Exception exception) {
742 exception.printStackTrace();
748 * Gets file contents.
750 * @param path the path
751 * @return the file contents
753 public static String getFileContents(Path path) {
756 return new String(Files.readAllBytes(path));
758 } catch (Exception exception) {
759 exception.printStackTrace();
765 * Gets concrete collection.
767 * @param clazz the clazz
768 * @return the concrete collection
770 public static Collection getConcreteCollection(Class clazz) {
771 switch (clazz.getName()) {
772 case "java.util.Collection":
773 case "java.util.List":
774 return new ArrayList<>();
775 case "java.util.Set":
776 return new HashSet<>();
777 case "java.util.SortedSet":
778 return new TreeSet<>();
779 case "java.util.Queue":
780 return new ConcurrentLinkedQueue<>();
781 case "java.util.Deque":
782 return new ArrayDeque<>();
783 case "java.util.concurrent.TransferQueue":
784 return new LinkedTransferQueue<>();
785 case "java.util.concurrent.BlockingQueue":
786 return new LinkedBlockingQueue<>();
795 * @param clazz the clazz
796 * @return the default for
798 public static Object getDefaultFor(Class clazz) {
799 if (byte.class == clazz) {
800 return new Byte("0");
801 } else if (short.class == clazz) {
802 return new Short("0");
803 } else if (int.class == clazz) {
804 return new Integer("0");
805 } else if (float.class == clazz) {
806 return new Float("0");
807 } else if (long.class == clazz) {
808 return new Long("0");
809 } else if (double.class == clazz) {
810 return new Double("0");
811 } else if (boolean.class == clazz) {
812 return Boolean.FALSE;
818 * Gets compatible collection for abstract def.
820 * @param clazz the clazz
821 * @return the compatible collection for abstract def
823 public static Collection getCompatibleCollectionForAbstractDef(Class clazz) {
824 if (BlockingQueue.class.isAssignableFrom(clazz)) {
825 return getConcreteCollection(BlockingQueue.class);
827 if (TransferQueue.class.isAssignableFrom(clazz)) {
828 return getConcreteCollection(TransferQueue.class);
830 if (Deque.class.isAssignableFrom(clazz)) {
831 return getConcreteCollection(Deque.class);
833 if (Queue.class.isAssignableFrom(clazz)) {
834 return getConcreteCollection(Queue.class);
836 if (SortedSet.class.isAssignableFrom(clazz)) {
837 return getConcreteCollection(SortedSet.class);
839 if (Set.class.isAssignableFrom(clazz)) {
840 return getConcreteCollection(Set.class);
842 if (List.class.isAssignableFrom(clazz)) {
843 return getConcreteCollection(List.class);
849 * Gets configuration repository key.
851 * @param array the array
852 * @return the configuration repository key
854 public static String getConfigurationRepositoryKey(String[] array) {
855 Deque<String> stack = new ArrayDeque<>();
856 stack.push(Constants.DEFAULT_TENANT);
857 for (String element : array) {
860 String toReturn = stack.pop();
861 return stack.pop() + Constants.KEY_ELEMENTS_DELEMETER + toReturn;
865 * Gets configuration repository key.
867 * @param file the file
868 * @return the configuration repository key
870 public static String getConfigurationRepositoryKey(File file) {
871 return getConfigurationRepositoryKey(
872 ConfigurationUtils.getNamespace(file).split(Constants.TENANT_NAMESPACE_SAPERATOR));
876 * Gets configuration repository key.
879 * @return the configuration repository key
881 public static String getConfigurationRepositoryKey(URL url) {
882 return getConfigurationRepositoryKey(
883 ConfigurationUtils.getNamespace(url).split(Constants.TENANT_NAMESPACE_SAPERATOR));
887 * To map linked hash map.
889 * @param config the config
890 * @return the linked hash map
892 public static LinkedHashMap toMap(Configuration config) {
893 Iterator<String> iterator = config.getKeys();
894 LinkedHashMap<String, String> map = new LinkedHashMap<>();
895 while (iterator.hasNext()) {
896 String key = iterator.next();
897 if (!(key.equals(Constants.MODE_KEY) || key.equals(Constants.NAMESPACE_KEY)
898 || key.equals(Constants.LOAD_ORDER_KEY))) {
899 map.put(key, config.getProperty(key).toString());
909 * @param orig the orig
910 * @param latest the latest
913 public static Map diff(LinkedHashMap orig, LinkedHashMap latest) {
914 orig = new LinkedHashMap<>(orig);
915 latest = new LinkedHashMap<>(latest);
916 List<String> set = new ArrayList(orig.keySet());
917 for (String key : set) {
918 if (latest.remove(key, orig.get(key))) {
922 Set<String> keys = latest.keySet();
923 for (String key : keys) {
926 set = new ArrayList(orig.keySet());
927 for (String key : set) {
930 return new HashMap<>(latest);
936 * @param tenant the tenant
937 * @param namespace the namespace
939 * @param processingHints the processing hints
940 * @return the boolean
941 * @throws Exception the exception
943 public static boolean isArray(String tenant, String namespace, String key, int processingHints)
945 Object obj = ConfigurationUtils
946 .getProperty(ConfigurationRepository.lookup().getConfigurationFor(tenant, namespace), key,
948 return (obj != null) && ConfigurationUtils.isCollection(obj.toString());
952 * Is direct lookup boolean.
954 * @param hints the hints
955 * @return the boolean
957 public static boolean isDirectLookup(int hints) {
958 return (hints & LATEST_LOOKUP.value()) == LATEST_LOOKUP.value();
962 * Is external lookup boolean.
964 * @param hints the hints
965 * @return the boolean
967 public static boolean isExternalLookup(int hints) {
968 return (hints & EXTERNAL_LOOKUP.value()) == EXTERNAL_LOOKUP.value();
972 * Is node specific boolean.
974 * @param hints the hints
975 * @return the boolean
977 public static boolean isNodeSpecific(int hints) {
978 return (hints & NODE_SPECIFIC.value()) == NODE_SPECIFIC.value();
981 public static boolean isZeroLengthArray(Class clazz, Object obj) {
982 if (clazz.isArray() && clazz.getComponentType().isPrimitive()) {
983 if (clazz.getComponentType() == int.class) {
984 return ((int[]) obj).length == 0;
985 } else if (clazz.getComponentType() == byte.class) {
986 return ((byte[]) obj).length == 0;
987 } else if (clazz.getComponentType() == short.class) {
988 return ((short[]) obj).length == 0;
989 } else if (clazz.getComponentType() == float.class) {
990 return ((float[]) obj).length == 0;
991 } else if (clazz.getComponentType() == boolean.class) {
992 return ((boolean[]) obj).length == 0;
993 } else if (clazz.getComponentType() == double.class) {
994 return ((double[]) obj).length == 0;
995 } else if (clazz.getComponentType() == long.class) {
996 return ((long[]) obj).length == 0;
998 return ((Object[]) obj).length == 0;
1006 * Checks if value is blank
1011 public static boolean isBlank(String value) {
1012 return value == null || value.trim().length() == 0;