code improvements- incorporating comments
[cli.git] / framework / src / main / java / org / onap / cli / fw / schema / OnapCommandSchemaMerger.java
1 /*
2  * Copyright 2017 Huawei Technologies Co., Ltd.
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.cli.fw.schema;
18
19 import java.util.LinkedHashMap;
20 import java.util.List;
21 import java.util.Map;
22 import java.util.Map.Entry;
23
24 import org.onap.cli.fw.cmd.OnapCommand;
25 import org.onap.cli.fw.conf.OnapCommandConstants;
26 import org.onap.cli.fw.error.OnapCommandException;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
30 /**
31  * Helps to merge two yaml schemas
32  *
33  */
34 public class OnapCommandSchemaMerger {
35
36     static Logger LOG = LoggerFactory.getLogger(OnapCommandSchemaMerger.class);
37
38     public static Map<String, ?> mergeSchemas(OnapCommand cmd) throws OnapCommandException {
39         Map<String, Object> mergedResult = new LinkedHashMap<String, Object>();
40
41         for (String schema: cmd.getSchemas()) {
42             Map<String , Object> schemaMap = (Map<String, Object>) OnapCommandSchemaLoader.validateSchemaVersion(schema, cmd.getSchemaVersion());
43             mergeYamlMap(mergedResult, schemaMap);
44         }
45
46         return mergedResult;
47
48     }
49
50     public static void mergeYamlMap(Map<String, Object> mergedResult, Map<String, Object> yamlContents) {
51         if (yamlContents == null) return;
52
53         for (String key : yamlContents.keySet()) {
54
55             Object yamlValue = yamlContents.get(key);
56             if (yamlValue == null) {
57                 mergedResult.put(key, yamlValue);
58                 continue;
59             }
60
61             Object existingValue = mergedResult.get(key);
62             if (existingValue != null) {
63                 if (yamlValue instanceof Map) {
64                     if (existingValue instanceof Map) {
65                         mergeYamlMap((Map<String, Object>) existingValue, (Map<String, Object>)  yamlValue);
66                     } else if (existingValue instanceof String) {
67                         throw new IllegalArgumentException("Cannot merge complex element into a simple element: "+key);
68                     } else {
69                         throw unknownValueType(key, yamlValue);
70                     }
71                 } else if (yamlValue instanceof List) {
72                     mergeYamlLists(mergedResult, key, yamlValue);
73
74                 } else if (yamlValue instanceof String
75                         || yamlValue instanceof Boolean
76                         || yamlValue instanceof Double
77                         || yamlValue instanceof Integer) {
78                     mergedResult.put(key, yamlValue);
79
80                 } else {
81                     throw unknownValueType(key, yamlValue);
82                 }
83
84             } else {
85                 if (yamlValue instanceof Map
86                         || yamlValue instanceof List
87                         || yamlValue instanceof String
88                         || yamlValue instanceof Boolean
89                         || yamlValue instanceof Integer
90                         || yamlValue instanceof Double) {
91                     mergedResult.put(key, yamlValue);
92                 } else {
93                     throw unknownValueType(key, yamlValue);
94                 }
95             }
96         }
97     }
98
99     private static IllegalArgumentException unknownValueType(String key, Object yamlValue) {
100         final String msg = "Cannot merge element of unknown type: " + key + ": " + yamlValue.getClass().getName();
101         return new IllegalArgumentException(msg);
102     }
103
104     @SuppressWarnings("unchecked")
105     private static void mergeYamlLists(Map<String, Object> mergedResult, String key, Object yamlValue) {
106         if (! (yamlValue instanceof List && mergedResult.get(key) instanceof List)) {
107             throw new IllegalArgumentException("Cannot merge a list with a non-list: "+key);
108         }
109
110         List<Object> originalList = (List<Object>) mergedResult.get(key);
111
112         for (Object o: (List<Object>) yamlValue) {
113             Map<String, Object> oN = (Map) o;
114             String nameN = (String)oN.getOrDefault(OnapCommandConstants.NAME, null);
115
116             //Name should be existing in the map, otherwise continue as don't know how to compare
117             if (nameN != null) {
118
119                 boolean existing = false;
120                 for (Object e: originalList) {
121                     Map<String, Object> oE = (Map) e;
122                     String nameE = (String)oE.getOrDefault(OnapCommandConstants.NAME, null);
123
124                     //Name should be existing in the map, otherwise continue as don't know how to compare
125                     if (nameN.equals(nameE)) {
126                         for (Entry<String, Object> oNe : oN.entrySet()) {
127                                oE.put(oNe.getKey(), oNe.getValue());
128                         }
129                         existing = true;
130                         break;
131                     }
132                 }
133
134                 if (!existing) {
135                     originalList.add(o);
136                 }
137             }
138         }
139     }
140 }
141