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 (String key : yamlContents.keySet()) {
82 Object yamlValue = yamlContents.get(key);
83 if (yamlValue == null) {
84 mergedResult.put(key, yamlValue);
88 Object existingValue = mergedResult.get(key);
89 if (existingValue != null) {
90 mergeWithExistingValue(yamlValue, existingValue, key, mergedResult);
92 if (yamlValue instanceof Map
93 || yamlValue instanceof List
94 || yamlValue instanceof String
95 || yamlValue instanceof Boolean
96 || yamlValue instanceof Integer
97 || yamlValue instanceof Double) {
98 mergedResult.put(key, yamlValue);
100 throw unknownValueType(key, yamlValue);
106 private static IllegalArgumentException unknownValueType(String key, Object yamlValue) {
107 final String msg = "Cannot merge element of unknown type: " + key + ": " + yamlValue.getClass().getName();
108 return new IllegalArgumentException(msg);
111 private static void compareWithExistingNames(String nameN, List<Object> originalList, Map<String, Object> oN, Object o){
114 boolean existing = false;
115 for (Object e: originalList) {
116 Map<String, Object> oE = (Map) e;
117 String nameE = (String)oE.getOrDefault(OnapCommandConstants.NAME, null);
119 //Name should be existing in the map, otherwise continue as don't know how to compare
120 if (nameN.equals(nameE)) {
121 for (Entry<String, Object> oNe : oN.entrySet()) {
122 oE.put(oNe.getKey(), oNe.getValue());
135 @SuppressWarnings("unchecked")
136 private static void mergeYamlLists(Map<String, Object> mergedResult, String key, Object yamlValue) {
137 if (! (yamlValue instanceof List && mergedResult.get(key) instanceof List)) {
138 throw new IllegalArgumentException("Cannot merge a list with a non-list: "+key);
141 List<Object> originalList = (List<Object>) mergedResult.get(key);
143 for (Object o: (List<Object>) yamlValue) {
144 Map<String, Object> oN = (Map) o;
145 String nameN = (String)oN.getOrDefault(OnapCommandConstants.NAME, null);
147 //Name should be existing in the map, otherwise continue as don't know how to compare
148 compareWithExistingNames(nameN, originalList, oN, o);