2 * Copyright © 2016-2017 European Support Limited
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.sdc.tosca.services;
19 import java.util.List;
20 import java.util.Optional;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
23 import org.yaml.snakeyaml.DumperOptions;
24 import org.yaml.snakeyaml.TypeDescription;
25 import org.yaml.snakeyaml.Yaml;
26 import org.yaml.snakeyaml.constructor.Constructor;
27 import org.yaml.snakeyaml.introspector.BeanAccess;
28 import org.yaml.snakeyaml.introspector.Property;
29 import org.yaml.snakeyaml.introspector.PropertyUtils;
30 import org.yaml.snakeyaml.nodes.MappingNode;
31 import org.yaml.snakeyaml.nodes.NodeTuple;
32 import org.yaml.snakeyaml.nodes.Tag;
33 import org.yaml.snakeyaml.parser.ParserException;
34 import org.yaml.snakeyaml.representer.Representer;
37 import java.beans.IntrospectionException;
38 import java.io.IOException;
39 import java.io.InputStream;
40 import java.util.AbstractMap;
41 import java.util.LinkedHashMap;
42 import java.util.LinkedHashSet;
49 @SuppressWarnings("unchecked")
50 public class YamlUtil {
51 private static final Logger LOGGER = LoggerFactory.getLogger(YamlUtil.class.getName());
53 private static final String DEFAULT = "default";
54 private static final String DEFAULT_STR = "_default";
59 * @param <T> the type parameter
60 * @param yamlContent the yaml content
61 * @param typClass the t class
64 public <T> T yamlToObject(String yamlContent, Class<T> typClass) {
65 Constructor constructor = getConstructor(typClass);
66 constructor.setPropertyUtils(getPropertyUtils());
67 TypeDescription yamlFileDescription = new TypeDescription(typClass);
68 constructor.addTypeDescription(yamlFileDescription);
69 Yaml yaml = new Yaml(constructor);
70 T yamlObj = (T) yaml.load(yamlContent);
71 //noinspection ResultOfMethodCallIgnored
76 public InputStream loadYamlFileIs(String yamlFullFileName) {
77 return YamlUtil.class.getResourceAsStream(yamlFullFileName);
83 * @param <T> the type parameter
84 * @param yamlContent the yaml content
85 * @param typClass the t class
88 public <T> T yamlToObject(InputStream yamlContent, Class<T> typClass) {
90 Constructor constructor = getConstructor(typClass);
91 constructor.setPropertyUtils(getPropertyUtils());
92 TypeDescription yamlFileDescription = new TypeDescription(typClass);
93 constructor.addTypeDescription(yamlFileDescription);
94 Yaml yaml = new Yaml(constructor);
95 T yamlObj = (T) yaml.load(yamlContent);
96 if (yamlObj != null) {
97 //noinspection ResultOfMethodCallIgnored
101 throw new RuntimeException();
103 } catch (Exception exception) {
104 throw new RuntimeException(exception);
107 if (yamlContent != null) {
110 } catch (IOException ignore) {
120 * @param <T> the type parameter
121 * @param typClass the t class
122 * @return the constructor
124 public <T> Constructor getConstructor(Class<T> typClass) {
125 return new StrictMapAppenderConstructor(typClass);
129 * Gets property utils.
131 * @return the property utils
133 protected PropertyUtils getPropertyUtils() {
134 return new MyPropertyUtils();
141 * @param yamlContent the yaml content
144 public Map<String, LinkedHashMap<String, Object>> yamlToMap(InputStream yamlContent) {
145 Yaml yaml = new Yaml();
146 return (Map<String, LinkedHashMap<String, Object>>) yaml.load(yamlContent);
151 * Parse a YAML file to List
153 * @param yamlFileInputStream the YAML file input stream
154 * @return The YAML casted as a list
156 public static Optional<List<Object>> yamlToList(final InputStream yamlFileInputStream) {
157 List<Object> yamlList = null;
159 yamlList = (List<Object>) read(yamlFileInputStream);
160 } catch (final ClassCastException ex) {
161 if (LOGGER.isWarnEnabled()) {
162 LOGGER.warn("Could not parse YAML to List.", ex);
165 return Optional.ofNullable(yamlList);
169 * Parse a YAML file to Object
171 * @param yamlFileInputStream the YAML file input stream
172 * @return The YAML Object
174 public static Object read(final InputStream yamlFileInputStream) {
175 final Yaml yaml = new Yaml();
176 return yaml.load(yamlFileInputStream);
180 * Object to yaml string.
184 public String objectToYaml(Object obj) {
185 DumperOptions options = new DumperOptions();
186 options.setPrettyFlow(true);
187 options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
188 Representer representer = new CustomRepresenter();
189 representer.addClassTag(obj.getClass(), Tag.MAP);
190 representer.setPropertyUtils(new MyPropertyUtils());
192 Yaml yaml = new Yaml(representer, options);
193 return yaml.dump(obj);
197 * Is yaml file content valid boolean.
199 * @param yamlFullFileName the yaml full file name
200 * @return the boolean
202 public boolean isYamlFileContentValid(String yamlFullFileName) {
203 Yaml yaml = new Yaml();
205 Object loadResult = yaml.load(yamlFullFileName);
206 return loadResult != null;
207 } catch (Exception exception) {
213 private class CustomRepresenter extends Representer {
215 protected MappingNode representJavaBean(Set<Property> properties, Object javaBean) {
216 //remove the bean type from the output yaml (!! ...)
217 if (!classTags.containsKey(javaBean.getClass())) {
218 addClassTag(javaBean.getClass(), Tag.MAP);
221 return super.representJavaBean(properties, javaBean);
225 protected NodeTuple representJavaBeanProperty(Object javaBean, Property property,
226 Object propertyValue, Tag customTag) {
227 if (propertyValue == null) {
230 NodeTuple defaultNode =
231 super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
233 return DEFAULT_STR.equals(property.getName())
234 ? new NodeTuple(representData(DEFAULT), defaultNode.getValueNode())
242 * The type My property utils.
244 public class MyPropertyUtils extends PropertyUtils {
245 //Unsorted properties
247 protected Set<Property> createPropertySet(Class<? extends Object> type, BeanAccess bnAccess)
248 throws IntrospectionException {
249 return new LinkedHashSet<>(getPropertiesMap(type,
250 BeanAccess.FIELD).values());
254 public Property getProperty(Class<?> type, String name) throws IntrospectionException {
255 String updatedName = name;
256 if (DEFAULT.equals(updatedName)) {
257 updatedName = DEFAULT_STR;
259 return super.getProperty(type, updatedName);
265 * The type Strict map appender constructor.
267 protected class StrictMapAppenderConstructor extends Constructor {
270 * Instantiates a new Strict map appender constructor.
272 * @param theRoot the the root
274 public StrictMapAppenderConstructor(Class<?> theRoot) {
279 protected Map<Object, Object> createDefaultMap() {
280 final Map<Object, Object> delegate = super.createDefaultMap();
281 return new AbstractMap<Object, Object>() {
283 public Object put(Object key, Object value) {
284 if (delegate.containsKey(key)) {
285 throw new IllegalStateException("duplicate key: " + key);
287 return delegate.put(key, value);
291 public Set<Entry<Object, Object>> entrySet() {
292 return delegate.entrySet();
298 protected Map<Object, Object> constructMapping(MappingNode node) {
300 return super.constructMapping(node);
301 } catch (IllegalStateException exception) {
302 throw new ParserException("while parsing MappingNode",
303 node.getStartMark(), exception.getMessage(),