7d0bcfeb83572491321d1da7e2046897fa643bef
[sdc.git] / common / openecomp-tosca-datatype / src / main / java / org / openecomp / sdc / tosca / services / YamlUtil.java
1 package org.openecomp.sdc.tosca.services;
2
3 import org.yaml.snakeyaml.DumperOptions;
4 import org.yaml.snakeyaml.TypeDescription;
5 import org.yaml.snakeyaml.Yaml;
6 import org.yaml.snakeyaml.constructor.Constructor;
7 import org.yaml.snakeyaml.introspector.BeanAccess;
8 import org.yaml.snakeyaml.introspector.Property;
9 import org.yaml.snakeyaml.introspector.PropertyUtils;
10 import org.yaml.snakeyaml.nodes.MappingNode;
11 import org.yaml.snakeyaml.nodes.NodeTuple;
12 import org.yaml.snakeyaml.nodes.Tag;
13 import org.yaml.snakeyaml.parser.ParserException;
14 import org.yaml.snakeyaml.representer.Representer;
15
16 import java.beans.IntrospectionException;
17 import java.io.IOException;
18 import java.io.InputStream;
19 import java.util.AbstractMap;
20 import java.util.LinkedHashMap;
21 import java.util.LinkedHashSet;
22 import java.util.Map;
23 import java.util.Set;
24
25 /**
26  * The type Yaml util.
27  */
28 @SuppressWarnings("unchecked")
29 public class YamlUtil {
30
31   /**
32    * Yaml to object t.
33    *
34    * @param <T>         the type parameter
35    * @param yamlContent the yaml content
36    * @param typClass    the t class
37    * @return the t
38    */
39   public <T> T yamlToObject(String yamlContent, Class<T> typClass) {
40     Constructor constructor = getConstructor(typClass);
41     constructor.setPropertyUtils(getPropertyUtils());
42     TypeDescription yamlFileDescription = new TypeDescription(typClass);
43     constructor.addTypeDescription(yamlFileDescription);
44     Yaml yaml = new Yaml(constructor);
45     T yamlObj = (T) yaml.load(yamlContent);
46     //noinspection ResultOfMethodCallIgnored
47     yamlObj.toString();
48     return yamlObj;
49   }
50
51   /**
52    * Yaml to object t.
53    *
54    * @param <T>         the type parameter
55    * @param yamlContent the yaml content
56    * @param typClass    the t class
57    * @return the t
58    */
59   public <T> T yamlToObject(InputStream yamlContent, Class<T> typClass) {
60     try {
61       Constructor constructor = getConstructor(typClass);
62       constructor.setPropertyUtils(getPropertyUtils());
63       TypeDescription yamlFileDescription = new TypeDescription(typClass);
64       constructor.addTypeDescription(yamlFileDescription);
65       Yaml yaml = new Yaml(constructor);
66       T yamlObj = (T) yaml.load(yamlContent);
67       if (yamlObj != null) {
68         //noinspection ResultOfMethodCallIgnored
69         yamlObj.toString();
70         return yamlObj;
71       } else {
72         throw new RuntimeException();
73       }
74     } catch (Exception exception) {
75       throw new RuntimeException(exception);
76     } finally {
77       try {
78         if (yamlContent != null) {
79           yamlContent.close();
80         }
81       } catch (IOException ignore) {
82         //do nothing
83       }
84     }
85   }
86
87
88   /**
89    * Gets constructor.
90    *
91    * @param <T>      the type parameter
92    * @param typClass the t class
93    * @return the constructor
94    */
95   public <T> Constructor getConstructor(Class<T> typClass) {
96     return new StrictMapAppenderConstructor(typClass);
97   }
98
99   /**
100    * Gets property utils.
101    *
102    * @return the property utils
103    */
104   protected PropertyUtils getPropertyUtils() {
105     return new MyPropertyUtils();
106   }
107
108
109   /**
110    * Yaml to map map.
111    *
112    * @param yamlContent the yaml content
113    * @return the map
114    */
115   public Map<String, LinkedHashMap<String, Object>> yamlToMap(InputStream yamlContent) {
116     Yaml yaml = new Yaml();
117     @SuppressWarnings("unchecked") Map<String, LinkedHashMap<String, Object>> yamlData =
118         (Map<String, LinkedHashMap<String, Object>>) yaml.load(yamlContent);
119     return yamlData;
120   }
121
122   /**
123    * Object to yaml string.
124    *
125    * @param <T> the type parameter
126    * @param obj the obj
127    * @return the string
128    */
129   public <T> String objectToYaml(Object obj) {
130     DumperOptions options = new DumperOptions();
131     options.setPrettyFlow(true);
132     options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
133     Representer representer = new CustomRepresenter();
134     representer.addClassTag(obj.getClass(), Tag.MAP);
135     representer.setPropertyUtils(new MyPropertyUtils());
136
137     Yaml yaml = new Yaml(representer, options);
138     return yaml.dump(obj);
139   }
140
141   /**
142    * Is yaml file content valid boolean.
143    *
144    * @param yamlFullFileName the yaml full file name
145    * @return the boolean
146    */
147   public boolean isYamlFileContentValid(String yamlFullFileName) {
148     Yaml yaml = new Yaml();
149     try {
150       Object loadResult = yaml.load(yamlFullFileName);
151       return loadResult != null;
152     } catch (Exception exception) {
153       return false;
154     }
155   }
156
157
158   private class CustomRepresenter extends Representer {
159     @Override
160     protected MappingNode representJavaBean(Set<Property> properties, Object javaBean) {
161       //remove the bean type from the output yaml (!! ...)
162       if (!classTags.containsKey(javaBean.getClass())) {
163         addClassTag(javaBean.getClass(), Tag.MAP);
164       }
165
166       return super.representJavaBean(properties, javaBean);
167     }
168
169     @Override
170     protected NodeTuple representJavaBeanProperty(Object javaBean, Property property,
171                                                   Object propertyValue, Tag customTag) {
172       if (propertyValue == null) {
173         return null;
174       } else {
175         NodeTuple defaultNode =
176             super.representJavaBeanProperty(javaBean, property, propertyValue, customTag);
177
178         return property.getName().equals("_default")
179             ? new NodeTuple(representData("default"), defaultNode.getValueNode())
180             : defaultNode;
181       }
182     }
183   }
184
185
186   /**
187    * The type My property utils.
188    */
189   public class MyPropertyUtils extends PropertyUtils {
190     //Unsorted properties
191     @Override
192     protected Set<Property> createPropertySet(Class<? extends Object> type, BeanAccess bnAccess)
193         throws IntrospectionException {
194       return new LinkedHashSet<Property>(getPropertiesMap(type,
195           BeanAccess.FIELD).values());
196     }
197
198     @Override
199     public Property getProperty(Class<?> type, String name) throws IntrospectionException {
200       if (name.equals("default")) {
201         name = "_default";
202       }
203       return super.getProperty(type, name);
204     }
205
206   }
207
208   /**
209    * The type Strict map appender constructor.
210    */
211   protected class StrictMapAppenderConstructor extends Constructor {
212
213     /**
214      * Instantiates a new Strict map appender constructor.
215      *
216      * @param theRoot the the root
217      */
218     public StrictMapAppenderConstructor(Class<?> theRoot) {
219       super(theRoot);
220     }
221
222     @Override
223     protected Map<Object, Object> createDefaultMap() {
224       final Map<Object, Object> delegate = super.createDefaultMap();
225       return new AbstractMap<Object, Object>() {
226         @Override
227         public Object put(Object key, Object value) {
228           if (delegate.containsKey(key)) {
229             throw new IllegalStateException("duplicate key: " + key);
230           }
231           return delegate.put(key, value);
232         }
233
234         @Override
235         public Set<Entry<Object, Object>> entrySet() {
236           return delegate.entrySet();
237         }
238       };
239     }
240
241     @Override
242     protected Map<Object, Object> constructMapping(MappingNode node) {
243       try {
244         return super.constructMapping(node);
245       } catch (IllegalStateException exception) {
246         throw new ParserException("while parsing MappingNode",
247             node.getStartMark(), exception.getMessage(),
248             node.getEndMark());
249       }
250     }
251   }
252 }