push addional 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.core.utilities.CommonMethods;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
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  * The type Yaml util.
50  */
51 public class YamlUtil {
52
53   private static Logger logger = LoggerFactory.getLogger(YamlUtil.class);
54
55   /**
56    * Yaml to object t.
57    *
58    * @param <T>         the type parameter
59    * @param yamlContent the yaml content
60    * @param typClass    the typ class
61    * @return the t
62    */
63   public <T> T yamlToObject(String yamlContent, Class<T> typClass) {
64     Constructor constructor = getConstructor(typClass);
65     constructor.setPropertyUtils(getPropertyUtils());
66     TypeDescription yamlFileDescription = new TypeDescription(typClass);
67     constructor.addTypeDescription(yamlFileDescription);
68     Yaml yaml = new Yaml(constructor);
69     T yamlObj = (T) yaml.load(yamlContent);
70     yamlObj.toString();
71     return yamlObj;
72   }
73
74   /**
75    * Yaml to object t.
76    *
77    * @param <T>         the type parameter
78    * @param yamlContent the yaml content
79    * @param typClass    the typ class
80    * @return the t
81    */
82   public <T> T yamlToObject(InputStream yamlContent, Class<T> typClass) {
83     try {
84       Constructor constructor = getConstructor(typClass);
85       constructor.setPropertyUtils(getPropertyUtils());
86       TypeDescription yamlFileDescription = new TypeDescription(typClass);
87       constructor.addTypeDescription(yamlFileDescription);
88       Yaml yaml = new Yaml(constructor);
89       T yamlObj = (T) yaml.load(yamlContent);
90       if (yamlObj != null) {
91         yamlObj.toString();
92         return yamlObj;
93       } else {
94         throw new RuntimeException();
95       }
96     } catch (Exception exception) {
97       logger.error("Error will trying to convert yaml to object:" + exception.getMessage());
98       throw new RuntimeException(exception);
99     } finally {
100       try {
101         if (yamlContent != null) {
102           yamlContent.close();
103         }
104       } catch (IOException ignore) {
105         //nothing to dd
106       }
107     }
108   }
109
110
111   /**
112    * Gets constructor.
113    *
114    * @param <T>      the type parameter
115    * @param typClass the typ class
116    * @return the constructor
117    */
118   public <T> Constructor getConstructor(Class<T> typClass) {
119     return new StrictMapAppenderConstructor(typClass);
120   }
121
122   /**
123    * Gets property utils.
124    *
125    * @return the property utils
126    */
127   protected PropertyUtils getPropertyUtils() {
128     return new MyPropertyUtils();
129   }
130
131   /**
132    * Yaml to map map.
133    *
134    * @param yamlContent the yaml content
135    * @return the map
136    */
137   public Map<String, LinkedHashMap<String, Object>> yamlToMap(InputStream yamlContent) {
138     Yaml yaml = new Yaml();
139     Map<String, LinkedHashMap<String, Object>> yamlData =
140         (Map<String, LinkedHashMap<String, Object>>) yaml.load(yamlContent);
141     return yamlData;
142   }
143
144   /**
145    * Object to yaml string.
146    *
147    * @param <T> the type parameter
148    * @param obj the obj
149    * @return the string
150    */
151   public <T> String objectToYaml(Object obj) {
152     DumperOptions options = new DumperOptions();
153     options.setPrettyFlow(true);
154     options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
155     Representer representer = new CustomRepresenter();
156     representer.addClassTag(obj.getClass(), Tag.MAP);
157     representer.setPropertyUtils(new MyPropertyUtils());
158
159     Yaml yaml = new Yaml(representer, options);
160     return yaml.dump(obj);
161   }
162
163   /**
164    * Load yaml file is input stream.
165    *
166    * @param yamlFullFileName the yaml full file name
167    * @return the input stream
168    */
169   public InputStream loadYamlFileIs(String yamlFullFileName) {
170     return CommonMethods.class.getResourceAsStream(yamlFullFileName);
171   }
172
173   /**
174    * Is yaml file content valid boolean.
175    *
176    * @param yamlFullFileName the yaml full file name
177    * @return the boolean
178    */
179   public boolean isYamlFileContentValid(String yamlFullFileName) {
180     Yaml yaml = new Yaml();
181     try {
182       Object loadResult = yaml.load(yamlFullFileName);
183       if (loadResult == null) {
184         return false;
185       }
186       return true;
187     } catch (Exception exception) {
188       return false;
189     }
190   }
191
192
193   private class CustomRepresenter extends Representer {
194     @Override
195     protected NodeTuple representJavaBeanProperty(Object javaBean, Property property,
196                                                   Object propertyValue, Tag customTag) {
197       if (propertyValue == null) {
198         return null;
199       } else {
200         NodeTuple defaultNode =
201             super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
202
203         return property.getName().equals("_default")
204             ? new NodeTuple(representData("default"), defaultNode.getValueNode())
205             : defaultNode;
206       }
207     }
208
209     @Override
210     protected MappingNode representJavaBean(Set<Property> properties, Object javaBean) {
211       //remove the bean type from the output yaml (!! ...)
212       if (!classTags.containsKey(javaBean.getClass())) {
213         addClassTag(javaBean.getClass(), Tag.MAP);
214       }
215
216       return super.representJavaBean(properties, javaBean);
217     }
218   }
219
220
221   /**
222    * The type My property utils.
223    */
224   public class MyPropertyUtils extends PropertyUtils {
225     @Override
226     public Property getProperty(Class<?> type, String name) throws IntrospectionException {
227       if (name.equals("default")) {
228         name = "_default";
229       }
230       return super.getProperty(type, name);
231     }
232
233     //Unsorted properties
234     @Override
235     protected Set<Property> createPropertySet(Class<? extends Object> type, BeanAccess beanAccess)
236         throws IntrospectionException {
237       return new LinkedHashSet<Property>(getPropertiesMap(type,
238           BeanAccess.FIELD).values());
239     }
240
241   }
242
243   /**
244    * The type Strict map appender constructor.
245    */
246   protected class StrictMapAppenderConstructor extends Constructor {
247
248     /**
249      * Instantiates a new Strict map appender constructor.
250      *
251      * @param theRoot the the root
252      */
253     public StrictMapAppenderConstructor(Class<?> theRoot) {
254       super(theRoot);
255     }
256
257     @Override
258     protected Map<Object, Object> constructMapping(MappingNode node) {
259       try {
260         return super.constructMapping(node);
261       } catch (IllegalStateException exception) {
262         throw new ParserException("while parsing MappingNode", node.getStartMark(),
263             exception.getMessage(), node.getEndMark());
264       }
265     }
266
267     @Override
268     protected Map<Object, Object> createDefaultMap() {
269       final Map<Object, Object> delegate = super.createDefaultMap();
270       return new AbstractMap<Object, Object>() {
271         @Override
272         public Object put(Object key, Object value) {
273           if (delegate.containsKey(key)) {
274             throw new IllegalStateException("duplicate key: " + key);
275           }
276           return delegate.put(key, value);
277         }
278
279         @Override
280         public Set<Entry<Object, Object>> entrySet() {
281           return delegate.entrySet();
282         }
283       };
284     }
285   }
286 }
287
288
289