1 package org.onap.config;
3 import com.google.common.collect.ImmutableMap;
4 import com.virtlink.commons.configuration2.jackson.JsonConfiguration;
5 import net.sf.corn.cps.CPScanner;
6 import net.sf.corn.cps.ResourceFilter;
7 import org.apache.commons.configuration2.CompositeConfiguration;
8 import org.apache.commons.configuration2.Configuration;
9 import org.apache.commons.configuration2.FileBasedConfiguration;
10 import org.apache.commons.configuration2.PropertiesConfiguration;
11 import org.apache.commons.configuration2.XMLConfiguration;
12 import org.apache.commons.configuration2.builder.BasicConfigurationBuilder;
13 import org.apache.commons.configuration2.builder.ReloadingFileBasedConfigurationBuilder;
14 import org.apache.commons.configuration2.builder.fluent.Configurations;
15 import org.apache.commons.configuration2.builder.fluent.Parameters;
16 import org.apache.commons.configuration2.convert.DefaultListDelimiterHandler;
17 import org.apache.commons.configuration2.ex.ConfigurationException;
18 import org.apache.commons.io.IOUtils;
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
21 import org.onap.config.api.Config;
22 import org.onap.config.api.ConfigurationManager;
23 import org.onap.config.impl.ConfigurationRepository;
24 import org.onap.config.impl.YamlConfiguration;
25 import org.onap.config.impl.AgglomerateConfiguration;
26 import org.onap.config.impl.ConfigurationDataSource;
27 import org.onap.config.type.ConfigurationMode;
28 import org.onap.config.type.ConfigurationType;
30 import javax.sql.DataSource;
32 import java.lang.reflect.Field;
33 import java.lang.reflect.ParameterizedType;
34 import java.lang.reflect.Type;
36 import java.nio.file.Files;
37 import java.nio.file.Path;
38 import java.sql.Connection;
39 import java.sql.PreparedStatement;
40 import java.sql.ResultSet;
41 import java.sql.Statement;
42 import java.util.ArrayDeque;
43 import java.util.ArrayList;
44 import java.util.Arrays;
45 import java.util.Collection;
46 import java.util.Deque;
47 import java.util.HashMap;
48 import java.util.HashSet;
49 import java.util.Iterator;
50 import java.util.LinkedHashMap;
51 import java.util.List;
53 import java.util.Optional;
54 import java.util.Queue;
56 import java.util.SortedSet;
57 import java.util.TreeSet;
58 import java.util.concurrent.BlockingQueue;
59 import java.util.concurrent.ConcurrentLinkedQueue;
60 import java.util.concurrent.Executors;
61 import java.util.concurrent.LinkedBlockingQueue;
62 import java.util.concurrent.LinkedTransferQueue;
63 import java.util.concurrent.ThreadFactory;
64 import java.util.concurrent.TransferQueue;
65 import java.util.regex.Matcher;
66 import java.util.regex.Pattern;
67 import java.util.stream.Collectors;
68 import java.util.stream.Stream;
70 import java.util.concurrent.Executors;
71 import java.util.concurrent.ThreadFactory;
72 import java.util.stream.Collectors;
73 import java.util.stream.Stream;
75 import static com.google.common.collect.ImmutableMap.builder;
77 import static java.util.Optional.ofNullable;
78 import static org.onap.config.api.Hint.EXTERNAL_LOOKUP;
79 import static org.onap.config.api.Hint.LATEST_LOOKUP;
80 import static org.onap.config.api.Hint.NODE_SPECIFIC;
83 import static com.google.common.collect.ImmutableMap.builder;
84 import static org.onap.config.api.Hint.*;
87 * The type Configuration utils.
89 public class ConfigurationUtils {
90 private static final Logger LOGGER = LoggerFactory.getLogger(ConfigurationUtils.class);
92 private ConfigurationUtils() {
95 private static ImmutableMap<Class, Class> arrayClassMap;
98 ImmutableMap.Builder<Class, Class> builder = builder();
99 builder.put(Byte.class, Byte[].class).put(Short.class, Short[].class)
100 .put(Integer.class, Integer[].class).put(Long.class, Long[].class)
101 .put(Float.class, Float[].class).put(Double.class, Double[].class)
102 .put(Boolean.class, Boolean[].class).put(Character.class, Character[].class)
103 .put(String.class, String[].class);
104 arrayClassMap = builder.build();
108 * Gets thread factory.
110 * @return the thread factory
112 public static ThreadFactory getThreadFactory() {
114 Thread thread = Executors.privilegedThreadFactory().newThread(r1);
115 thread.setDaemon(true);
123 * @param file the file
124 * @param recursive the recursive
125 * @param onlyDirectory the only directory
126 * @return the all files
128 public static Collection<File> getAllFiles(File file, boolean recursive, boolean onlyDirectory) {
129 ArrayList<File> collection = new ArrayList<>();
130 if (file.isDirectory() && file.exists()) {
131 File[] files = file.listFiles();
132 for (File innerFile : files) {
133 if (innerFile.isFile() && !onlyDirectory) {
134 collection.add(innerFile);
135 } else if (innerFile.isDirectory()) {
136 collection.add(innerFile);
138 collection.addAll(getAllFiles(innerFile, recursive, onlyDirectory));
147 * Gets comma saperated list.
149 * @param list the list
150 * @return the comma separated list
152 public static String getCommaSeparatedList(List list) {
153 return ((Stream<String>) list.stream().filter(o -> o != null && !o.toString().trim().isEmpty()).map(o -> o.toString().trim())).collect(Collectors.joining(","));
157 * Gets comma saperated list.
159 * @param list the list
160 * @return the comma saperated list
162 public static String getCommaSeparatedList(String[] list) {
163 return getCommaSeparatedList(list == null ? Arrays.asList() : Arrays.asList(list));
170 * @return the config type
172 public static ConfigurationType getConfigType(URL url) {
173 return Enum.valueOf(ConfigurationType.class,
174 url.getFile().substring(url.getFile().lastIndexOf('.') + 1).toUpperCase());
180 * @param file the file
181 * @return the config type
183 public static ConfigurationType getConfigType(File file) {
184 return Enum.valueOf(ConfigurationType.class,
185 file.getAbsolutePath().substring(file.getAbsolutePath().lastIndexOf('.') + 1)
193 * @return the boolean
195 public static boolean isConfig(URL url) {
196 return isConfig(url.getFile());
202 * @param file the file
203 * @return the boolean
205 public static boolean isConfig(File file) {
206 return file != null && file.exists() && isConfig(file.getName());
212 * @param file the file
213 * @return the boolean
215 public static boolean isConfig(String file) {
216 file = file.toUpperCase().substring(file.lastIndexOf('!') + 1);
217 file = file.substring(file.lastIndexOf('/') + 1);
219 "CONFIG(-\\w*){0,1}(-" + "(" + ConfigurationMode.OVERRIDE + "|" + ConfigurationMode.MERGE
220 + "|" + ConfigurationMode.UNION + ")){0,1}" + "\\.("
221 + ConfigurationType.PROPERTIES.name() + "|" + ConfigurationType.XML.name() + "|"
222 + ConfigurationType.JSON.name() + "|" + ConfigurationType.YAML.name() + ")$")
223 || file.matches("CONFIG(.)*\\.(" + ConfigurationType.PROPERTIES.name() + "|"
224 + ConfigurationType.XML.name() + "|" + ConfigurationType.JSON.name() + "|"
225 + ConfigurationType.YAML.name() + ")$");
232 * @return the namespace
234 public static String getNamespace(URL url) {
236 Optional<String> namespace = getConfiguration(url).flatMap(ConfigurationUtils::getNamespace).map(String::toUpperCase);
238 return namespace.orElseGet(() -> getNamespace(url.getFile().toUpperCase()));
244 * @param file the file
245 * @return the namespace
247 public static String getNamespace(File file) {
248 Optional<String> namespace = getConfiguration(file)
249 .flatMap(ConfigurationUtils::getNamespace)
250 .map(String::toUpperCase);
251 return namespace.orElseGet(() -> getNamespace(file.getName().toUpperCase()));
254 private static Optional<String> getNamespace(Configuration config) {
255 return ofNullable(config)
256 .flatMap(configuration -> ofNullable(configuration.getString(Constants.NAMESPACE_KEY)))
257 .map(String::toUpperCase);
263 * @param file the file
264 * @return the namespace
266 public static String getNamespace(String file) {
267 file = file.toUpperCase().substring(file.lastIndexOf('!') + 1);
268 file = file.substring(file.lastIndexOf('/') + 1);
269 Pattern pattern = Pattern.compile(
270 "CONFIG(-\\w*){0,1}(-" + "(" + ConfigurationMode.OVERRIDE + "|" + ConfigurationMode.MERGE
271 + "|" + ConfigurationMode.UNION + ")){0,1}" + "\\.("
272 + ConfigurationType.PROPERTIES.name() + "|" + ConfigurationType.XML.name() + "|"
273 + ConfigurationType.JSON.name() + "|" + ConfigurationType.YAML.name() + ")$");
274 Matcher matcher = pattern.matcher(file);
275 boolean b1 = matcher.matches();
277 if (matcher.group(1) != null) {
278 String moduleName = matcher.group(1).substring(1);
279 return moduleName.equalsIgnoreCase(ConfigurationMode.OVERRIDE.name())
280 || moduleName.equalsIgnoreCase(ConfigurationMode.UNION.name())
281 || moduleName.equalsIgnoreCase(ConfigurationMode.MERGE.name())
282 ? Constants.DEFAULT_NAMESPACE : moduleName;
284 return Constants.DEFAULT_NAMESPACE;
286 } else if (isConfig(file)) {
287 return Constants.DEFAULT_NAMESPACE;
294 * Gets merge strategy.
297 * @return the merge strategy
299 public static ConfigurationMode getMergeStrategy(URL url) {
300 Optional<ConfigurationMode> configurationMode = getConfiguration(url).flatMap(ConfigurationUtils::getMergeStrategy).flatMap(ConfigurationUtils::convertConfigurationMode);
301 return configurationMode.orElseGet(() -> getMergeStrategy(url.getFile().toUpperCase()));
304 private static Optional<ConfigurationMode> convertConfigurationMode(String configMode) {
305 ConfigurationMode configurationMode = null;
307 configurationMode = ConfigurationMode.valueOf(configMode);
308 } catch (Exception exception) {
309 LOGGER.error("Could not find convert {} into configuration mode", configMode);
311 return Optional.ofNullable(configurationMode);
314 private static Optional<String> getMergeStrategy(Configuration config) {
315 return ofNullable(config)
316 .flatMap(configuration -> ofNullable(configuration.getString(Constants.MODE_KEY)))
317 .map(String::toUpperCase);
322 * Gets merge strategy.
324 * @param file the file
325 * @return the merge strategy
327 public static ConfigurationMode getMergeStrategy(File file) {
328 Optional<ConfigurationMode> configurationMode = getConfiguration(file).flatMap(ConfigurationUtils::getMergeStrategy).flatMap(ConfigurationUtils::convertConfigurationMode);
329 return configurationMode.orElseGet(() -> getMergeStrategy(file.getName().toUpperCase()));
333 * Gets merge strategy.
335 * @param file the file
336 * @return the merge strategy
338 public static ConfigurationMode getMergeStrategy(String file) {
339 file = file.toUpperCase().substring(file.lastIndexOf('!') + 1);
340 file = file.substring(file.lastIndexOf('/') + 1);
341 Pattern pattern = Pattern.compile(
342 "CONFIG(-\\w*){0,1}(-" + "(" + ConfigurationMode.OVERRIDE + "|" + ConfigurationMode.MERGE
343 + "|" + ConfigurationMode.UNION + ")){0,1}" + "\\.("
344 + ConfigurationType.PROPERTIES.name() + "|" + ConfigurationType.XML.name() + "|"
345 + ConfigurationType.JSON.name() + "|" + ConfigurationType.YAML.name() + ")$");
346 Matcher matcher = pattern.matcher(file);
347 boolean b1 = matcher.matches();
349 for (int i = 1; i <= matcher.groupCount(); i++) {
350 String modeName = matcher.group(i);
351 if (modeName != null) {
352 modeName = modeName.substring(1);
355 return Enum.valueOf(ConfigurationMode.class, modeName);
356 } catch (Exception exception) {
366 * Gets configuration.
369 * @return the configuration
371 public static Optional<FileBasedConfiguration> getConfiguration(URL url) {
372 FileBasedConfiguration builder = null;
374 ConfigurationType configType = ConfigurationUtils.getConfigType(url);
375 switch (configType) {
377 builder = new Configurations().fileBased(PropertiesConfiguration.class, url);
380 builder = new Configurations().fileBased(XMLConfiguration.class, url);
383 builder = new Configurations().fileBased(JsonConfiguration.class, url);
386 builder = new Configurations().fileBased(YamlConfiguration.class, url);
389 throw new ConfigurationException("Configuration type not supported:" + configType);
391 } catch (ConfigurationException exception) {
392 exception.printStackTrace();
394 return ofNullable(builder);
398 * Gets configuration.
400 * @param file the file
401 * @return the configuration
403 public static Optional<FileBasedConfiguration> getConfiguration(File file) {
404 FileBasedConfiguration builder = null;
406 ConfigurationType configType = ConfigurationUtils.getConfigType(file);
407 switch (configType) {
409 builder = new Configurations().fileBased(PropertiesConfiguration.class, file);
412 builder = new Configurations().fileBased(XMLConfiguration.class, file);
415 builder = new Configurations().fileBased(JsonConfiguration.class, file);
418 builder = new Configurations().fileBased(YamlConfiguration.class, file);
421 throw new ConfigurationException("Configuration type not supported:" + configType);
423 } catch (ConfigurationException exception) {
424 exception.printStackTrace();
426 return ofNullable(builder);
430 * Gets collection generic type.
432 * @param field the field
433 * @return the collection generic type
435 public static Class getCollectionGenericType(Field field) {
436 Type type = field.getGenericType();
438 if (type instanceof ParameterizedType) {
440 ParameterizedType paramType = (ParameterizedType) type;
441 Type[] arr = paramType.getActualTypeArguments();
443 for (Type tp : arr) {
444 Class<?> clzz = (Class<?>) tp;
445 if (isWrapperClass(clzz)) {
448 throw new RuntimeException("Collection of type " + clzz.getName() + " not supported.");
452 return String[].class;
459 * @param clazz the clazz
460 * @return the array class
462 public static Class getArrayClass(Class clazz) {
463 return arrayClassMap.getOrDefault(clazz, null);
467 * Gets all class path resources.
469 * @return the all class path resources
471 public static List<URL> getAllClassPathResources() {
472 return CPScanner.scanResources(new ResourceFilter());
476 * Execute ddlsql boolean.
479 * @return the boolean
480 * @throws Exception the exception
482 public static boolean executeDdlSql(String sql) throws Exception {
483 DataSource datasource = ConfigurationDataSource.lookup();
484 if (datasource == null) {
485 System.err.println("DB configuration not found. Configuration management will be using "
486 + "in-memory persistence.");
489 try (Connection con = datasource.getConnection(); Statement stmt = con.createStatement()) {
490 stmt.executeQuery(sql);
491 } catch (Exception exception) {
492 System.err.println("Datasource initialization error. Configuration management will be using in-memory persistence.");
499 * Gets configuration builder.
502 * @return the configuration builder
504 public static BasicConfigurationBuilder<FileBasedConfiguration> getConfigurationBuilder(URL url) {
505 ConfigurationType configType = ConfigurationUtils.getConfigType(url);
506 ReloadingFileBasedConfigurationBuilder<FileBasedConfiguration> builder = getFileBasedConfigurationReloadingFileBasedConfigurationBuilder(
508 builder.configure(new Parameters().fileBased().setURL(url)
509 .setListDelimiterHandler(new DefaultListDelimiterHandler(',')));
514 * Gets configuration builder.
516 * @param file the file
517 * @param autoSave the auto save
518 * @return the configuration builder
520 public static BasicConfigurationBuilder<FileBasedConfiguration> getConfigurationBuilder(File file,
522 ReloadingFileBasedConfigurationBuilder<FileBasedConfiguration> builder;
523 ConfigurationType configType = ConfigurationUtils.getConfigType(file);
524 builder = getFileBasedConfigurationReloadingFileBasedConfigurationBuilder(configType);
525 builder.configure(new Parameters().fileBased().setFile(file)
526 .setListDelimiterHandler(new DefaultListDelimiterHandler(',')));
527 builder.setAutoSave(autoSave);
531 private static ReloadingFileBasedConfigurationBuilder<FileBasedConfiguration> getFileBasedConfigurationReloadingFileBasedConfigurationBuilder(
532 ConfigurationType configType) {
533 ReloadingFileBasedConfigurationBuilder<FileBasedConfiguration> builder;
534 switch (configType) {
536 builder = new ReloadingFileBasedConfigurationBuilder<>(PropertiesConfiguration.class);
539 builder = new ReloadingFileBasedConfigurationBuilder<>(XMLConfiguration.class);
542 builder = new ReloadingFileBasedConfigurationBuilder<>(JsonConfiguration.class);
545 builder = new ReloadingFileBasedConfigurationBuilder<>(YamlConfiguration.class);
548 throw new IllegalArgumentException("Configuration type not supported:" + configType);
555 * Execute select sql collection.
558 * @param params the params
559 * @return the collection
560 * @throws Exception the exception
562 public static Collection<String> executeSelectSql(String sql, String[] params) throws Exception {
563 Collection<String> coll = new ArrayList<>();
564 DataSource datasource = ConfigurationDataSource.lookup();
565 try (Connection con = datasource.getConnection();
566 PreparedStatement stmt = con.prepareStatement(sql)) {
567 if (params != null) {
568 for (int i = 0; i < params.length; i++) {
569 stmt.setString(i + 1, params[i]);
573 try (ResultSet rs = stmt.executeQuery()) {
576 coll.add(rs.getString(1));
580 } catch (Exception exception) {
581 //exception.printStackTrace();
589 * Execute insert sql boolean.
592 * @param params the params
593 * @return the boolean
594 * @throws Exception the exception
596 public static boolean executeInsertSql(String sql, Object[] params) throws Exception {
597 DataSource datasource = ConfigurationDataSource.lookup();
598 try (Connection con = datasource.getConnection();
599 PreparedStatement stmt = con.prepareStatement(sql)) {
600 if (params != null) {
602 for (Object obj : params) {
606 switch (obj.getClass().getName()) {
607 case "java.lang.String":
608 stmt.setString(++counter, obj.toString());
610 case "java.lang.Integer":
611 stmt.setInt(++counter, ((Integer) obj).intValue());
613 case "java.lang.Long":
614 stmt.setLong(++counter, ((Long) obj).longValue());
617 stmt.setString(++counter, obj.toString());
622 stmt.executeUpdate();
624 } catch (Exception exception) {
625 exception.printStackTrace();
633 * @param <T> the type parameter
634 * @param config the config
635 * @param clazz the clazz
636 * @param keyPrefix the key prefix
638 * @throws Exception the exception
640 public static <T> T read(Configuration config, Class<T> clazz, String keyPrefix)
643 clazz.getAnnotation(Config.class);
644 if (confAnnot != null) {
645 keyPrefix += (confAnnot.key() + ".");
647 T objToReturn = clazz.newInstance();
648 for (Field field : clazz.getDeclaredFields()) {
649 Config fieldConfAnnot =
650 field.getAnnotation(Config.class);
651 if (fieldConfAnnot != null) {
652 field.setAccessible(true);
653 field.set(objToReturn, config.getProperty(keyPrefix + fieldConfAnnot.key()));
654 } else if (field.getType().getAnnotation(Config.class) != null) {
655 field.set(objToReturn, read(config, field.getType(), keyPrefix));
662 * Gets db configuration builder.
664 * @param configName the config name
665 * @return the db configuration builder
666 * @throws Exception the exception
668 public static BasicConfigurationBuilder<AgglomerateConfiguration> getDbConfigurationBuilder(
669 String configName) throws Exception {
670 Configuration dbConfig = ConfigurationRepository.lookup()
671 .getConfigurationFor(Constants.DEFAULT_TENANT, Constants.DB_NAMESPACE);
672 BasicConfigurationBuilder<AgglomerateConfiguration> builder =
673 new BasicConfigurationBuilder<AgglomerateConfiguration>(AgglomerateConfiguration.class);
675 new Parameters().database()
676 .setDataSource(ConfigurationDataSource.lookup())
677 .setTable(dbConfig.getString("config.Table"))
678 .setKeyColumn(dbConfig.getString("configKey"))
679 .setValueColumn(dbConfig.getString("configValue"))
680 .setConfigurationNameColumn(dbConfig.getString("configNameColumn"))
681 .setConfigurationName(configName)
690 * @param config the config
692 * @param processingHints the processing hints
693 * @return the property
695 public static Object getProperty(Configuration config, String key, int processingHints) {
696 if (!isDirectLookup(processingHints)) {
697 if (config instanceof AgglomerateConfiguration) {
698 return ((AgglomerateConfiguration) config).getPropertyValue(key);
699 } else if (config instanceof CompositeConfiguration) {
700 CompositeConfiguration conf = (CompositeConfiguration) config;
701 for (int i = 0; i < conf.getNumberOfConfigurations(); i++) {
702 if (conf.getConfiguration(i) instanceof AgglomerateConfiguration) {
703 return ((AgglomerateConfiguration) conf.getConfiguration(i)).getPropertyValue(key);
704 } else if (isNodeSpecific(processingHints)) {
705 Object obj = conf.getConfiguration(i).getProperty(key);
713 return config.getProperty(key);
717 * Gets primitive array.
719 * @param collection the collection
720 * @param clazz the clazz
721 * @return the primitive array
723 public static Object getPrimitiveArray(Collection collection, Class clazz) {
724 if (clazz == int.class) {
725 int[] array = new int[collection.size()];
726 Object[] objArray = collection.toArray();
727 for (int i = 0; i < collection.size(); i++) {
728 array[i] = (int) objArray[i];
732 if (clazz == byte.class) {
733 byte[] array = new byte[collection.size()];
734 Object[] objArray = collection.toArray();
735 for (int i = 0; i < collection.size(); i++) {
736 array[i] = (byte) objArray[i];
740 if (clazz == short.class) {
741 short[] array = new short[collection.size()];
742 Object[] objArray = collection.toArray();
743 for (int i = 0; i < collection.size(); i++) {
744 array[i] = (short) objArray[i];
748 if (clazz == long.class) {
749 long[] array = new long[collection.size()];
750 Object[] objArray = collection.toArray();
751 for (int i = 0; i < collection.size(); i++) {
752 array[i] = (long) objArray[i];
756 if (clazz == float.class) {
757 float[] array = new float[collection.size()];
758 Object[] objArray = collection.toArray();
759 for (int i = 0; i < collection.size(); i++) {
760 array[i] = (float) objArray[i];
764 if (clazz == double.class) {
765 double[] array = new double[collection.size()];
766 Object[] objArray = collection.toArray();
767 for (int i = 0; i < collection.size(); i++) {
768 array[i] = (double) objArray[i];
772 if (clazz == boolean.class) {
773 boolean[] array = new boolean[collection.size()];
774 Object[] objArray = collection.toArray();
775 for (int i = 0; i < collection.size(); i++) {
776 array[i] = (boolean) objArray[i];
785 * Is wrapper class boolean.
787 * @param clazz the clazz
788 * @return the boolean
790 public static boolean isWrapperClass(Class clazz) {
791 return clazz == String.class || clazz == Boolean.class || clazz == Character.class
792 || Number.class.isAssignableFrom(clazz);
796 * Gets collection string.
798 * @param input the input
799 * @return the collection string
801 public static String getCollectionString(String input) {
802 Pattern pattern = Pattern.compile("^\\[(.*)\\]$");
803 Matcher matcher = pattern.matcher(input);
804 if (matcher.matches()) {
805 input = matcher.group(1);
811 * Is collection boolean.
813 * @param input the input
814 * @return the boolean
816 public static boolean isCollection(String input) {
817 Pattern pattern = Pattern.compile("^\\[(.*)\\]$");
818 Matcher matcher = pattern.matcher(input);
819 return matcher.matches();
823 * Process variables if present string.
825 * @param tenant the tenant
826 * @param namespace the namespace
827 * @param data the data
830 public static String processVariablesIfPresent(String tenant, String namespace, String data) {
831 Pattern pattern = Pattern.compile("^.*\\$\\{(.*)\\}.*");
832 Matcher matcher = pattern.matcher(data);
833 if (matcher.matches()) {
834 String key = matcher.group(1);
835 if (key.toUpperCase().startsWith("ENV:")) {
836 String envValue = System.getenv(key.substring(4));
837 return processVariablesIfPresent(tenant, namespace, data.replaceAll("\\$\\{" + key + "\\}",
838 envValue == null ? "" : envValue.replace("\\", "\\\\")));
839 } else if (key.toUpperCase().startsWith("SYS:")) {
840 String sysValue = System.getProperty(key.substring(4));
841 return processVariablesIfPresent(tenant, namespace, data.replaceAll("\\$\\{" + key + "\\}",
842 sysValue == null ? "" : sysValue.replace("\\", "\\\\")));
844 String propertyValue = ConfigurationUtils.getCollectionString(
845 ConfigurationManager.lookup().getAsStringValues(tenant, namespace, key).toString());
846 return processVariablesIfPresent(tenant, namespace, data.replaceAll("\\$\\{" + key + "\\}",
847 propertyValue == null ? "" : propertyValue.replace("\\", "\\\\")));
855 * Gets file contents.
857 * @param path the path
858 * @return the file contents
860 public static String getFileContents(String path) {
863 return IOUtils.toString(new URL(path));
865 } catch (Exception exception) {
866 exception.printStackTrace();
872 * Gets file contents.
874 * @param path the path
875 * @return the file contents
877 public static String getFileContents(Path path) {
880 return new String(Files.readAllBytes(path));
882 } catch (Exception exception) {
883 exception.printStackTrace();
889 * Gets concrete collection.
891 * @param clazz the clazz
892 * @return the concrete collection
894 public static Collection getConcreteCollection(Class clazz) {
895 switch (clazz.getName()) {
896 case "java.util.Collection":
897 case "java.util.List":
898 return new ArrayList<>();
899 case "java.util.Set":
900 return new HashSet<>();
901 case "java.util.SortedSet":
902 return new TreeSet<>();
903 case "java.util.Queue":
904 return new ConcurrentLinkedQueue<>();
905 case "java.util.Deque":
906 return new ArrayDeque<>();
907 case "java.util.concurrent.TransferQueue":
908 return new LinkedTransferQueue<>();
909 case "java.util.concurrent.BlockingQueue":
910 return new LinkedBlockingQueue<>();
919 * @param clazz the clazz
920 * @return the default for
922 public static Object getDefaultFor(Class clazz) {
923 if (byte.class == clazz) {
924 return new Byte("0");
925 } else if (short.class == clazz) {
926 return new Short("0");
927 } else if (int.class == clazz) {
928 return new Integer("0");
929 } else if (float.class == clazz) {
930 return new Float("0");
931 } else if (long.class == clazz) {
932 return new Long("0");
933 } else if (double.class == clazz) {
934 return new Double("0");
935 } else if (boolean.class == clazz) {
936 return Boolean.FALSE;
942 * Gets compatible collection for abstract def.
944 * @param clazz the clazz
945 * @return the compatible collection for abstract def
947 public static Collection getCompatibleCollectionForAbstractDef(Class clazz) {
948 if (BlockingQueue.class.isAssignableFrom(clazz)) {
949 return getConcreteCollection(BlockingQueue.class);
951 if (TransferQueue.class.isAssignableFrom(clazz)) {
952 return getConcreteCollection(TransferQueue.class);
954 if (Deque.class.isAssignableFrom(clazz)) {
955 return getConcreteCollection(Deque.class);
957 if (Queue.class.isAssignableFrom(clazz)) {
958 return getConcreteCollection(Queue.class);
960 if (SortedSet.class.isAssignableFrom(clazz)) {
961 return getConcreteCollection(SortedSet.class);
963 if (Set.class.isAssignableFrom(clazz)) {
964 return getConcreteCollection(Set.class);
966 if (List.class.isAssignableFrom(clazz)) {
967 return getConcreteCollection(List.class);
973 * Gets configuration repository key.
975 * @param array the array
976 * @return the configuration repository key
978 public static String getConfigurationRepositoryKey(String[] array) {
979 Deque<String> stack = new ArrayDeque<>();
980 stack.push(Constants.DEFAULT_TENANT);
981 for (String element : array) {
984 String toReturn = stack.pop();
985 return stack.pop() + Constants.KEY_ELEMENTS_DELEMETER + toReturn;
989 * Gets configuration repository key.
991 * @param file the file
992 * @return the configuration repository key
994 public static String getConfigurationRepositoryKey(File file) {
995 return getConfigurationRepositoryKey(
996 ConfigurationUtils.getNamespace(file).split(Constants.TENANT_NAMESPACE_SAPERATOR));
1000 * Gets configuration repository key.
1002 * @param url the url
1003 * @return the configuration repository key
1005 public static String getConfigurationRepositoryKey(URL url) {
1006 return getConfigurationRepositoryKey(
1007 ConfigurationUtils.getNamespace(url).split(Constants.TENANT_NAMESPACE_SAPERATOR));
1011 * To map linked hash map.
1013 * @param config the config
1014 * @return the linked hash map
1016 public static LinkedHashMap toMap(Configuration config) {
1017 Iterator<String> iterator = config.getKeys();
1018 LinkedHashMap<String, String> map = new LinkedHashMap<>();
1019 while (iterator.hasNext()) {
1020 String key = iterator.next();
1021 if (!(key.equals(Constants.MODE_KEY) || key.equals(Constants.NAMESPACE_KEY)
1022 || key.equals(Constants.LOAD_ORDER_KEY))) {
1023 map.put(key, config.getProperty(key).toString());
1033 * @param orig the orig
1034 * @param latest the latest
1037 public static Map diff(LinkedHashMap orig, LinkedHashMap latest) {
1038 orig = new LinkedHashMap<>(orig);
1039 latest = new LinkedHashMap<>(latest);
1040 List<String> set = new ArrayList(orig.keySet());
1041 for (String key : set) {
1042 if (latest.remove(key, orig.get(key))) {
1046 Set<String> keys = latest.keySet();
1047 for (String key : keys) {
1050 set = new ArrayList(orig.keySet());
1051 for (String key : set) {
1052 latest.put(key, "");
1054 return new HashMap<>(latest);
1060 * @param tenant the tenant
1061 * @param namespace the namespace
1062 * @param key the key
1063 * @param processingHints the processing hints
1064 * @return the boolean
1065 * @throws Exception the exception
1067 public static boolean isArray(String tenant, String namespace, String key, int processingHints)
1069 Object obj = ConfigurationUtils
1070 .getProperty(ConfigurationRepository.lookup().getConfigurationFor(tenant, namespace), key,
1072 return (obj != null) && ConfigurationUtils.isCollection(obj.toString());
1076 * Is direct lookup boolean.
1078 * @param hints the hints
1079 * @return the boolean
1081 public static boolean isDirectLookup(int hints) {
1082 return (hints & LATEST_LOOKUP.value()) == LATEST_LOOKUP.value();
1086 * Is external lookup boolean.
1088 * @param hints the hints
1089 * @return the boolean
1091 public static boolean isExternalLookup(int hints) {
1092 return (hints & EXTERNAL_LOOKUP.value()) == EXTERNAL_LOOKUP.value();
1096 * Is node specific boolean.
1098 * @param hints the hints
1099 * @return the boolean
1101 public static boolean isNodeSpecific(int hints) {
1102 return (hints & NODE_SPECIFIC.value()) == NODE_SPECIFIC.value();
1105 public static boolean isZeroLengthArray(Class clazz, Object obj) {
1106 if (clazz.isArray() && clazz.getComponentType().isPrimitive()) {
1107 if (clazz.getComponentType() == int.class) {
1108 return ((int[]) obj).length == 0;
1109 } else if (clazz.getComponentType() == byte.class) {
1110 return ((byte[]) obj).length == 0;
1111 } else if (clazz.getComponentType() == short.class) {
1112 return ((short[]) obj).length == 0;
1113 } else if (clazz.getComponentType() == float.class) {
1114 return ((float[]) obj).length == 0;
1115 } else if (clazz.getComponentType() == boolean.class) {
1116 return ((boolean[]) obj).length == 0;
1117 } else if (clazz.getComponentType() == double.class) {
1118 return ((double[]) obj).length == 0;
1119 } else if (clazz.getComponentType() == long.class) {
1120 return ((long[]) obj).length == 0;
1122 return ((Object[]) obj).length == 0;
1130 * Checks if value is blank
1135 public static boolean isBlank(String value) {
1136 return value == null || value.trim().length() == 0;