2 * Copyright 2017 Huawei Technologies Co., Ltd.
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.cli.fw.schema;
19 import java.util.LinkedHashMap;
20 import java.util.List;
22 import java.util.Map.Entry;
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;
31 * Helps to merge two yaml schemas
34 public class OnapCommandSchemaMerger {
36 static Logger logger = LoggerFactory.getLogger(OnapCommandSchemaMerger.class);
38 private OnapCommandSchemaMerger(){
39 //It is made private in order to resolve: Utility classes should not have public constructors
42 public static Map<String, Object> mergeSchemas(OnapCommand cmd) throws OnapCommandException {
43 Map<String, Object> mergedResult = new LinkedHashMap<>();
45 for (String schema: cmd.getSchemas()) {
46 Map<String , Object> schemaMap = OnapCommandSchemaLoader.validateSchemaVersion(schema, cmd.getSchemaVersion());
47 mergeYamlMap(mergedResult, schemaMap);
54 public static void mergeWithExistingValue(Object yamlValue, Object existingValue, String key, Map<String, Object> mergedResult){
55 if (yamlValue instanceof Map) {
56 if (existingValue instanceof Map) {
57 mergeYamlMap((Map<String, Object>) existingValue, (Map<String, Object>) yamlValue);
58 } else if (existingValue instanceof String) {
59 throw new IllegalArgumentException("Cannot merge complex element into a simple element: "+key);
61 throw unknownValueType(key, yamlValue);
63 } else if (yamlValue instanceof List) {
64 mergeYamlLists(mergedResult, key, yamlValue);
66 } else if (yamlValue instanceof String
67 || yamlValue instanceof Boolean
68 || yamlValue instanceof Double
69 || yamlValue instanceof Integer) {
70 mergedResult.put(key, yamlValue);
73 throw unknownValueType(key, yamlValue);
77 public static void mergeYamlMap(Map<String, Object> mergedResult, Map<String, Object> yamlContents) {
78 if (yamlContents == null) return;
80 for (Map.Entry<String,Object> entry : yamlContents.entrySet()) {
82 String key = entry.getKey();
83 Object yamlValue = entry.getValue();
84 if (yamlValue == null) {
85 mergedResult.put(key, yamlValue);
89 Object existingValue = mergedResult.get(key);
90 if (existingValue != null) {
91 mergeWithExistingValue(yamlValue, existingValue, key, mergedResult);
93 if (yamlValue instanceof Map
94 || yamlValue instanceof List
95 || yamlValue instanceof String
96 || yamlValue instanceof Boolean
97 || yamlValue instanceof Integer
98 || yamlValue instanceof Double) {
99 mergedResult.put(key, yamlValue);
101 throw unknownValueType(key, yamlValue);
107 private static IllegalArgumentException unknownValueType(String key, Object yamlValue) {
108 final String msg = "Cannot merge element of unknown type: " + key + ": " + yamlValue.getClass().getName();
109 return new IllegalArgumentException(msg);
112 private static void compareWithExistingNames(String nameN, List<Object> originalList, Map<String, Object> oN, Object o){
115 boolean existing = false;
116 for (Object e: originalList) {
117 Map<String, Object> oE = (Map) e;
118 String nameE = (String)oE.getOrDefault(OnapCommandConstants.NAME, null);
120 //Name should be existing in the map, otherwise continue as don't know how to compare
121 if (nameN.equals(nameE)) {
122 for (Entry<String, Object> oNe : oN.entrySet()) {
123 oE.put(oNe.getKey(), oNe.getValue());
136 @SuppressWarnings("unchecked")
137 private static void mergeYamlLists(Map<String, Object> mergedResult, String key, Object yamlValue) {
138 if (! (yamlValue instanceof List && mergedResult.get(key) instanceof List)) {
139 throw new IllegalArgumentException("Cannot merge a list with a non-list: "+key);
142 List<Object> originalList = (List<Object>) mergedResult.get(key);
144 for (Object o: (List<Object>) yamlValue) {
145 Map<String, Object> oN = (Map) o;
146 String nameN = (String)oN.getOrDefault(OnapCommandConstants.NAME, null);
148 //Name should be existing in the map, otherwise continue as don't know how to compare
149 compareWithExistingNames(nameN, originalList, oN, o);