[SDC] rebase 1710 code
[sdc.git] / openecomp-be / lib / openecomp-core-lib / openecomp-utilities-lib / src / main / java / org / openecomp / core / utilities / yaml / YamlUtil.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.openecomp.core.utilities.yaml;
22
23 import org.openecomp.sdc.logging.api.Logger;
24 import org.openecomp.sdc.logging.api.LoggerFactory;
25 import org.openecomp.core.utilities.CommonMethods;
26 import org.yaml.snakeyaml.DumperOptions;
27 import org.yaml.snakeyaml.TypeDescription;
28 import org.yaml.snakeyaml.Yaml;
29 import org.yaml.snakeyaml.constructor.Constructor;
30 import org.yaml.snakeyaml.introspector.BeanAccess;
31 import org.yaml.snakeyaml.introspector.Property;
32 import org.yaml.snakeyaml.introspector.PropertyUtils;
33 import org.yaml.snakeyaml.nodes.MappingNode;
34 import org.yaml.snakeyaml.nodes.NodeTuple;
35 import org.yaml.snakeyaml.nodes.Tag;
36 import org.yaml.snakeyaml.parser.ParserException;
37 import org.yaml.snakeyaml.representer.Representer;
38
39 import java.beans.IntrospectionException;
40 import java.io.IOException;
41 import java.io.InputStream;
42 import java.util.AbstractMap;
43 import java.util.LinkedHashMap;
44 import java.util.LinkedHashSet;
45 import java.util.Map;
46 import java.util.Set;
47
48
49 /**
50  * The type Yaml util.
51  */
52 public class YamlUtil {
53
54   private static Logger logger = (Logger) LoggerFactory.getLogger(YamlUtil.class);
55
56   /**
57    * Yaml to object t.
58    *
59    * @param <T>         the type parameter
60    * @param yamlContent the yaml content
61    * @param typClass      the t class
62    * @return the t
63    */
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     yamlObj.toString();
72     return yamlObj;
73   }
74
75   /**
76    * Yaml to object t.
77    *
78    * @param <T>         the type parameter
79    * @param yamlContent the yaml content
80    * @param typClass      the t class
81    * @return the t
82    */
83   public <T> T yamlToObject(InputStream yamlContent, Class<T> typClass) {
84     try {
85       Constructor constructor = getConstructor(typClass);
86       constructor.setPropertyUtils(getPropertyUtils());
87       TypeDescription yamlFileDescription = new TypeDescription(typClass);
88       constructor.addTypeDescription(yamlFileDescription);
89       Yaml yaml = new Yaml(constructor);
90       T yamlObj = (T) yaml.load(yamlContent);
91       if (yamlObj != null) {
92         yamlObj.toString();
93         return yamlObj;
94       } else {
95         throw new RuntimeException();
96       }
97     } catch (Exception exception) {
98       logger.error("Error will trying to convert yaml to object:" + exception.getMessage());
99       throw new RuntimeException(exception);
100     } finally {
101       try {
102         if (yamlContent != null) {
103           yamlContent.close();
104         }
105       } catch (IOException ignore) {
106         //do nothing
107       }
108     }
109   }
110
111
112   /**
113    * Gets constructor.
114    *
115    * @param <T>    the type parameter
116    * @param typClass the t class
117    * @return the constructor
118    */
119   public <T> Constructor getConstructor(Class<T> typClass) {
120     return new StrictMapAppenderConstructor(typClass);
121   }
122
123   /**
124    * Gets property utils.
125    *
126    * @return the property utils
127    */
128   protected PropertyUtils getPropertyUtils() {
129     return new MyPropertyUtils();
130   }
131
132
133   /**
134    * Yaml to map map.
135    *
136    * @param yamlContent the yaml content
137    * @return the map
138    */
139   public Map<String, LinkedHashMap<String, Object>> yamlToMap(InputStream yamlContent) {
140     Yaml yaml = new Yaml();
141     Map<String, LinkedHashMap<String, Object>> yamlData =
142         (Map<String, LinkedHashMap<String, Object>>) yaml.load(yamlContent);
143     return yamlData;
144   }
145
146   /**
147    * Object to yaml string.
148    *
149    * @param <T> the type parameter
150    * @param obj   the obj
151    * @return the string
152    */
153   public <T> String objectToYaml(Object obj) {
154     DumperOptions options = new DumperOptions();
155     options.setPrettyFlow(true);
156     options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
157     Representer representer = new CustomRepresenter();
158     representer.addClassTag(obj.getClass(), Tag.MAP);
159     representer.setPropertyUtils(new MyPropertyUtils());
160
161     Yaml yaml = new Yaml(representer, options);
162     return yaml.dump(obj);
163   }
164
165   /**
166    * Load yaml file is input stream.
167    *
168    * @param yamlFullFileName the yaml full file name
169    * @return the input stream
170    */
171   public InputStream loadYamlFileIs(String yamlFullFileName) {
172     return CommonMethods.class.getResourceAsStream(yamlFullFileName);
173   }
174
175   /**
176    * Is yaml file content valid boolean.
177    *
178    * @param yamlFullFileName the yaml full file name
179    * @return the boolean
180    */
181   public boolean isYamlFileContentValid(String yamlFullFileName) {
182     Yaml yaml = new Yaml();
183     try {
184       Object loadResult = yaml.load(yamlFullFileName);
185       if (loadResult == null) {
186         return false;
187       }
188       return true;
189     } catch (Exception exception) {
190       return false;
191     }
192   }
193
194
195   private class CustomRepresenter extends Representer {
196     @Override
197     protected MappingNode representJavaBean(Set<Property> properties, Object javaBean) {
198       //remove the bean type from the output yaml (!! ...)
199       if (!classTags.containsKey(javaBean.getClass())) {
200         addClassTag(javaBean.getClass(), Tag.MAP);
201       }
202
203       return super.representJavaBean(properties, javaBean);
204     }
205
206     @Override
207     protected NodeTuple representJavaBeanProperty(Object javaBean, Property property,
208                                                   Object propertyValue, Tag customTag) {
209       if (propertyValue == null) {
210         return null;
211       } else {
212         NodeTuple defaultNode =
213             super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
214
215         return property.getName().equals("_default")
216             ? new NodeTuple(representData("default"), defaultNode.getValueNode())
217             : defaultNode;
218       }
219     }
220   }
221
222
223   /**
224    * The type My property utils.
225    */
226   public class MyPropertyUtils extends PropertyUtils {
227     //Unsorted properties
228     @Override
229     protected Set<Property> createPropertySet(Class<? extends Object> type, BeanAccess bnAccess)
230         throws IntrospectionException {
231       return new LinkedHashSet<Property>(getPropertiesMap(type,
232           BeanAccess.FIELD).values());
233     }
234
235     @Override
236     public Property getProperty(Class<?> type, String name) throws IntrospectionException {
237       if (name.equals("default")) {
238         name = "_default";
239       }
240       return super.getProperty(type, name);
241     }
242
243   }
244
245   /**
246    * The type Strict map appender constructor.
247    */
248   protected class StrictMapAppenderConstructor extends Constructor {
249
250     /**
251      * Instantiates a new Strict map appender constructor.
252      *
253      * @param theRoot the the root
254      */
255     public StrictMapAppenderConstructor(Class<?> theRoot) {
256       super(theRoot);
257     }
258
259     @Override
260     protected Map<Object, Object> createDefaultMap() {
261       final Map<Object, Object> delegate = super.createDefaultMap();
262       return new AbstractMap<Object, Object>() {
263         @Override
264         public Object put(Object key, Object value) {
265           if (delegate.containsKey(key)) {
266             throw new IllegalStateException("duplicate key: " + key);
267           }
268           return delegate.put(key, value);
269         }
270
271         @Override
272         public Set<Entry<Object, Object>> entrySet() {
273           return delegate.entrySet();
274         }
275       };
276     }
277
278     @Override
279     protected Map<Object, Object> constructMapping(MappingNode node) {
280       try {
281         return super.constructMapping(node);
282       } catch (IllegalStateException exception) {
283         throw new ParserException("while parsing MappingNode",
284             node.getStartMark(), exception.getMessage(),
285             node.getEndMark());
286       }
287     }
288   }
289 }
290
291
292