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