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