80fbaf8fd0bc185d742cf37fb6bb594c71ff8766
[sdc.git] / common / onap-common-configuration-management / onap-configuration-management-core / src / main / java / org / onap / config / impl / AggregateConfiguration.java
1 /*
2  * Copyright © 2016-2018 European Support Limited
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 package org.onap.config.impl;
18
19 import static org.onap.config.Constants.LOAD_ORDER_KEY;
20
21 import java.io.File;
22 import java.net.URL;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.HashMap;
26 import java.util.LinkedHashMap;
27 import java.util.Map;
28 import org.apache.commons.configuration2.CombinedConfiguration;
29 import org.apache.commons.configuration2.Configuration;
30 import org.apache.commons.configuration2.tree.MergeCombiner;
31 import org.apache.commons.configuration2.tree.OverrideCombiner;
32 import org.apache.commons.configuration2.tree.UnionCombiner;
33 import org.onap.config.ConfigurationUtils;
34 import org.onap.config.type.ConfigurationMode;
35
36 public final class AggregateConfiguration {
37
38     private final Map<String, Configuration> rootConfig = new HashMap<>();
39     private final Map<String, Configuration> unionConfig = new HashMap<>();
40     private final Map<String, Configuration> mergeConfig = new HashMap<>();
41     private final Map<String, Configuration> overrideConfig = new LinkedHashMap<>();
42
43     public AggregateConfiguration() {
44
45         try {
46             Class clazz = Class.forName(Thread.currentThread().getStackTrace()[2].getClassName());
47             if (!clazz.getCanonicalName().equals(ConfigurationImpl.class.getCanonicalName())) {
48                 throw new RuntimeException("Illegal access.");
49             }
50         } catch (ClassNotFoundException cfe) {
51             throw new RuntimeException("Class not found while loading change notifier");
52         }
53     }
54
55     public void addConfig(File file) throws Exception {
56         addConfig(file.getAbsolutePath().toUpperCase(), ConfigurationUtils.getMergeStrategy(file),
57                 ConfigurationUtils.getConfigurationBuilder(file, false).getConfiguration());
58     }
59
60     private void addConfig(String path, ConfigurationMode configMode, Configuration config) {
61         if (configMode != null) {
62             switch (configMode) {
63                 case MERGE:
64                     mergeConfig.put(path, config);
65                     break;
66                 case OVERRIDE:
67                     overrideConfig.put(path, config);
68                     break;
69                 case UNION:
70                     unionConfig.put(path, config);
71                     break;
72                 default:
73             }
74         } else {
75             rootConfig.put(path, config);
76         }
77     }
78
79     public void addConfig(URL url) throws Exception {
80         addConfig(url.getFile().toUpperCase(), ConfigurationUtils.getMergeStrategy(url),
81                 ConfigurationUtils.getConfigurationBuilder(url).getConfiguration());
82     }
83
84     public void removeConfig(File file) {
85         String key = file.getAbsolutePath().toUpperCase();
86         if (rootConfig.containsKey(key)) {
87             rootConfig.remove(key);
88         } else if (mergeConfig.containsKey(key)) {
89             mergeConfig.remove(key);
90         } else if (unionConfig.containsKey(key)) {
91             unionConfig.remove(key);
92         } else if (overrideConfig.containsKey(key)) {
93             overrideConfig.remove(key);
94         }
95     }
96
97     public boolean containsConfig(File file) {
98         String key = file.getAbsolutePath().toUpperCase();
99         return rootConfig.containsKey(key) || mergeConfig.containsKey(key) || unionConfig.containsKey(key)
100                        || overrideConfig.containsKey(key);
101     }
102
103     public Configuration getFinalConfiguration() {
104         CombinedConfiguration ccRoot = new CombinedConfiguration(new MergeCombiner());
105         ArrayList<Configuration> tempList = new ArrayList<>(rootConfig.values());
106         tempList.sort(this::sortForMerge);
107         for (Configuration conf : tempList) {
108             ccRoot.addConfiguration(conf);
109         }
110         CombinedConfiguration ccMergeRoot = new CombinedConfiguration(new MergeCombiner());
111         ccMergeRoot.addConfiguration(ccRoot);
112         tempList = new ArrayList<>(mergeConfig.values());
113         tempList.sort(this::sortForMerge);
114         for (Configuration conf : tempList) {
115             ccMergeRoot.addConfiguration(conf);
116         }
117         CombinedConfiguration ccUnionRoot = new CombinedConfiguration(new UnionCombiner());
118         ccUnionRoot.addConfiguration(ccMergeRoot);
119         for (Configuration conf : unionConfig.values()) {
120             ccUnionRoot.addConfiguration(conf);
121         }
122         ArrayList<Configuration> tempOverrideConfigs = new ArrayList<>(overrideConfig.values());
123         Collections.reverse(tempOverrideConfigs);
124         tempOverrideConfigs.sort(this::sortForOverride);
125         CombinedConfiguration ccOverrideRoot = new CombinedConfiguration(new OverrideCombiner());
126         for (Configuration conf : tempOverrideConfigs) {
127             ccOverrideRoot.addConfiguration(conf);
128         }
129         ccOverrideRoot.addConfiguration(ccUnionRoot);
130         return ccOverrideRoot;
131     }
132
133     private int sortForOverride(Configuration conf1, Configuration conf2) {
134         String order1 = conf1.getString(LOAD_ORDER_KEY);
135         String order2 = conf2.getString(LOAD_ORDER_KEY);
136         if (ConfigurationUtils.isBlank(order1) || !order1.trim().matches("\\d+")) {
137             order1 = "0";
138         }
139         if (ConfigurationUtils.isBlank(order2) || !order2.trim().matches("\\d+")) {
140             order2 = "0";
141         }
142         return Integer.parseInt(order2.trim()) - Integer.parseInt(order1.trim());
143     }
144
145     private int sortForMerge(Configuration conf1, Configuration conf2) {
146         String order1 = conf1.getString(LOAD_ORDER_KEY);
147         String order2 = conf2.getString(LOAD_ORDER_KEY);
148         if (ConfigurationUtils.isBlank(order1) || !order1.trim().matches("\\d+")) {
149             order1 = "0";
150         }
151         if (ConfigurationUtils.isBlank(order2) || !order2.trim().matches("\\d+")) {
152             order2 = "0";
153         }
154         return Integer.parseInt(order1.trim()) - Integer.parseInt(order2.trim());
155     }
156 }