Create plugin point for csar generation
[sdc.git] / common / onap-tosca-datatype / src / main / java / org / onap / sdc / tosca / services / YamlUtil.java
1 /*
2  * Copyright © 2016-2017 European Support Limited
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 package org.onap.sdc.tosca.services;
17
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.util.LinkedHashMap;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.Optional;
24 import java.util.Set;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27 import org.yaml.snakeyaml.DumperOptions;
28 import org.yaml.snakeyaml.LoaderOptions;
29 import org.yaml.snakeyaml.TypeDescription;
30 import org.yaml.snakeyaml.Yaml;
31 import org.yaml.snakeyaml.constructor.Constructor;
32 import org.yaml.snakeyaml.introspector.Property;
33 import org.yaml.snakeyaml.introspector.PropertyUtils;
34 import org.yaml.snakeyaml.nodes.MappingNode;
35 import org.yaml.snakeyaml.nodes.NodeTuple;
36 import org.yaml.snakeyaml.nodes.Tag;
37 import org.yaml.snakeyaml.representer.Representer;
38
39 /**
40  * The type Yaml util.
41  */
42 @SuppressWarnings("unchecked")
43 public class YamlUtil {
44
45     static final String DEFAULT = "default";
46     static final String DEFAULT_STR = "_default";
47     private static final Logger LOGGER = LoggerFactory.getLogger(YamlUtil.class.getName());
48
49     /**
50      * Parse a YAML file to List
51      *
52      * @param yamlFileInputStream the YAML file input stream
53      * @return The YAML casted as a list
54      */
55     public static Optional<List<Object>> yamlToList(final InputStream yamlFileInputStream) {
56         List<Object> yamlList = null;
57         try {
58             yamlList = (List<Object>) read(yamlFileInputStream);
59         } catch (final ClassCastException ex) {
60             if (LOGGER.isWarnEnabled()) {
61                 LOGGER.warn("Could not parse YAML to List.", ex);
62             }
63         }
64         return Optional.ofNullable(yamlList);
65     }
66
67     /**
68      * Parse a YAML file to Object
69      *
70      * @param yamlFileInputStream the YAML file input stream
71      * @return The YAML Object
72      */
73     public static Object read(final InputStream yamlFileInputStream) {
74         return new Yaml().load(yamlFileInputStream);
75     }
76
77     /**
78      * Yaml to object t.
79      *
80      * @param <T>         the type parameter
81      * @param yamlContent the yaml content
82      * @param typClass    the t class
83      * @return the t
84      */
85     public <T> T yamlToObject(String yamlContent, Class<T> typClass) {
86         Constructor constructor = getConstructor(typClass);
87         constructor.setPropertyUtils(getPropertyUtils());
88         TypeDescription yamlFileDescription = new TypeDescription(typClass);
89         constructor.addTypeDescription(yamlFileDescription);
90         T yamlObj = new Yaml(constructor, new Representer(new DumperOptions()), new DumperOptions(), getLoaderOptions()).load(yamlContent);
91
92         //noinspection ResultOfMethodCallIgnored
93         yamlObj.toString();
94         return yamlObj;
95     }
96
97     public InputStream loadYamlFileIs(String yamlFullFileName) {
98         return YamlUtil.class.getResourceAsStream(yamlFullFileName);
99     }
100
101     /**
102      * Yaml to object t.
103      *
104      * @param <T>         the type parameter
105      * @param yamlContent the yaml content
106      * @param typClass    the t class
107      * @return the t
108      */
109     public <T> T yamlToObject(InputStream yamlContent, Class<T> typClass) {
110         try {
111             Constructor constructor = getConstructor(typClass);
112             constructor.setAllowDuplicateKeys(false);
113             constructor.setPropertyUtils(getPropertyUtils());
114             TypeDescription yamlFileDescription = new TypeDescription(typClass);
115             constructor.addTypeDescription(yamlFileDescription);
116             //No Yaml Constructor takes only Constructor and LoaderOptions, that is why I had to pass anonymous Representer and DumperOptions objects
117             T yamlObj = new Yaml(constructor, new Representer(new DumperOptions()), new DumperOptions(), getLoaderOptions()).load(yamlContent);
118             if (yamlObj != null) {
119                 //noinspection ResultOfMethodCallIgnored
120                 yamlObj.toString();
121                 return yamlObj;
122             } else {
123                 throw new RuntimeException();
124             }
125         } catch (Exception exception) {
126             throw new RuntimeException(exception);
127         } finally {
128             try {
129                 if (yamlContent != null) {
130                     yamlContent.close();
131                 }
132             } catch (IOException ignore) {
133                 //do nothing
134             }
135         }
136     }
137
138     private LoaderOptions getLoaderOptions() {
139         LoaderOptions options = new LoaderOptions();
140         options.setAllowDuplicateKeys(false);
141         options.setMaxAliasesForCollections(9999);
142         return options;
143     }
144
145     /**
146      * Gets constructor.
147      *
148      * @param <T>      the type parameter
149      * @param typClass the t class
150      * @return the constructor
151      */
152     public <T> Constructor getConstructor(Class<T> typClass) {
153         return new StrictMapAppenderConstructor(typClass);
154     }
155
156     /**
157      * Gets property utils.
158      *
159      * @return the property utils
160      */
161     protected PropertyUtils getPropertyUtils() {
162         return new MyPropertyUtils();
163     }
164
165     /**
166      * Yaml to map map.
167      *
168      * @param yamlContent the yaml content
169      * @return the map
170      */
171     public Map<String, LinkedHashMap<String, Object>> yamlToMap(InputStream yamlContent) {
172         return new Yaml().load(yamlContent);
173     }
174
175     /**
176      * Object to yaml string.
177      *
178      * @param obj the obj
179      * @return the string
180      */
181     public String objectToYaml(Object obj) {
182         DumperOptions options = new DumperOptions();
183         options.setPrettyFlow(true);
184         options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
185         Representer representer = new CustomRepresenter();
186         representer.addClassTag(obj.getClass(), Tag.MAP);
187         representer.setPropertyUtils(new MyPropertyUtils());
188         Yaml yaml = new Yaml(representer, options);
189         return yaml.dump(obj);
190     }
191
192     /**
193      * Is yaml file content valid boolean.
194      *
195      * @param yamlFullFileName the yaml full file name
196      * @return the boolean
197      */
198     public boolean isYamlFileContentValid(String yamlFullFileName) {
199         try {
200             return new Yaml().load(yamlFullFileName) != null;
201         } catch (Exception exception) {
202             return false;
203         }
204     }
205
206     private class CustomRepresenter extends Representer {
207
208         @Override
209         protected MappingNode representJavaBean(Set<Property> properties, Object javaBean) {
210             //remove the bean type from the output yaml (!! ...)
211             if (!classTags.containsKey(javaBean.getClass())) {
212                 addClassTag(javaBean.getClass(), Tag.MAP);
213             }
214             return super.representJavaBean(properties, javaBean);
215         }
216
217         @Override
218         protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue, Tag customTag) {
219             if (propertyValue == null) {
220                 return null;
221             } else {
222                 NodeTuple defaultNode = super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
223                 return DEFAULT_STR.equals(property.getName()) ? new NodeTuple(representData(DEFAULT), defaultNode.getValueNode()) : defaultNode;
224             }
225         }
226     }
227 }