Unit/SONAR/Checkstyle in ONAP-REST
[policy/engine.git] / ONAP-REST / src / main / java / org / onap / policy / rest / util / MsModelUtils.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP-REST
4  * ================================================================================
5  * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
6  * Modified Copyright (C) 2018 Samsung Electronics Co., Ltd.
7  * Modifications Copyright (C) 2019 Nordix Foundation.
8  * ================================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.policy.rest.util;
24
25 import com.att.research.xacml.util.XACMLProperties;
26 import com.google.gson.Gson;
27
28 import java.io.File;
29 import java.io.FileInputStream;
30 import java.io.FileNotFoundException;
31 import java.io.IOException;
32 import java.io.InputStream;
33 import java.util.ArrayList;
34 import java.util.Arrays;
35 import java.util.Collections;
36 import java.util.HashMap;
37 import java.util.HashSet;
38 import java.util.Iterator;
39 import java.util.LinkedHashMap;
40 import java.util.List;
41 import java.util.Map;
42 import java.util.Map.Entry;
43 import java.util.Set;
44
45 import lombok.Getter;
46 import lombok.Setter;
47
48 import org.apache.commons.lang.StringUtils;
49 import org.apache.commons.logging.Log;
50 import org.apache.commons.logging.LogFactory;
51 import org.eclipse.emf.common.util.EList;
52 import org.eclipse.emf.common.util.EMap;
53 import org.eclipse.emf.common.util.Enumerator;
54 import org.eclipse.emf.common.util.TreeIterator;
55 import org.eclipse.emf.common.util.URI;
56 import org.eclipse.emf.ecore.EAnnotation;
57 import org.eclipse.emf.ecore.EClass;
58 import org.eclipse.emf.ecore.EClassifier;
59 import org.eclipse.emf.ecore.EEnum;
60 import org.eclipse.emf.ecore.EEnumLiteral;
61 import org.eclipse.emf.ecore.EObject;
62 import org.eclipse.emf.ecore.EPackage;
63 import org.eclipse.emf.ecore.EReference;
64 import org.eclipse.emf.ecore.EStructuralFeature;
65 import org.eclipse.emf.ecore.impl.EAttributeImpl;
66 import org.eclipse.emf.ecore.impl.EEnumImpl;
67 import org.eclipse.emf.ecore.resource.Resource;
68 import org.eclipse.emf.ecore.resource.ResourceSet;
69 import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
70 import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
71 import org.json.JSONObject;
72 import org.onap.policy.rest.XacmlRestProperties;
73 import org.onap.policy.rest.dao.CommonClassDao;
74 import org.onap.policy.rest.jpa.DictionaryData;
75 import org.yaml.snakeyaml.Yaml;
76
77 @Getter
78 @Setter
79 public class MsModelUtils {
80
81     private static final Log logger = LogFactory.getLog(MsModelUtils.class);
82
83     // String constants
84     private static final String BOOLEAN = "boolean";
85     private static final String CONFIGURATION = "configuration";
86     private static final String DATATYPE = "data_types.policy.data.";
87     private static final String DATA_TYPE = "data_types";
88     private static final String DEFAULT = ".default";
89     private static final String DEFAULTVALUE = ":defaultValue-";
90     private static final String DESCRIPTION = ".description";
91     private static final String DESCRIPTION_KEY = "description";
92     private static final String DESCRIPTION_TOKEN = ":description-";
93     private static final String DICTIONARY = "dictionary:";
94     private static final String DICTIONARYNAME = "dictionaryName";
95     private static final String ERROR = "error";
96     private static final String E_PROXY_URI = "eProxyURI:";
97     private static final String INTEGER = "integer";
98     private static final String JSON_MODEL = "JSON_MODEL";
99     private static final String LIST = "list";
100     private static final String MANYFALSE = ":MANY-false";
101     private static final String MANYTRUE = ":MANY-true";
102     private static final String MAP = "map";
103     private static final String MATCHABLE = ".matchable";
104     private static final String MATCHABLEKEY = "matchable";
105     private static final String MATCHINGTRUE = "matching-true";
106     private static final String NODE_TYPE = "node_types";
107     private static final String PROPERTIES = ".properties.";
108     private static final String PROPERTIES_KEY = "properties";
109     private static final String REQUIRED = ".required";
110     private static final String REQUIREDFALSE = ":required-false";
111     private static final String REQUIREDTRUE = ":required-true";
112     private static final String REQUIREDVALUE = ":required-";
113     private static final String STRING = "string";
114     private static final String TOSCA_DEFINITION_VERSION = "tosca_definitions_version";
115     private static final String TOSCA_SIMPLE_YAML_1_0_0 = "tosca_simple_yaml_1_0_0";
116     private static final String TYPE = ".type";
117
118     private static CommonClassDao commonClassDao;
119
120     private HashMap<String, MsAttributeObject> classMap = new HashMap<>();
121     private HashMap<String, String> enumMap = new HashMap<>();
122     private HashMap<String, String> matchingClass = new HashMap<>();
123     private String onap = "";
124     private String policy = "";
125     private List<String> orderedElements = new ArrayList<>();
126     private String dataOrderInfo = "";
127     private Set<String> uniqueDataKeys = new HashSet<>();
128     private Set<String> uniqueKeys = new HashSet<>();
129     private String listConstraints = null;
130     private String referenceAttributes;
131     private LinkedHashMap<String, Object> retmap = new LinkedHashMap<>();
132     private Map<String, String> matchableValues;
133     private StringBuilder dataListBuffer = new StringBuilder();
134     private List<String> dataConstraints = new ArrayList<>();
135     private String attributeString = null;
136     private boolean isDuplicatedAttributes = false;
137     private String jsonRuleFormation = null;
138
139     /**
140      * The Enum AnnotationType.
141      */
142     private enum AnnotationType {
143         MATCHING,
144         VALIDATION,
145         DICTIONARY
146     }
147
148     /**
149      * The Enum ModelType.
150      */
151     public enum ModelType {
152         XMI
153     }
154
155     /**
156      * The Enum SearchType.
157      */
158     public enum SearchType {
159         TOSCA_DEFINITION_VERSION,
160         TOSCA_SIMPLE_YAML_1_0_0,
161         NODE_TYPE,
162         DATA_TYPE,
163         JSON_MODEL
164     }
165
166     /**
167      * Instantiates a new ms model utils.
168      */
169     public MsModelUtils() {
170         // Default Constructor
171     }
172
173     /**
174      * Instantiates a new ms model utils.
175      *
176      * @param commonClassDao the common class dao
177      */
178     public MsModelUtils(CommonClassDao commonClassDao) {
179         MsModelUtils.commonClassDao = commonClassDao;
180     }
181
182     /**
183      * Instantiates a new ms model utils.
184      *
185      * @param onap the onap
186      * @param policy the policy
187      */
188     public MsModelUtils(String onap, String policy) {
189         this.onap = onap;
190         this.policy = policy;
191     }
192
193     /**
194      * Process epackage.
195      *
196      * @param file the file
197      * @param model the model
198      * @return the map
199      */
200     public Map<String, MsAttributeObject> processEpackage(String file, ModelType model) {
201         if (model == ModelType.XMI) {
202             processXmiEpackage(file);
203         }
204         return classMap;
205     }
206
207     /**
208      * Process XMI epackage.
209      *
210      * @param xmiFile the xmi file
211      */
212     private void processXmiEpackage(String xmiFile) {
213         EPackage root = getEpackage(xmiFile);
214         TreeIterator<EObject> treeItr = root.eAllContents();
215         String className;
216         String returnValue;
217
218         // Pulling out dependency from file
219         while (treeItr.hasNext()) {
220             EObject obj = treeItr.next();
221             if (obj instanceof EClassifier) {
222                 EClassifier eclassifier = (EClassifier) obj;
223                 className = eclassifier.getName();
224
225                 if (obj instanceof EEnum) {
226                     enumMap.putAll(getEEnum(obj));
227                 } else if (obj instanceof EClass) {
228                     String temp = getDependencyList(eclassifier).toString();
229                     returnValue = StringUtils.replaceEach(temp, new String[]
230                         { "[", "]" }, new String[]
231                         { "", "" });
232                     getAttributes(className, returnValue, root);
233                 }
234             }
235         }
236
237         if (!enumMap.isEmpty()) {
238             addEnumClassMap();
239         }
240         if (!matchingClass.isEmpty()) {
241             checkForMatchingClass();
242         }
243     }
244
245     /**
246      * Check for matching class.
247      */
248     private void checkForMatchingClass() {
249         HashMap<String, String> tempAttribute = new HashMap<>();
250
251         for (Entry<String, String> set : matchingClass.entrySet()) {
252             String key = set.getKey();
253             if (classMap.containsKey(key)) {
254                 Map<String, String> listAttributes = classMap.get(key).getAttribute();
255                 Map<String, String> listRef = classMap.get(key).getRefAttribute();
256                 for (Entry<String, String> eset : listAttributes.entrySet()) {
257                     String key2 = eset.getKey();
258                     tempAttribute.put(key2, MATCHINGTRUE);
259                 }
260                 for (Entry<String, String> eset : listRef.entrySet()) {
261                     String key3 = eset.getKey();
262                     tempAttribute.put(key3, MATCHINGTRUE);
263                 }
264
265             }
266             updateMatching(tempAttribute, key);
267         }
268
269     }
270
271     /**
272      * Update matching.
273      *
274      * @param tempAttribute the temp attribute
275      * @param key the key
276      */
277     private void updateMatching(HashMap<String, String> tempAttribute, String key) {
278         Map<String, MsAttributeObject> newClass = classMap;
279
280         for (Entry<String, MsAttributeObject> updateClass : newClass.entrySet()) {
281             Map<String, String> valueMap = updateClass.getValue().getMatchingSet();
282             String keymap = updateClass.getKey();
283             if (valueMap.containsKey(key)) {
284                 Map<String, String> modifyMap = classMap.get(keymap).getMatchingSet();
285                 modifyMap.remove(key);
286                 modifyMap.putAll(tempAttribute);
287                 classMap.get(keymap).setMatchingSet(modifyMap);
288             }
289
290         }
291     }
292
293     /**
294      * Adds the enum class map.
295      */
296     private void addEnumClassMap() {
297         for (Entry<String, MsAttributeObject> value : classMap.entrySet()) {
298             value.getValue().setEnumType(enumMap);
299         }
300     }
301
302     /**
303      * Gets the epackage.
304      *
305      * @param xmiFile the xmi file
306      * @return the epackage
307      */
308     private EPackage getEpackage(String xmiFile) {
309         ResourceSet resSet = new ResourceSetImpl();
310         Resource.Factory.Registry reg = Resource.Factory.Registry.INSTANCE;
311         Map<String, Object> objectMap = reg.getExtensionToFactoryMap();
312         objectMap.put("xmi", new XMIResourceFactoryImpl());
313         Resource resource = resSet.getResource(URI.createFileURI(xmiFile), true);
314         try {
315             resource.load(Collections.emptyMap());
316         } catch (IOException e) {
317             logger.error("Error loading Encore Resource for new Model" + e);
318         }
319
320         return (EPackage) resource.getContents().get(0);
321     }
322
323     /**
324      * Gets the e enum.
325      *
326      * @param obj the obj
327      * @return the e enum
328      */
329     private HashMap<String, String> getEEnum(EObject obj) {
330         List<String> valueList = new ArrayList<>();
331         HashMap<String, String> returnMap = new HashMap<>();
332         EEnum eenum = (EEnum) obj;
333
334         String name = eenum.getName();
335         for (EEnumLiteral enumLiteral : eenum.getELiterals()) {
336             Enumerator instance = enumLiteral.getInstance();
337             String value = instance.getLiteral();
338             valueList.add(value);
339         }
340         returnMap.put(name, valueList.toString());
341         return returnMap;
342     }
343
344     /**
345      * Gets the attributes.
346      *
347      * @param className the class name
348      * @param dependency the dependency
349      * @param root the root
350      */
351     public void getAttributes(String className, String dependency, EPackage root) {
352         List<String> dpendList = new ArrayList<>();
353         if (dependency != null) {
354             dpendList = new ArrayList<>(Arrays.asList(dependency.split(",")));
355         }
356         MsAttributeObject msAttributeObject = new MsAttributeObject();
357         msAttributeObject.setClassName(className);
358         String extendClass = getSubTypes(root, className);
359         Map<String, String> returnRefList = getRefAttributeList(root, className, extendClass);
360         Map<String, String> returnAttributeList = getAttributeList(root, className, extendClass);
361         Map<String, Object> returnSubList = getSubAttributeList(root, className, extendClass);
362         HashMap<String, String> returnAnnotation = getAnnotation(root, className, extendClass);
363         msAttributeObject.setAttribute(returnAttributeList);
364         msAttributeObject.setRefAttribute(returnRefList);
365         msAttributeObject.setSubClass(returnSubList);
366         msAttributeObject.setDependency(dpendList.toString());
367         msAttributeObject.addMatchingSet(returnAnnotation);
368         msAttributeObject.setPolicyTempalate(isPolicyTemplate(root, className));
369
370         this.classMap.put(className, msAttributeObject);
371     }
372
373     /**
374      * Gets the annotation.
375      *
376      * @param root the root
377      * @param className the class name
378      * @param extendClass the extend class
379      * @return the annotation
380      */
381     private HashMap<String, String> getAnnotation(EPackage root, String className, String extendClass) {
382         TreeIterator<EObject> treeItr = root.eAllContents();
383         boolean requiredAttribute = false;
384         boolean requiredMatchAttribute = false;
385         HashMap<String, String> annotationSet = new HashMap<>();
386
387         // Pulling out dependency from file
388         while (treeItr.hasNext()) {
389             EObject obj = treeItr.next();
390             if (obj instanceof EClassifier) {
391                 requiredAttribute = isRequiredAttribute(obj, className);
392                 requiredMatchAttribute = isRequiredAttribute(obj, extendClass);
393             }
394
395             if (requiredAttribute) {
396                 if (obj instanceof EStructuralFeature) {
397                     checkAnnotation(annotationSet, (EStructuralFeature) obj);
398                 }
399             } else if (requiredMatchAttribute && (obj instanceof EStructuralFeature)) {
400                 findMatchingAnnotation(annotationSet, obj);
401             }
402         }
403         return annotationSet;
404     }
405
406     /**
407      * Find matching annotation.
408      *
409      * @param annotationSet the annotation set
410      * @param obj the obj
411      */
412     private void findMatchingAnnotation(HashMap<String, String> annotationSet, EObject obj) {
413         EStructuralFeature estrucClassifier = (EStructuralFeature) obj;
414         if (estrucClassifier.getEAnnotations().isEmpty()) {
415             return;
416         }
417         String matching = annotationValue(estrucClassifier, AnnotationType.MATCHING, policy);
418         if (matching != null) {
419             if (obj instanceof EReference) {
420                 EClass refType = ((EReference) obj).getEReferenceType();
421                 annotationSet.put(refType.getName(), matching);
422                 matchingClass.put(refType.getName(), matching);
423             } else {
424                 annotationSet.put(estrucClassifier.getName(), matching);
425             }
426         }
427
428     }
429
430     /**
431      * Check annotation.
432      *
433      * @param annotationSet the annotation set
434      * @param obj the obj
435      */
436     private void checkAnnotation(HashMap<String, String> annotationSet, EStructuralFeature obj) {
437         EStructuralFeature estrucClassifier = obj;
438         if (estrucClassifier.getEAnnotations().isEmpty()) {
439             return;
440         }
441         String matching = annotationValue(estrucClassifier, AnnotationType.MATCHING, policy);
442         if (matching != null) {
443             annotationSet.put(estrucClassifier.getName(), matching);
444         }
445         String range = annotationValue(estrucClassifier, AnnotationType.VALIDATION, policy);
446         if (range != null) {
447             annotationSet.put(estrucClassifier.getName(), range);
448         }
449         String annotationDict = annotationValue(estrucClassifier, AnnotationType.DICTIONARY, policy);
450         if (annotationDict != null) {
451             annotationSet.put(estrucClassifier.getName(), annotationDict);
452         }
453     }
454
455     /**
456      * Gets the sub attribute list.
457      *
458      * @param root the root
459      * @param className the class name
460      * @param superClass the super class
461      * @return the sub attribute list
462      */
463     private Map<String, Object> getSubAttributeList(EPackage root, String className, String superClass) {
464         TreeIterator<EObject> treeItr = root.eAllContents();
465         boolean requiredAttribute = false;
466         Map<String, Object> subAttribute = new HashMap<>();
467         int rollingCount = 0;
468         int processClass = 0;
469
470         // Pulling out dependency from file
471         while (treeItr.hasNext() && rollingCount < 2) {
472
473             EObject obj = treeItr.next();
474             if (obj instanceof EClassifier) {
475                 requiredAttribute = isRequiredAttribute(obj, className) || isRequiredAttribute(obj, superClass);
476                 if (requiredAttribute) {
477                     processClass++;
478                 }
479                 rollingCount = rollingCount + processClass;
480             }
481
482             if (requiredAttribute && (obj instanceof EStructuralFeature)) {
483                 EStructuralFeature estrucClassifier = (EStructuralFeature) obj;
484                 if (!estrucClassifier.getEAnnotations().isEmpty()) {
485                     updateSubAttributes(subAttribute, obj, estrucClassifier);
486                 }
487             }
488         }
489         return subAttribute;
490     }
491
492     /**
493      * Update sub attributes.
494      *
495      * @param subAttribute the sub attribute
496      * @param obj the obj
497      * @param estrucClassifier the e struc classifier
498      */
499     private void updateSubAttributes(Map<String, Object> subAttribute, EObject obj,
500                     EStructuralFeature estrucClassifier) {
501         if (!(obj instanceof EReference)) {
502             return;
503         }
504         if (annotationTest(estrucClassifier, CONFIGURATION, onap)) {
505             EClass refType = ((EReference) obj).getEReferenceType();
506             if (!refType.toString().contains(E_PROXY_URI)) {
507                 String required = REQUIREDFALSE;
508                 if (estrucClassifier.getLowerBound() == 1) {
509                     required = REQUIREDTRUE;
510                 }
511                 subAttribute.put(estrucClassifier.getName(), refType.getName() + required);
512             }
513         }
514     }
515
516     /**
517      * Check defult value.
518      *
519      * @param defultValue the defult value
520      * @return the string
521      */
522     public String checkDefultValue(String defultValue) {
523         if (defultValue != null) {
524             return DEFAULTVALUE + defultValue;
525         }
526         return ":defaultValue-NA";
527
528     }
529
530     /**
531      * Check required pattern.
532      *
533      * @param upper the upper
534      * @param lower the lower
535      * @return the string
536      */
537     public String checkRequiredPattern(int upper, int lower) {
538         String pattern = XACMLProperties.getProperty(XacmlRestProperties.PROP_XCORE_REQUIRED_PATTERN);
539         if (pattern != null && upper == Integer.parseInt(pattern.split(",")[1])
540                         && lower == Integer.parseInt(pattern.split(",")[0])) {
541             return REQUIREDTRUE;
542         }
543         return REQUIREDFALSE;
544     }
545
546     /**
547      * Builds the java object.
548      *
549      * @param map the map
550      * @return the JSON object
551      */
552     public JSONObject buildJavaObject(Map<String, String> map) {
553         return new JSONObject(map);
554     }
555
556     /**
557      * Gets the ref attribute list.
558      *
559      * @param root the root
560      * @param className the class name
561      * @param superClass the super class
562      * @return the ref attribute list
563      */
564     public Map<String, String> getRefAttributeList(EPackage root, String className, String superClass) {
565
566         TreeIterator<EObject> treeItr = root.eAllContents();
567         boolean requiredAttribute = false;
568         HashMap<String, String> refAttribute = new HashMap<>();
569         int rollingCount = 0;
570         int processClass = 0;
571         boolean annotation;
572         // Pulling out dependency from file
573         while (treeItr.hasNext()) {
574             EObject obj = treeItr.next();
575             if (obj instanceof EClassifier) {
576                 requiredAttribute = isRequiredAttribute(obj, className) || isRequiredAttribute(obj, superClass);
577                 if (requiredAttribute) {
578                     processClass++;
579                 }
580                 rollingCount = rollingCount + processClass;
581             }
582
583             if (requiredAttribute && (obj instanceof EStructuralFeature)) {
584                 EStructuralFeature estrucClassifier = (EStructuralFeature) obj;
585                 if (!estrucClassifier.getEAnnotations().isEmpty()) {
586                     annotation = annotationTest(estrucClassifier, CONFIGURATION, onap);
587                     if (annotation && obj instanceof EReference) {
588                         updRefAttributes(refAttribute, (EStructuralFeature) obj, estrucClassifier);
589                     } else if (annotation && obj instanceof EAttributeImpl) {
590                         updEnumTypeRefAttrib(refAttribute, (EStructuralFeature) obj, estrucClassifier);
591                     }
592                 }
593             }
594         }
595
596         return refAttribute;
597     }
598
599     /**
600      * Upd enum type ref attrib.
601      *
602      * @param refAttribute the ref attribute
603      * @param obj the obj
604      * @param estrucClassifier the e struc classifier
605      */
606     private void updEnumTypeRefAttrib(HashMap<String, String> refAttribute, EStructuralFeature obj,
607                     EStructuralFeature estrucClassifier) {
608         EClassifier refType = ((EAttributeImpl) obj).getEType();
609         if (!(refType instanceof EEnumImpl)) {
610             return;
611         }
612
613         String array = arrayCheck(obj.getUpperBound());
614         String required = REQUIREDFALSE;
615         if (obj.getLowerBound() == 1) {
616             required = REQUIREDTRUE;
617         }
618         refAttribute.put(estrucClassifier.getName(), refType.getName() + array + required);
619     }
620
621     /**
622      * Upd ref attributes.
623      *
624      * @param refAttribute the ref attribute
625      * @param obj the obj
626      * @param estrucClassifier the e struc classifier
627      */
628     private void updRefAttributes(HashMap<String, String> refAttribute, EStructuralFeature obj,
629                     EStructuralFeature estrucClassifier) {
630         EClass refType = ((EReference) obj).getEReferenceType();
631         if (refType.toString().contains(E_PROXY_URI)) {
632             String one = refType.toString().split(E_PROXY_URI)[1];
633             String refValue = StringUtils.replaceEach(one.split("#")[1], new String[]
634                 { "//", ")" }, new String[]
635                 { "", "" });
636             refAttribute.put(estrucClassifier.getName(), refValue);
637         } else {
638             String required = REQUIREDFALSE;
639             if (obj.getLowerBound() == 1) {
640                 required = REQUIREDTRUE;
641             }
642             refAttribute.put(estrucClassifier.getName(),
643                             refType.getName() + arrayCheck(obj.getUpperBound()) + required);
644         }
645     }
646
647     /**
648      * Annotation test.
649      *
650      * @param estrucClassifier the e struc classifier
651      * @param annotation the annotation
652      * @param type the type
653      * @return true, if successful
654      */
655     private boolean annotationTest(EStructuralFeature estrucClassifier, String annotation, String type) {
656         String annotationType;
657         EAnnotation eannotation;
658         String onapType;
659         String onapValue;
660
661         EList<EAnnotation> value = estrucClassifier.getEAnnotations();
662
663         for (int i = 0; i < value.size(); i++) {
664             annotationType = value.get(i).getSource();
665             eannotation = estrucClassifier.getEAnnotations().get(i);
666             onapType = eannotation.getDetails().get(0).getValue();
667             onapValue = eannotation.getDetails().get(0).getKey();
668
669             if (annotationType.contains(type) && onapType.contains(annotation)) {
670                 return true;
671             }
672
673             if (annotationType.contains(type) && onapValue.contains(annotation)) {
674                 return true;
675             }
676         }
677
678         return false;
679     }
680
681     /**
682      * Annotation value.
683      *
684      * @param estrucClassifier the e struc classifier
685      * @param annotation the annotation
686      * @param type the type
687      * @return the string
688      */
689     private String annotationValue(EStructuralFeature estrucClassifier, AnnotationType annotation, String type) {
690         String annotationType;
691         EAnnotation eannotation;
692         String onapType;
693         String onapValue = null;
694
695         EList<EAnnotation> value = estrucClassifier.getEAnnotations();
696
697         for (int i = 0; i < value.size(); i++) {
698             annotationType = value.get(i).getSource();
699             eannotation = estrucClassifier.getEAnnotations().get(i);
700             onapType = eannotation.getDetails().get(0).getKey();
701             if (annotationType.contains(type) && onapType.compareToIgnoreCase(annotation.toString()) == 0) {
702                 onapValue = eannotation.getDetails().get(0).getValue();
703                 if (annotation == AnnotationType.VALIDATION) {
704                     return onapValue;
705                 } else {
706                     return onapType + "-" + onapValue;
707                 }
708             }
709         }
710
711         return onapValue;
712     }
713
714     /**
715      * Checks if is required attribute.
716      *
717      * @param obj the obj
718      * @param className the class name
719      * @return true, if is required attribute
720      */
721     public boolean isRequiredAttribute(EObject obj, String className) {
722         EClassifier eclassifier = (EClassifier) obj;
723         String workingClass = eclassifier.getName().trim();
724         return workingClass.equalsIgnoreCase(className);
725     }
726
727     /**
728      * Checks if is policy template.
729      *
730      * @param root the root
731      * @param className the class name
732      * @return true, if is policy template
733      */
734     private boolean isPolicyTemplate(EPackage root, String className) {
735         boolean result = false;
736         for (EClassifier classifier : root.getEClassifiers()) {
737             if (classifier instanceof EClass) {
738                 EClass eclass = (EClass) classifier;
739                 if (eclass.getName().contentEquals(className)) {
740                     result = checkPolicyTemplate(eclass);
741                     break;
742                 }
743             }
744         }
745         return result;
746     }
747
748     /**
749      * Check policy template.
750      *
751      * @param eclass the e class
752      * @return true, if successful
753      */
754     private boolean checkPolicyTemplate(EClass eclass) {
755         EList<EAnnotation> value = eclass.getEAnnotations();
756         for (EAnnotation workingValue : value) {
757             EMap<String, String> keyMap = workingValue.getDetails();
758             if (keyMap.containsKey("policyTemplate")) {
759                 return true;
760             }
761         }
762         return false;
763     }
764
765     /**
766      * Gets the sub types.
767      *
768      * @param root the root
769      * @param className the class name
770      * @return the sub types
771      */
772     private String getSubTypes(EPackage root, String className) {
773         String returnSubTypes = null;
774         for (EClassifier classifier : root.getEClassifiers()) {
775             if (classifier instanceof EClass) {
776                 returnSubTypes = findSubTypes(className, returnSubTypes, (EClass) classifier);
777             }
778         }
779         return returnSubTypes;
780     }
781
782     /**
783      * Find sub types.
784      *
785      * @param className the class name
786      * @param returnSubTypes the return sub types
787      * @param classifier the classifier
788      * @return the string
789      */
790     private String findSubTypes(String className, String returnSubTypes, EClass classifier) {
791         EClass eclass = classifier;
792
793         for (EClass esuperType : eclass.getEAllSuperTypes()) {
794             if (eclass.getName().contentEquals(className)) {
795                 returnSubTypes = esuperType.getName();
796             }
797         }
798         return returnSubTypes;
799     }
800
801     /**
802      * Gets the attribute list.
803      *
804      * @param root the root
805      * @param className the class name
806      * @param superClass the super class
807      * @return the attribute list
808      */
809     public Map<String, String> getAttributeList(EPackage root, String className, String superClass) {
810
811         TreeIterator<EObject> treeItr = root.eAllContents();
812         boolean requiredAttribute = false;
813         HashMap<String, String> refAttribute = new HashMap<>();
814
815         // Pulling out dependency from file
816         while (treeItr.hasNext()) {
817             EObject obj = treeItr.next();
818             if (obj instanceof EClassifier) {
819                 requiredAttribute = isRequiredAttribute(obj, className) || isRequiredAttribute(obj, superClass);
820             }
821
822             if (requiredAttribute && (obj instanceof EStructuralFeature)) {
823                 EStructuralFeature estrucClassifier = (EStructuralFeature) obj;
824                 if (!estrucClassifier.getEAnnotations().isEmpty()) {
825                     checkStrucClassifier(refAttribute, obj, estrucClassifier);
826                 }
827             }
828         }
829         return refAttribute;
830
831     }
832
833     /**
834      * Check struc classifier.
835      *
836      * @param refAttribute the ref attribute
837      * @param obj the obj
838      * @param estrucClassifier the e struc classifier
839      */
840     private void checkStrucClassifier(HashMap<String, String> refAttribute, EObject obj,
841                     EStructuralFeature estrucClassifier) {
842         EClassifier refType = ((EStructuralFeature) obj).getEType();
843         boolean annotation = annotationTest(estrucClassifier, CONFIGURATION, onap);
844         boolean dictionaryTest = annotationTest(estrucClassifier, DICTIONARY, policy);
845         if (annotation && !(obj instanceof EReference) && !(refType instanceof EEnumImpl)) {
846             updEReferenceAttrib(refAttribute, dictionaryTest, (EStructuralFeature) obj, estrucClassifier);
847         }
848     }
849
850     /**
851      * Upd E reference attrib.
852      *
853      * @param refAttribute the ref attribute
854      * @param dictionaryTest the dictionary test
855      * @param obj the obj
856      * @param estrucClassifier the e struc classifier
857      */
858     private void updEReferenceAttrib(HashMap<String, String> refAttribute, boolean dictionaryTest,
859                     EStructuralFeature obj, EStructuralFeature estrucClassifier) {
860         String etype;
861         String name = estrucClassifier.getName();
862         if (dictionaryTest) {
863             etype = annotationValue(estrucClassifier, AnnotationType.DICTIONARY, policy);
864         } else {
865             etype = estrucClassifier.getEType().getInstanceClassName();
866         }
867         String defaultValue = checkDefultValue(obj.getDefaultValueLiteral());
868         String array = arrayCheck(obj.getUpperBound());
869         String required = checkRequiredPattern(obj.getUpperBound(), obj.getLowerBound());
870         refAttribute.put(name, etype + defaultValue + required + array);
871     }
872
873     /**
874      * Array check.
875      *
876      * @param upperBound the upper bound
877      * @return the string
878      */
879     public String arrayCheck(int upperBound) {
880
881         if (upperBound == -1) {
882             return MANYTRUE;
883         }
884
885         return MANYFALSE;
886     }
887
888     /**
889      * Gets the dependency list.
890      *
891      * @param eclassifier the e classifier
892      * @return the dependency list
893      */
894     public List<String> getDependencyList(EClassifier eclassifier) {
895         List<String> returnValue = new ArrayList<>();
896         ;
897         EList<EClass> somelist = ((EClass) eclassifier).getEAllSuperTypes();
898         if (somelist.isEmpty()) {
899             return returnValue;
900         }
901         for (EClass depend : somelist) {
902             if (depend.toString().contains(E_PROXY_URI)) {
903                 String one = depend.toString().split(E_PROXY_URI)[1];
904                 String value = StringUtils.replaceEach(one.split("#")[1], new String[]
905                     { "//", ")" }, new String[]
906                     { "", "" });
907                 returnValue.add(value);
908             }
909         }
910
911         return returnValue;
912     }
913
914     /**
915      * Builds the sub list.
916      *
917      * @param subClassAttributes the sub class attributes
918      * @param classMap the class map
919      * @param className the class name
920      * @return the map
921      */
922     public Map<String, String> buildSubList(Map<String, String> subClassAttributes,
923                     Map<String, MsAttributeObject> classMap, String className) {
924         Map<String, String> missingValues = new HashMap<>();
925         Map<String, String> workingMap;
926         boolean enumType;
927
928         for (Entry<String, String> map : classMap.get(className).getRefAttribute().entrySet()) {
929             String value = map.getValue().split(":")[0];
930             if (value != null) {
931                 classMap.get(className).getEnumType();
932                 enumType = classMap.get(className).getEnumType().containsKey(value);
933                 if (!enumType) {
934                     workingMap = classMap.get(value).getRefAttribute();
935                     for (Entry<String, String> subMab : workingMap.entrySet()) {
936                         String value2 = subMab.getValue().split(":")[0];
937                         if (!subClassAttributes.containsValue(value2)) {
938                             missingValues.put(subMab.getKey(), subMab.getValue());
939                         }
940                     }
941
942                 }
943             }
944         }
945
946         return missingValues;
947     }
948
949     /**
950      * Recursive reference.
951      *
952      * @param classMap the class map
953      * @param className the class name
954      * @return the map
955      */
956     public Map<String, Map<String, String>> recursiveReference(Map<String, MsAttributeObject> classMap,
957                     String className) {
958
959         Map<String, Map<String, String>> returnObject = new HashMap<>();
960         Map<String, String> returnClass = getRefclass(classMap, className);
961         returnObject.put(className, returnClass);
962         for (Entry<String, String> reAttribute : returnClass.entrySet()) {
963             if (reAttribute.getValue().split(":")[1].contains("MANY")
964                             && classMap.get(reAttribute.getValue().split(":")[0]) != null) {
965                 returnObject.putAll(recursiveReference(classMap, reAttribute.getValue().split(":")[0]));
966             }
967
968         }
969
970         return returnObject;
971
972     }
973
974     /**
975      * Creates the json.
976      *
977      * @param classMap the class map
978      * @param className the class name
979      * @return the string
980      */
981     public String createJson(Map<String, MsAttributeObject> classMap, String className) {
982         boolean enumType;
983         Map<String, Map<String, String>> myObject = new HashMap<>();
984         for (Entry<String, String> map : classMap.get(className).getRefAttribute().entrySet()) {
985             String value = map.getValue().split(":")[0];
986             if (value != null) {
987                 enumType = classMap.get(className).getEnumType().containsKey(value);
988                 if (!enumType && map.getValue().split(":")[1].contains("MANY")) {
989                     Map<String, Map<String, String>> testRecursive = recursiveReference(classMap,
990                                     map.getValue().split(":")[0]);
991                     myObject.putAll(testRecursive);
992                 }
993             }
994         }
995
996         Gson gson = new Gson();
997         return gson.toJson(myObject);
998     }
999
1000     /**
1001      * Gets the refclass.
1002      *
1003      * @param classMap the class map
1004      * @param className the class name
1005      * @return the refclass
1006      */
1007     public Map<String, String> getRefclass(Map<String, MsAttributeObject> classMap, String className) {
1008         HashMap<String, String> missingValues = new HashMap<>();
1009
1010         if (classMap.get(className).getAttribute() != null || !classMap.get(className).getAttribute().isEmpty()) {
1011             missingValues.putAll(classMap.get(className).getAttribute());
1012         }
1013
1014         if (classMap.get(className).getRefAttribute() != null || !classMap.get(className).getRefAttribute().isEmpty()) {
1015             missingValues.putAll(classMap.get(className).getRefAttribute());
1016         }
1017
1018         return missingValues;
1019     }
1020
1021     /**
1022      * Creates the sub attributes.
1023      *
1024      * @param dependency the dependency
1025      * @param classMap the class map
1026      * @param modelName the model name
1027      * @return the string
1028      */
1029     public String createSubAttributes(List<String> dependency, Map<String, MsAttributeObject> classMap,
1030                     String modelName) {
1031
1032         HashMap<String, Object> workingMap = new HashMap<>();
1033         MsAttributeObject tempObject;
1034         if (dependency != null) {
1035             if (dependency.isEmpty()) {
1036                 return "{}";
1037             }
1038             dependency.add(modelName);
1039             for (String element : dependency) {
1040                 tempObject = classMap.get(element);
1041                 if (tempObject != null) {
1042                     workingMap.putAll(classMap.get(element).getSubClass());
1043                 }
1044             }
1045         }
1046
1047         return createJson(classMap, modelName);
1048     }
1049
1050     /**
1051      * Gets the full dependency list.
1052      *
1053      * @param dependency the dependency
1054      * @param classMap the class map
1055      * @return the full dependency list
1056      */
1057     public List<String> getFullDependencyList(List<String> dependency, Map<String, MsAttributeObject> classMap) {
1058         ArrayList<String> returnList = new ArrayList<>();
1059         ArrayList<String> workingList;
1060         returnList.addAll(dependency);
1061         for (String element : dependency) {
1062             if (classMap.containsKey(element)) {
1063                 MsAttributeObject value = classMap.get(element);
1064                 String rawValue = StringUtils.replaceEach(value.getDependency(), new String[]
1065                     { "[", "]" }, new String[]
1066                     { "", "" });
1067                 workingList = new ArrayList<>(Arrays.asList(rawValue.split(",")));
1068                 for (String depend : workingList) {
1069                     updDependencyList(returnList, depend);
1070                 }
1071             }
1072         }
1073
1074         return returnList;
1075     }
1076
1077     /**
1078      * Upd dependency list.
1079      *
1080      * @param returnList the return list
1081      * @param depend the depend
1082      */
1083     private void updDependencyList(ArrayList<String> returnList, String depend) {
1084         if (!returnList.contains(depend) && !depend.isEmpty()) {
1085             returnList.add(depend.trim());
1086         }
1087     }
1088
1089     /**
1090      * Parses the TOSCA model.
1091      *
1092      * @param fileName the file name
1093      * @return the string
1094      */
1095     public String parseTosca(String fileName) {
1096         Map<String, String> map = new LinkedHashMap<>();
1097         try {
1098             map = load(fileName);
1099             if (map != null && map.get(ERROR) != null) {
1100                 return map.get(ERROR);
1101             }
1102             parseDataAndPolicyNodes(map);
1103             LinkedHashMap<String, String> dataMapForJson = parseDataNodes(map);
1104             constructJsonForDataFields(dataMapForJson);
1105             LinkedHashMap<String, LinkedHashMap<String, String>> mapKey = parsePolicyNodes(map);
1106             createAttributes(mapKey);
1107
1108         } catch (IOException e) {
1109             logger.error(e);
1110         } catch (ParserException e) {
1111             logger.error(e);
1112             return e.getMessage();
1113         }
1114
1115         return null;
1116     }
1117
1118     /**
1119      * Load.
1120      *
1121      * @param fileName the file name
1122      * @return the map
1123      * @throws IOException Signals that an I/O exception has occurred.
1124      * @throws ParserException the parser exception
1125      */
1126     public Map<String, String> load(String fileName) throws IOException, ParserException {
1127         File newConfiguration = new File(fileName);
1128         StringBuilder orderInfo = new StringBuilder("[");
1129         Yaml yaml = new Yaml();
1130         LinkedHashMap<Object, Object> yamlMap = null;
1131         try (InputStream is = new FileInputStream(newConfiguration)) {
1132             yamlMap = yaml.load(is);
1133         } catch (FileNotFoundException e) {
1134             logger.error(e);
1135         } catch (Exception e) {
1136             logger.error(e);
1137             throw new ParserException("Invalid TOSCA Model format. Please make sure it is a valid YAML file");
1138         }
1139
1140         LinkedHashMap<String, String> settings = new LinkedHashMap<>();
1141         if (yamlMap == null) {
1142             return settings;
1143         }
1144
1145         String message = validations(yamlMap);
1146
1147         if (message != null) {
1148             settings.put(ERROR, message);
1149             return settings;
1150         }
1151
1152         findNode(yamlMap);
1153
1154         if (!isDuplicatedAttributes && orderedElements != null && !orderedElements.isEmpty()) {
1155             orderedElements.stream().forEach(string -> {
1156                 orderInfo.append(string);
1157                 orderInfo.append(",");
1158                 logger.info("Content: " + string);
1159             });
1160
1161             orderInfo.append("]");
1162
1163             dataOrderInfo = orderInfo.toString();
1164             dataOrderInfo = dataOrderInfo.replace(",]", "]");
1165
1166             logger.info("dataOrderInfo :" + dataOrderInfo);
1167         }
1168
1169         List<String> path = new ArrayList<>();
1170         serializeMap(settings, new StringBuilder(), path, yamlMap);
1171         return settings;
1172     }
1173
1174     /**
1175      * Validations.
1176      *
1177      * @param yamlMap the yaml map
1178      * @return the string
1179      */
1180     @SuppressWarnings("unchecked")
1181     private String validations(@SuppressWarnings("rawtypes") Map yamlMap) {
1182
1183         boolean isNoteTypeFound = false;
1184         boolean isDataTypeFound = false;
1185         boolean isToscaVersionKeyFound = false;
1186         boolean isToscaVersionValueFound = false;
1187         @SuppressWarnings("rawtypes")
1188         Map m1 = new HashMap();
1189         short order = 0;
1190         if (yamlMap != null) {
1191             // Get a set of the entries
1192             @SuppressWarnings("rawtypes")
1193             Set<Entry> entries = yamlMap.entrySet();
1194             for (Map.Entry<Object, Object> me : entries) {
1195                 if (TOSCA_SIMPLE_YAML_1_0_0.equals(me.getValue())) {
1196                     isToscaVersionValueFound = true;
1197                 }
1198
1199                 switch (me.getKey().toString()) {
1200                     case TOSCA_DEFINITION_VERSION:
1201                         isToscaVersionKeyFound = true;
1202                         order++;
1203                         m1.put(TOSCA_DEFINITION_VERSION, order);
1204                         break;
1205                     case NODE_TYPE:
1206                         isNoteTypeFound = true;
1207                         order++;
1208                         m1.put(NODE_TYPE, order);
1209                         break;
1210                     case DATA_TYPE:
1211                         isDataTypeFound = true;
1212                         order++;
1213                         m1.put(DATA_TYPE, order);
1214                         break;
1215                     case JSON_MODEL:
1216                         setJsonRuleFormation(me.getValue().toString());
1217                         break;
1218                     default:
1219                         break;
1220                 }
1221             }
1222             if (!isDataTypeFound) {
1223                 return "data_types are missing or invalid.";
1224             }
1225             if (!isToscaVersionKeyFound || !isToscaVersionValueFound) {
1226                 return "tosca_definitions_version is missing or invalid.";
1227             }
1228
1229             if (!isNoteTypeFound) {
1230                 return "node_types are missing or invalid.";
1231             }
1232
1233             short version = (short) m1.get(TOSCA_DEFINITION_VERSION);
1234
1235             if (version > 1) {
1236                 return "tosca_definitions_version should be defined first.";
1237             }
1238
1239             short data = (short) m1.get(DATA_TYPE);
1240             short node = (short) m1.get(NODE_TYPE);
1241             if (isDataTypeFound && node > data) {
1242                 return "node_types should be defined before data_types.";
1243             }
1244
1245         }
1246
1247         return null;
1248     }
1249
1250     /**
1251      * Serialize map.
1252      *
1253      * @param settings the settings
1254      * @param sb the sb
1255      * @param path the path
1256      * @param yamlMap the yaml map
1257      */
1258     @SuppressWarnings(
1259         { "unchecked", "rawtypes" })
1260     private void serializeMap(LinkedHashMap<String, String> settings, StringBuilder sb, List<String> path,
1261                     Map<Object, Object> yamlMap) {
1262         for (Map.Entry<Object, Object> entry : yamlMap.entrySet()) {
1263
1264             if (entry.getValue() instanceof Map) {
1265                 path.add((String) entry.getKey());
1266                 serializeMap(settings, sb, path, (Map<Object, Object>) entry.getValue());
1267                 path.remove(path.size() - 1);
1268             } else if (entry.getValue() instanceof List) {
1269                 path.add((String) entry.getKey());
1270                 serializeList(settings, sb, path, (List) entry.getValue());
1271                 path.remove(path.size() - 1);
1272             } else {
1273                 serializeValue(settings, sb, path, (String) entry.getKey(), entry.getValue());
1274             }
1275         }
1276     }
1277
1278     /**
1279      * Serialize list.
1280      *
1281      * @param settings the settings
1282      * @param sb the sb
1283      * @param path the path
1284      * @param yamlList the yaml list
1285      */
1286     @SuppressWarnings("unchecked")
1287     private void serializeList(LinkedHashMap<String, String> settings, StringBuilder sb, List<String> path,
1288                     List<String> yamlList) {
1289         int counter = 0;
1290         for (Object listEle : yamlList) {
1291             if (listEle instanceof Map) {
1292                 path.add(Integer.toString(counter));
1293                 serializeMap(settings, sb, path, (Map<Object, Object>) listEle);
1294                 path.remove(path.size() - 1);
1295             } else if (listEle instanceof List) {
1296                 path.add(Integer.toString(counter));
1297                 serializeList(settings, sb, path, (List<String>) listEle);
1298                 path.remove(path.size() - 1);
1299             } else {
1300                 serializeValue(settings, sb, path, Integer.toString(counter), listEle);
1301             }
1302             counter++;
1303         }
1304     }
1305
1306     /**
1307      * Serialize value.
1308      *
1309      * @param settings the settings
1310      * @param sb the sb
1311      * @param path the path
1312      * @param name the name
1313      * @param value the value
1314      */
1315     private void serializeValue(LinkedHashMap<String, String> settings, StringBuilder sb, List<String> path,
1316                     String name, Object value) {
1317         if (value == null) {
1318             return;
1319         }
1320         sb.setLength(0);
1321         for (String pathEle : path) {
1322             sb.append(pathEle).append('.');
1323         }
1324         sb.append(name);
1325         settings.put(sb.toString(), value.toString());
1326     }
1327
1328     /**
1329      * Parses the data and policy nodes.
1330      *
1331      * @param map the map
1332      */
1333     void parseDataAndPolicyNodes(Map<String, String> map) {
1334         for (String key : map.keySet()) {
1335             if (key.contains("policy.nodes.Root")) {
1336                 continue;
1337             } else if (key.contains("policy.nodes")) {
1338                 String wordToFind = "policy.nodes.";
1339                 int indexForPolicyNode = key.indexOf(wordToFind);
1340                 String subNodeString = key.substring(indexForPolicyNode + 13, key.length());
1341
1342                 stringBetweenDots(subNodeString);
1343             } else if (key.contains("policy.data")) {
1344                 String wordToFind = "policy.data.";
1345                 int indexForPolicyNode = key.indexOf(wordToFind);
1346                 String subNodeString = key.substring(indexForPolicyNode + 12, key.length());
1347
1348                 stringBetweenDotsForDataFields(subNodeString);
1349             }
1350         }
1351     }
1352
1353     /**
1354      * String between dots.
1355      *
1356      * @param str the str
1357      * @return the int
1358      */
1359     // Second index of dot should be returned.
1360     public int stringBetweenDots(String str) {
1361         String stringToSearch = str;
1362         String[] ss = stringToSearch.split("\\.");
1363         if (ss != null) {
1364             int len = ss.length;
1365             if (len > 2) {
1366                 uniqueKeys.add(ss[2]);
1367             }
1368         }
1369
1370         return uniqueKeys.size();
1371     }
1372
1373     /**
1374      * String between dots for data fields.
1375      *
1376      * @param str the str
1377      */
1378     public void stringBetweenDotsForDataFields(String str) {
1379         String stringToSearch = str;
1380         String[] ss = stringToSearch.split("\\.");
1381         if (ss != null) {
1382             int len = ss.length;
1383
1384             if (len > 2) {
1385                 uniqueDataKeys.add(ss[0] + "%" + ss[2]);
1386             }
1387         }
1388     }
1389
1390     /**
1391      * Construct json for data fields.
1392      *
1393      * @param dataMapForJson the data map for json
1394      */
1395     void constructJsonForDataFields(LinkedHashMap<String, String> dataMapForJson) {
1396         LinkedHashMap<String, LinkedHashMap<String, String>> dataMapKey = new LinkedHashMap<>();
1397         LinkedHashMap<String, String> hmSub;
1398         for (Map.Entry<String, String> entry : dataMapForJson.entrySet()) {
1399             String uniqueDataKey = entry.getKey();
1400             String[] uniqueDataKeySplit = uniqueDataKey.split("%");
1401             String value = dataMapForJson.get(uniqueDataKey);
1402             if (dataMapKey.containsKey(uniqueDataKeySplit[0])) {
1403                 hmSub = dataMapKey.get(uniqueDataKeySplit[0]);
1404                 hmSub.put(uniqueDataKeySplit[1], value);
1405             } else {
1406                 hmSub = new LinkedHashMap<>();
1407                 hmSub.put(uniqueDataKeySplit[1], value);
1408             }
1409
1410             dataMapKey.put(uniqueDataKeySplit[0], hmSub);
1411         }
1412
1413         JSONObject mainObject = new JSONObject();
1414         JSONObject json;
1415         for (Map.Entry<String, LinkedHashMap<String, String>> entry : dataMapKey.entrySet()) {
1416             String keyString = entry.getKey();
1417             json = new JSONObject();
1418             HashMap<String, String> jsonHm = dataMapKey.get(keyString);
1419             for (Map.Entry<String, String> entryMap : jsonHm.entrySet()) {
1420                 String key = entryMap.getKey();
1421                 json.put(key, jsonHm.get(key));
1422             }
1423             mainObject.put(keyString, json);
1424         }
1425         Iterator<String> keysItr = mainObject.keys();
1426         while (keysItr.hasNext()) {
1427             String key = keysItr.next();
1428             String value = mainObject.get(key).toString();
1429             retmap.put(key, value);
1430         }
1431
1432         logger.info("#############################################################################");
1433         logger.info(mainObject);
1434         logger.info("###############################################################################");
1435     }
1436
1437     /**
1438      * Parses the data nodes.
1439      *
1440      * @param map the map
1441      * @return the linked hash map
1442      */
1443     LinkedHashMap<String, String> parseDataNodes(Map<String, String> map) {
1444         LinkedHashMap<String, String> dataMapForJson = new LinkedHashMap<>();
1445         matchableValues = new HashMap<>();
1446         for (String uniqueDataKey : uniqueDataKeys) {
1447             if (uniqueDataKey.contains("%")) {
1448                 String[] uniqueDataKeySplit = uniqueDataKey.split("%");
1449                 String findType = DATATYPE + uniqueDataKeySplit[0] + PROPERTIES + uniqueDataKeySplit[1] + TYPE;
1450                 String typeValue = map.get(findType);
1451                 logger.info(typeValue);
1452
1453                 String findRequired = DATATYPE + uniqueDataKeySplit[0] + PROPERTIES + uniqueDataKeySplit[1] + REQUIRED;
1454                 String requiredValue = map.get(findRequired);
1455
1456                 String matchable = DATATYPE + uniqueDataKeySplit[0] + PROPERTIES + uniqueDataKeySplit[1] + MATCHABLE;
1457
1458                 String matchableValue = map.get(matchable);
1459
1460                 if ("true".equalsIgnoreCase(matchableValue)) {
1461                     String key = uniqueDataKeySplit[uniqueDataKeySplit.length - 1];
1462                     matchableValues.put(key, MATCHINGTRUE);
1463                 }
1464
1465                 if (requiredValue == null || requiredValue.isEmpty()) {
1466                     requiredValue = "false";
1467                 }
1468                 if (INTEGER.equalsIgnoreCase(typeValue) || STRING.equalsIgnoreCase(typeValue)
1469                                 || typeValue.equalsIgnoreCase(BOOLEAN)) {
1470                     String findDefault = DATATYPE + uniqueDataKeySplit[0] + PROPERTIES + uniqueDataKeySplit[1]
1471                                     + DEFAULT;
1472                     String defaultValue = map.get(findDefault);
1473                     logger.info("defaultValue is:" + defaultValue);
1474                     logger.info("requiredValue is:" + requiredValue);
1475
1476                     StringBuilder attributeIndividualStringBuilder = new StringBuilder();
1477                     attributeIndividualStringBuilder.append(typeValue + DEFAULTVALUE);
1478                     attributeIndividualStringBuilder.append(defaultValue + REQUIREDVALUE);
1479                     attributeIndividualStringBuilder.append(requiredValue + MANYFALSE);
1480
1481                     String findDescription = DATATYPE + uniqueDataKeySplit[0] + PROPERTIES + uniqueDataKeySplit[1]
1482                                     + DESCRIPTION;
1483                     attributeIndividualStringBuilder.append(DESCRIPTION_TOKEN + map.get(findDescription));
1484                     dataMapForJson.put(uniqueDataKey, attributeIndividualStringBuilder.toString());
1485                 } else if (LIST.equalsIgnoreCase(typeValue) || MAP.equalsIgnoreCase(typeValue)) {
1486                     logger.info("requiredValue is:" + requiredValue);
1487                     String findList = DATATYPE + uniqueDataKeySplit[0] + PROPERTIES + uniqueDataKeySplit[1]
1488                                     + ".entry_schema.type";
1489                     String findDefaultValue = DATATYPE + uniqueDataKeySplit[0] + PROPERTIES + uniqueDataKeySplit[1]
1490                                     + ".entry_schema.default";
1491                     String findDescription = DATATYPE + uniqueDataKeySplit[0] + PROPERTIES + uniqueDataKeySplit[1]
1492                                     + ".entry_schema.description";
1493                     String listValue = map.get(findList);
1494                     String defaultValue = map.get(findDefaultValue);
1495                     String description = map.get(findDescription);
1496                     if (listValue != null) {
1497                         logger.info("Type of list is:" + listValue);
1498                         // Its userdefined
1499                         if (listValue.contains(".")) {
1500                             String trimValue = listValue.substring(listValue.lastIndexOf('.') + 1);
1501                             StringBuilder referenceIndividualStringBuilder = new StringBuilder();
1502                             referenceIndividualStringBuilder.append(trimValue + REQUIREDVALUE);
1503                             referenceIndividualStringBuilder.append(requiredValue + MANYTRUE);
1504                             referenceIndividualStringBuilder.append(DESCRIPTION_TOKEN + description);
1505                             dataMapForJson.put(uniqueDataKey, referenceIndividualStringBuilder.toString());
1506                         } else { // Its string
1507                             StringBuilder stringListItems = new StringBuilder();
1508                             if (LIST.equalsIgnoreCase(typeValue)) {
1509                                 stringListItems.append(uniqueDataKeySplit[1].toUpperCase() + DEFAULTVALUE + defaultValue
1510                                                 + REQUIREDVALUE + requiredValue + MANYFALSE + DESCRIPTION_TOKEN
1511                                                 + description);
1512                             } else if (MAP.equalsIgnoreCase(typeValue)) {
1513                                 stringListItems.append(uniqueDataKeySplit[1].toUpperCase() + DEFAULTVALUE + defaultValue
1514                                                 + REQUIREDVALUE + requiredValue + MANYTRUE + DESCRIPTION_TOKEN
1515                                                 + description);
1516                             }
1517                             dataMapForJson.put(uniqueDataKey, stringListItems.toString());
1518                             dataListBuffer.append(uniqueDataKeySplit[1].toUpperCase() + "=[");
1519                             for (int i = 0; i < 10; i++) {
1520                                 String findConstraints = DATATYPE + uniqueDataKeySplit[0] + PROPERTIES
1521                                                 + uniqueDataKeySplit[1] + ".entry_schema.constraints.0.valid_values."
1522                                                 + i;
1523                                 String constraintsValue = map.get(findConstraints);
1524                                 logger.info(constraintsValue);
1525                                 boolean ruleCheck = false;
1526                                 if (constraintsValue == null) {
1527                                     break;
1528                                 } else if (constraintsValue.startsWith(DICTIONARY)) {
1529                                     List<Object> dictFromDB = null;
1530                                     String[] dictionaryNameValRule;
1531                                     String[] dictionaryName = constraintsValue.split(":");
1532                                     String dictionaryNameVal = dictionaryName[1];
1533                                     if (dictionaryNameVal.contains("#Rules")) {
1534                                         ruleCheck = true;
1535                                         dictionaryNameValRule = dictionaryNameVal.split("#");
1536                                         dictFromDB = commonClassDao.getDataById(DictionaryData.class, DICTIONARYNAME,
1537                                                         dictionaryNameValRule[0]);
1538                                     } else {
1539                                         dictFromDB = commonClassDao.getDataById(DictionaryData.class, DICTIONARYNAME,
1540                                                         dictionaryName[1]);
1541                                     }
1542                                     if (dictFromDB != null && !dictFromDB.isEmpty()) {
1543                                         DictionaryData data = (DictionaryData) dictFromDB.get(0);
1544                                         if (ruleCheck) {
1545                                             constraintsValue = DICTIONARY + data.getDictionaryUrl() + "@"
1546                                                             + data.getDictionaryDataByName() + "&Rule";
1547                                         } else {
1548                                             constraintsValue = DICTIONARY + data.getDictionaryUrl() + "@"
1549                                                             + data.getDictionaryDataByName();
1550                                         }
1551                                     }
1552                                     dataListBuffer.append(constraintsValue + ",");
1553                                 } else {
1554                                     logger.info("constraintsValue => " + constraintsValue);
1555                                     if (constraintsValue.contains("=")) {
1556                                         constraintsValue = constraintsValue.replace("=", "equal-sign");
1557                                     }
1558                                     dataConstraints.add(constraintsValue);
1559                                     dataListBuffer.append(constraintsValue + ",");
1560                                 }
1561                             }
1562                             dataListBuffer.append("]#");
1563                             logger.info(dataListBuffer);
1564                         }
1565                     }
1566                 } else {
1567                     String findUserDefined = DATATYPE + uniqueDataKeySplit[0] + "." + PROPERTIES_KEY + "."
1568                                     + uniqueDataKeySplit[1] + TYPE;
1569                     String findDescription = DATATYPE + uniqueDataKeySplit[0] + "." + PROPERTIES_KEY + "."
1570                                     + uniqueDataKeySplit[1] + DESCRIPTION;
1571                     String userDefinedValue = map.get(findUserDefined);
1572                     String description = map.get(findDescription);
1573                     String trimValue = userDefinedValue.substring(userDefinedValue.lastIndexOf('.') + 1);
1574                     StringBuilder referenceIndividualStringBuilder = new StringBuilder();
1575                     referenceIndividualStringBuilder.append(trimValue + REQUIREDVALUE);
1576                     referenceIndividualStringBuilder.append(requiredValue + MANYFALSE);
1577                     referenceIndividualStringBuilder.append(DESCRIPTION_TOKEN + description);
1578                     dataMapForJson.put(uniqueDataKey, referenceIndividualStringBuilder.toString());
1579
1580                 }
1581             } else {
1582                 matchableValues.put(uniqueDataKey, MATCHINGTRUE);
1583             }
1584         }
1585
1586         return dataMapForJson;
1587     }
1588
1589     /**
1590      * Parses the policy nodes.
1591      *
1592      * @param map the map
1593      * @return the linked hash map
1594      * @throws ParserException the parser exception
1595      */
1596     LinkedHashMap<String, LinkedHashMap<String, String>> parsePolicyNodes(Map<String, String> map)
1597                     throws ParserException {
1598         LinkedHashMap<String, LinkedHashMap<String, String>> mapKey = new LinkedHashMap<>();
1599         for (String uniqueKey : uniqueKeys) {
1600             LinkedHashMap<String, String> hm;
1601
1602             for (Entry<String, String> entry : map.entrySet()) {
1603                 String key = entry.getKey();
1604                 if (key.contains(uniqueKey) && key.contains("policy.nodes")) {
1605                     if (mapKey.containsKey(uniqueKey)) {
1606                         hm = mapKey.get(uniqueKey);
1607                         String keyStr = key.substring(key.lastIndexOf('.') + 1);
1608                         String valueStr = map.get(key);
1609                         if ("type".equalsIgnoreCase(keyStr) && key.contains("entry_schema.0.type")
1610                                         || key.contains("entry_schema.type") && valueStr.contains("policy.data.")) {
1611                             throw new ParserException("For user defined object type,"
1612                                             + " Please make sure no space between 'type:' and object " + valueStr);
1613
1614                         }
1615                         if ("type".equals(keyStr)) {
1616                             if (!key.contains("entry_schema")) {
1617                                 hm.put(keyStr, valueStr);
1618                             }
1619                         } else {
1620                             hm.put(keyStr, valueStr);
1621                         }
1622
1623                     } else {
1624                         hm = new LinkedHashMap<>();
1625                         String keyStr = key.substring(key.lastIndexOf('.') + 1);
1626                         String valueStr = map.get(key);
1627
1628                         if (("type").equals(keyStr)) {
1629                             if (!key.contains("entry_schema")) {
1630                                 hm.put(keyStr, valueStr);
1631                             }
1632                         } else {
1633                             hm.put(keyStr, valueStr);
1634                         }
1635                         mapKey.put(uniqueKey, hm);
1636                     }
1637                 }
1638             }
1639         }
1640         return mapKey;
1641     }
1642
1643     /**
1644      * Creates the attributes.
1645      *
1646      * @param mapKey the map key
1647      */
1648     private void createAttributes(LinkedHashMap<String, LinkedHashMap<String, String>> mapKey) {
1649         StringBuilder attributeStringBuilder = new StringBuilder();
1650         StringBuilder referenceStringBuilder = new StringBuilder();
1651         StringBuilder listBuffer = new StringBuilder();
1652         List<String> constraints = new ArrayList<>();
1653         for (Map.Entry<String, LinkedHashMap<String, String>> entry : mapKey.entrySet()) {
1654             String keySetString = entry.getKey();
1655             LinkedHashMap<String, String> keyValues = mapKey.get(keySetString);
1656             if (keyValues.get("type") != null && (STRING.equalsIgnoreCase(keyValues.get("type"))
1657                             || INTEGER.equalsIgnoreCase(keyValues.get("type"))
1658                             || BOOLEAN.equalsIgnoreCase(keyValues.get("type")))) {
1659                 StringBuilder attributeIndividualStringBuilder = new StringBuilder();
1660                 attributeIndividualStringBuilder.append(keySetString + "=");
1661                 attributeIndividualStringBuilder.append(keyValues.get("type") + DEFAULTVALUE);
1662                 attributeIndividualStringBuilder.append(keyValues.get("default") + REQUIREDVALUE);
1663                 attributeIndividualStringBuilder.append(keyValues.get("required") + MANYFALSE);
1664                 attributeIndividualStringBuilder.append(DESCRIPTION_TOKEN + keyValues.get(DESCRIPTION_KEY));
1665                 attributeStringBuilder.append(attributeIndividualStringBuilder + ",");
1666                 if (keyValues.get(MATCHABLEKEY) != null && "true".equalsIgnoreCase(keyValues.get(MATCHABLEKEY))) {
1667                     matchableValues.put(keySetString, MATCHINGTRUE);
1668                 }
1669             } else if (LIST.equalsIgnoreCase(keyValues.get("type"))) {
1670                 if ("true".equalsIgnoreCase(keyValues.get(MATCHABLEKEY))) {
1671                     matchableValues.put(keySetString, MATCHINGTRUE);
1672                 }
1673                 // List Data type
1674                 Set<String> keys = keyValues.keySet();
1675                 Iterator<String> itr = keys.iterator();
1676                 boolean isDefinedType = false;
1677                 while (itr.hasNext()) {
1678                     String key = itr.next();
1679                     if ((!("type").equals(key) || ("required").equals(key))) {
1680                         String value = keyValues.get(key);
1681                         // The "." in the value determines if its a string or a user defined type.
1682                         if (!value.contains(".")) {
1683                             // This is string
1684                             if (StringUtils.isNumeric(key)) { // only integer key for the value of Constrains
1685                                 constraints.add(keyValues.get(key));
1686                             }
1687                         } else {
1688                             // This is user defined type
1689                             String trimValue = value.substring(value.lastIndexOf('.') + 1);
1690                             StringBuilder referenceIndividualStringBuilder = new StringBuilder();
1691                             referenceIndividualStringBuilder.append(keySetString + "=" + trimValue + MANYTRUE
1692                                             + DESCRIPTION_TOKEN + keyValues.get(DESCRIPTION_KEY));
1693                             referenceStringBuilder.append(referenceIndividualStringBuilder + ",");
1694                             isDefinedType = true;
1695                         }
1696                     }
1697
1698                 }
1699
1700                 if (!isDefinedType && LIST.equalsIgnoreCase(keyValues.get("type"))
1701                                 && (constraints == null || constraints.isEmpty())) {
1702                     referenceStringBuilder.append(keySetString + "=MANY-true" + ",");
1703                 }
1704             } else {
1705                 // User defined Datatype.
1706                 if ("true".equalsIgnoreCase(keyValues.get(MATCHABLEKEY))) {
1707                     matchableValues.put(keySetString, MATCHINGTRUE);
1708                 }
1709                 String value = keyValues.get("type");
1710                 if (value != null && !value.isEmpty()) {
1711                     String trimValue = value.substring(value.lastIndexOf('.') + 1);
1712                     StringBuilder referenceIndividualStringBuilder = new StringBuilder();
1713                     referenceIndividualStringBuilder.append(keySetString + "=" + trimValue + MANYFALSE
1714                                     + DESCRIPTION_TOKEN + keyValues.get(DESCRIPTION_KEY));
1715                     referenceStringBuilder.append(referenceIndividualStringBuilder + ",");
1716                 } else {
1717                     logger.info("keyValues.get(type) is null/empty");
1718                 }
1719
1720             }
1721             if (constraints != null && !constraints.isEmpty()) {
1722                 // List handling.
1723                 listBuffer.append(keySetString.toUpperCase() + "=[");
1724                 for (String str : constraints) {
1725                     if (str.contains(DICTIONARY)) {
1726                         String[] dictionaryName = str.split(":");
1727                         List<Object> dictFromDB = commonClassDao.getDataById(DictionaryData.class, DICTIONARYNAME,
1728                                         dictionaryName[1]);
1729                         if (dictFromDB != null && !dictFromDB.isEmpty()) {
1730                             DictionaryData data = (DictionaryData) dictFromDB.get(0);
1731                             str = DICTIONARY + data.getDictionaryUrl() + "@" + data.getDictionaryDataByName();
1732                         }
1733                     }
1734                     listBuffer.append(str + ",");
1735                 }
1736                 listBuffer.append("]#");
1737                 logger.info(listBuffer);
1738
1739                 StringBuilder referenceIndividualStringBuilder = new StringBuilder();
1740                 referenceIndividualStringBuilder.append(keySetString + "=" + keySetString.toUpperCase() + MANYFALSE);
1741                 referenceStringBuilder.append(referenceIndividualStringBuilder + ",");
1742                 constraints.clear();
1743             }
1744         }
1745
1746         dataListBuffer.append(listBuffer);
1747
1748         logger.info("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
1749         logger.info("Whole attribute String is:" + attributeStringBuilder);
1750         logger.info("Whole reference String is:" + referenceStringBuilder);
1751         logger.info("List String is:" + listBuffer);
1752         logger.info("Data list buffer is:" + dataListBuffer);
1753         logger.info("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
1754
1755         this.listConstraints = dataListBuffer.toString();
1756         this.referenceAttributes = referenceStringBuilder.toString();
1757         this.attributeString = attributeStringBuilder.toString();
1758     }
1759
1760     /**
1761      * Find node.
1762      *
1763      * @param map the map
1764      */
1765     @SuppressWarnings("unchecked")
1766     private void findNode(LinkedHashMap<Object, Object> map) {
1767
1768         map.forEach((key, value) -> {
1769             // if the value is properties and its type is map object, then save all the keys
1770             if (key.equals(PROPERTIES_KEY) && value instanceof Map) {
1771                 saveNodes((LinkedHashMap<?, ?>) value);
1772                 if (isDuplicatedAttributes) {
1773                     orderedElements = new ArrayList<>();
1774                     return;
1775                 }
1776             }
1777
1778             if (!"policy.nodes.Root".equals(key) && value instanceof Map) {
1779                 // value is a Map object, then make a recursive call
1780                 findNode((LinkedHashMap<Object, Object>) value);
1781             }
1782         });
1783
1784     }
1785
1786     /**
1787      * Save nodes.
1788      *
1789      * @param map the map
1790      */
1791     private void saveNodes(LinkedHashMap<?, ?> map) {
1792
1793         for (Entry<?, ?> entry : map.entrySet()) {
1794
1795             if (orderedElements.indexOf(entry.getKey()) >= 0) { // duplicated attribute names
1796                 isDuplicatedAttributes = true;
1797                 return;
1798             } else {
1799                 orderedElements.add((String) entry.getKey());
1800             }
1801         }
1802     }
1803 }