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 LOG = LoggerFactory.getLogger(OnapCommandSchemaMerger.class);
38 public static Map<String, ?> mergeSchemas(OnapCommand cmd) throws OnapCommandException {
39 Map<String, Object> mergedResult = new LinkedHashMap<String, Object>();
41 for (String schema: cmd.getSchemas()) {
42 Map<String , Object> schemaMap = (Map<String, Object>) OnapCommandSchemaLoader.validateSchemaVersion(schema, cmd.getSchemaVersion());
43 mergeYamlMap(mergedResult, schemaMap);
50 public static void mergeYamlMap(Map<String, Object> mergedResult, Map<String, Object> yamlContents) {
51 if (yamlContents == null) return;
53 for (String key : yamlContents.keySet()) {
55 Object yamlValue = yamlContents.get(key);
56 if (yamlValue == null) {
57 mergedResult.put(key, yamlValue);
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);
69 throw unknownValueType(key, yamlValue);
71 } else if (yamlValue instanceof List) {
72 mergeYamlLists(mergedResult, key, yamlValue);
74 } else if (yamlValue instanceof String
75 || yamlValue instanceof Boolean
76 || yamlValue instanceof Double
77 || yamlValue instanceof Integer) {
78 mergedResult.put(key, yamlValue);
81 throw unknownValueType(key, yamlValue);
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);
93 throw unknownValueType(key, yamlValue);
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);
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);
110 List<Object> originalList = (List<Object>) mergedResult.get(key);
112 for (Object o: (List<Object>) yamlValue) {
113 Map<String, Object> oN = (Map) o;
114 String nameN = (String)oN.getOrDefault(OnapCommandConstants.NAME, null);
116 //Name should be existing in the map, otherwise continue as don't know how to compare
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);
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());