Fix nested stmts issue of Sonar
[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-2018 AT&T Intellectual Property. All rights reserved.
6  * Modified Copyright (C) 2018 Samsung Electronics Co., Ltd.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  * 
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  * 
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.rest.util;
23
24 import com.att.research.xacml.util.XACMLProperties;
25 import com.google.gson.Gson;
26 import org.apache.commons.lang.StringUtils;
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.eclipse.emf.common.util.*;
30 import org.eclipse.emf.ecore.*;
31 import org.eclipse.emf.ecore.impl.EAttributeImpl;
32 import org.eclipse.emf.ecore.impl.EEnumImpl;
33 import org.eclipse.emf.ecore.resource.Resource;
34 import org.eclipse.emf.ecore.resource.ResourceSet;
35 import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
36 import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
37 import org.json.JSONObject;
38 import org.onap.policy.rest.XACMLRestProperties;
39 import org.yaml.snakeyaml.Yaml;
40
41 import java.io.*;
42 import java.util.*;
43 import java.util.Map.Entry;
44
45
46 public class MSModelUtils {
47
48     private static final Log logger     = LogFactory.getLog(MSModelUtils.class);
49
50     private HashMap<String,MSAttributeObject > classMap = new HashMap<>();
51     private HashMap<String, String> enumMap = new HashMap<>();
52     private HashMap<String, String> matchingClass = new HashMap<>();
53     private String configuration = "configuration";
54     private String dictionary = "dictionary";
55     private String onap = "";
56     private String policy = "";
57     private String eProxyURI = "eProxyURI:";
58     private List<String> orderedElements = new ArrayList<>();
59     private String dataOrderInfo = null;
60     private Set<String> uniqueDataKeys= new HashSet<>();
61     private Set<String> uniqueKeys= new HashSet<>();
62     private String listConstraints = null;
63     private String referenceAttributes;
64     private LinkedHashMap<String, Object> retmap = new LinkedHashMap<>();
65     private Map<String, String>  matchableValues;
66     private static final String PROPERTIES=".properties.";
67     public static final String DATATYPE  = "data_types.policy.data.";
68     public static final String TYPE=".type";
69     public static final String REQUIRED=".required";
70     private static final String MATCHABLE=".matchable";
71     private static final String STRING="string";
72     private static final String INTEGER="integer";
73     private static final String LIST="list";
74     public static final String MAP="map";
75     private static final String DEFAULT=".default";
76     private static final String MANYFALSE=":MANY-false";
77     private static final String MANYTRUE=":MANY-true";
78     private static final String DEFAULTVALUE=":defaultValue-";
79     private static final String REQUIREDVALUE=":required-";
80     private static final String MATCHABLEKEY="matchable";
81     private static final String REQUIREDFALSE=":required-false";
82     private static final String REQUIREDTRUE=":required-true";
83     private static final String MATCHINGTRUE="matching-true";
84
85     private StringBuilder dataListBuffer=new StringBuilder();
86     private List<String> dataConstraints= new ArrayList <>();
87     private String attributeString = null;
88
89     public MSModelUtils(){
90     }
91
92     public MSModelUtils(String onap, String policy){
93         this.onap = onap;
94         this.policy = policy;
95     }
96
97     private enum ANNOTATION_TYPE{
98         MATCHING, VALIDATION, DICTIONARY
99     };
100
101     public enum MODEL_TYPE {
102         XMI
103     };
104
105
106     public Map<String, MSAttributeObject> processEpackage(String file, MODEL_TYPE model){
107         if (model == MODEL_TYPE.XMI ){
108             processXMIEpackage(file);
109         }
110         return classMap;
111
112     }
113
114     private void processXMIEpackage(String xmiFile){
115         EPackage root = getEpackage(xmiFile);
116         TreeIterator<EObject> treeItr = root.eAllContents();
117         String className;
118         String returnValue;
119
120         //    Pulling out dependency from file
121         while (treeItr.hasNext()) {
122             EObject obj = treeItr.next();
123             if (obj instanceof EClassifier) {
124                 EClassifier eClassifier = (EClassifier) obj;
125                 className = eClassifier.getName();
126
127                 if (obj instanceof EEnum) {
128                     enumMap.putAll(getEEnum(obj));
129                 }else if (obj instanceof EClass) {
130                     String temp = getDependencyList(eClassifier).toString();
131                     returnValue = StringUtils.replaceEach(temp, new String[]{"[", "]"}, new String[]{"", ""});
132                     getAttributes(className, returnValue, root);
133                 }
134             }
135         }
136
137         if (!enumMap.isEmpty()){
138             addEnumClassMap();
139         }
140         if (!matchingClass.isEmpty()){
141             CheckForMatchingClass();
142         }
143     }
144
145     private void CheckForMatchingClass() {
146         HashMap<String, String> tempAttribute = new HashMap<>();
147
148         for (Entry<String, String> set : matchingClass.entrySet()){
149             String key = set.getKey();
150             if (classMap.containsKey(key)){
151                 Map<String, String> listAttributes = classMap.get(key).getAttribute();
152                 Map<String, String> listRef = classMap.get(key).getRefAttribute();
153                 for (  Entry<String, String> eSet : listAttributes.entrySet()){
154                     String key2 = eSet.getKey();
155                     tempAttribute.put(key2, MATCHINGTRUE);
156                 }
157                 for (  Entry<String, String> eSet : listRef.entrySet()){
158                     String key3 = eSet.getKey();
159                     tempAttribute.put(key3, MATCHINGTRUE);
160                 }
161
162             }
163             UpdateMatching(tempAttribute, key);
164         }
165
166     }
167
168
169
170     private void UpdateMatching(HashMap<String, String> tempAttribute, String key) {
171         Map<String, MSAttributeObject> newClass = classMap;
172
173         for (Entry<String, MSAttributeObject> updateClass :  newClass.entrySet()){
174             Map<String, String> valueMap = updateClass.getValue().getMatchingSet();
175             String keymap = updateClass.getKey();
176             if (valueMap.containsKey(key)){
177                 Map<String, String> modifyMap = classMap.get(keymap).getMatchingSet();
178                 modifyMap.remove(key);
179                 modifyMap.putAll(tempAttribute);
180                 classMap.get(keymap).setMatchingSet(modifyMap);
181             }
182
183         }
184     }
185
186     private void addEnumClassMap() {
187         for (Entry<String, MSAttributeObject> value :classMap.entrySet()){
188             value.getValue().setEnumType(enumMap);
189         }
190     }
191
192     private EPackage getEpackage(String xmiFile) {
193         ResourceSet resSet = new ResourceSetImpl();
194         Resource.Factory.Registry reg = Resource.Factory.Registry.INSTANCE;
195         Map<String, Object> m = reg.getExtensionToFactoryMap();
196         m.put("xmi", new XMIResourceFactoryImpl());
197         Resource resource = resSet.getResource(URI.createFileURI(xmiFile), true);
198         try {
199             resource.load(Collections.emptyMap());
200         } catch (IOException e) {
201             logger.error("Error loading Encore Resource for new Model" + e);
202         }
203
204         return (EPackage) resource.getContents().get(0);
205     }
206
207     private HashMap<String, String> getEEnum(EObject obj) {
208         List<String> valueList = new ArrayList<>();
209         HashMap<String, String> returnMap = new HashMap<>();
210         EEnum eenum = (EEnum)obj;
211
212         String name = eenum.getName();
213         for (EEnumLiteral eEnumLiteral : eenum.getELiterals())
214         {
215             Enumerator instance = eEnumLiteral.getInstance();
216             String value = instance.getLiteral();
217             valueList.add(value);
218         }
219         returnMap.put(name, valueList.toString());
220         return returnMap;
221     }
222
223     public void getAttributes(String className, String dependency, EPackage root) {
224         List<String> dpendList = new ArrayList<>();
225         if (dependency!=null){
226             dpendList = new ArrayList<>(Arrays.asList(dependency.split(",")));
227         }
228         MSAttributeObject msAttributeObject = new MSAttributeObject();
229         msAttributeObject.setClassName(className);
230         String extendClass = getSubTypes(root, className);
231         Map<String, String> returnRefList = getRefAttributeList(root, className, extendClass);
232         Map<String, String> returnAttributeList = getAttributeList(root, className, extendClass);
233         Map<String, Object> returnSubList = getSubAttributeList(root, className, extendClass);
234         HashMap<String, String> returnAnnotation = getAnnotation(root, className, extendClass);
235         msAttributeObject.setAttribute(returnAttributeList);
236         msAttributeObject.setRefAttribute(returnRefList);
237         msAttributeObject.setSubClass(returnSubList);
238         msAttributeObject.setDependency(dpendList.toString());
239         msAttributeObject.addMatchingSet(returnAnnotation);
240         msAttributeObject.setPolicyTempalate(isPolicyTemplate(root, className));
241
242         this.classMap.put(className, msAttributeObject);
243     }
244
245     private HashMap<String, String> getAnnotation(EPackage root, String className, String extendClass) {
246         TreeIterator<EObject> treeItr = root.eAllContents();
247         boolean requiredAttribute = false;
248         boolean requiredMatchAttribute = false;
249         HashMap<String, String> annotationSet = new HashMap<>();
250
251         //    Pulling out dependency from file
252         while (treeItr.hasNext()) {
253             EObject obj = treeItr.next();
254             if (obj instanceof EClassifier) {
255                 requiredAttribute = isRequiredAttribute(obj,  className );
256                 requiredMatchAttribute = isRequiredAttribute(obj,  extendClass );
257             }
258
259             if (requiredAttribute){
260                 if (obj instanceof EStructuralFeature) {
261                     checkAnnotation(annotationSet, (EStructuralFeature) obj);
262                 }
263             } else if (requiredMatchAttribute && (obj instanceof EStructuralFeature)) {
264                 findMatchingAnnotation(annotationSet, obj);
265             }
266         }
267         return annotationSet;
268     }
269
270     private void findMatchingAnnotation(HashMap<String, String> annotationSet, EObject obj) {
271         EStructuralFeature eStrucClassifier = (EStructuralFeature) obj;
272         if (eStrucClassifier.getEAnnotations().isEmpty()) {
273             return;
274         }
275         String matching  = annotationValue(eStrucClassifier, ANNOTATION_TYPE.MATCHING, policy);
276         if (matching!=null){
277             if (obj instanceof EReference){
278                 EClass refType = ((EReference) obj).getEReferenceType();
279                 annotationSet.put(refType.getName(), matching);
280                 matchingClass.put(refType.getName(), matching);
281             }else{
282                 annotationSet.put(eStrucClassifier.getName(), matching);
283             }
284         }
285
286     }
287
288     private void checkAnnotation(HashMap<String, String> annotationSet, EStructuralFeature obj) {
289         EStructuralFeature eStrucClassifier = obj;
290         if (eStrucClassifier.getEAnnotations().isEmpty()) {
291             return;
292         }
293         String matching  = annotationValue(eStrucClassifier, ANNOTATION_TYPE.MATCHING, policy);
294         if (matching!=null){
295             annotationSet.put(eStrucClassifier.getName(), matching);
296         }
297         String range  = annotationValue(eStrucClassifier, ANNOTATION_TYPE.VALIDATION, policy);
298         if (range!=null){
299             annotationSet.put(eStrucClassifier.getName(), range);
300         }
301         String annotationDict = annotationValue(eStrucClassifier, ANNOTATION_TYPE.DICTIONARY, policy);
302         if (annotationDict!=null){
303             annotationSet.put(eStrucClassifier.getName(), annotationDict);
304         }
305     }
306
307     private Map<String, Object> getSubAttributeList(EPackage root, String className , String superClass) {
308         TreeIterator<EObject> treeItr = root.eAllContents();
309         boolean requiredAttribute = false;
310         Map<String, Object> subAttribute = new HashMap<>();
311         int rollingCount = 0;
312         int processClass = 0;
313
314         //    Pulling out dependency from file
315         while (treeItr.hasNext() && rollingCount < 2) {
316
317             EObject obj = treeItr.next();
318             if (obj instanceof EClassifier) {
319                 requiredAttribute = isRequiredAttribute(obj,  className ) || isRequiredAttribute(obj,  superClass );
320                 if (requiredAttribute){
321                     processClass++;
322                 }
323                 rollingCount = rollingCount+processClass;
324             }
325
326             if (requiredAttribute && (obj instanceof EStructuralFeature)) {
327                 EStructuralFeature eStrucClassifier = (EStructuralFeature) obj;
328                 if (!eStrucClassifier.getEAnnotations().isEmpty()) {
329                     updateSubAttributes(subAttribute, obj, eStrucClassifier);
330                 }
331             }
332         }
333         return subAttribute;
334     }
335
336     private void updateSubAttributes(Map<String, Object> subAttribute, EObject obj, EStructuralFeature eStrucClassifier) {
337         if (!(obj instanceof EReference)) {
338             return;
339         }
340         if (annotationTest(eStrucClassifier, configuration, onap)) {
341             EClass refType = ((EReference) obj).getEReferenceType();
342             if(!refType.toString().contains(eProxyURI)){
343                 String required = REQUIREDFALSE;
344                 if(eStrucClassifier.getLowerBound() == 1){
345                     required = REQUIREDTRUE;
346                 }
347                 subAttribute.put(eStrucClassifier.getName(), refType.getName() + required);
348             }
349         }
350     }
351
352     public String checkDefultValue(String defultValue) {
353         if (defultValue!=null){
354             return DEFAULTVALUE+ defultValue;
355         }
356         return ":defaultValue-NA";
357
358     }
359
360     public String checkRequiredPattern(int upper, int lower) {
361
362         String pattern = XACMLProperties.getProperty(XACMLRestProperties.PROP_XCORE_REQUIRED_PATTERN);
363
364         if (pattern!=null){
365             if (upper == Integer.parseInt(pattern.split(",")[1]) && lower==Integer.parseInt(pattern.split(",")[0])){
366                 return REQUIREDTRUE;
367             }
368         }
369
370         return REQUIREDFALSE;
371     }
372
373     public JSONObject buildJavaObject(Map<String, String> map){
374
375         return  new JSONObject(map);
376     }
377
378     public Map<String, String> getRefAttributeList(EPackage root, String className, String superClass){
379
380         TreeIterator<EObject> treeItr = root.eAllContents();
381         boolean requiredAttribute = false;
382         HashMap<String, String> refAttribute = new HashMap<>();
383         int rollingCount = 0;
384         int processClass = 0;
385         boolean annotation;
386         //    Pulling out dependency from file
387         while (treeItr.hasNext()) {
388             EObject obj = treeItr.next();
389             if (obj instanceof EClassifier) {
390                 requiredAttribute = isRequiredAttribute(obj,  className ) || isRequiredAttribute(obj,  superClass );
391                 if (requiredAttribute){
392                     processClass++;
393                 }
394                 rollingCount = rollingCount+processClass;
395             }
396
397             if (requiredAttribute && (obj instanceof EStructuralFeature)) {
398                     EStructuralFeature eStrucClassifier = (EStructuralFeature) obj;
399                     if (!eStrucClassifier.getEAnnotations().isEmpty()) {
400                         annotation = annotationTest(eStrucClassifier, configuration, onap);
401                         if ( annotation &&  obj instanceof EReference) {
402                             updRefAttributes(refAttribute, (EStructuralFeature) obj, eStrucClassifier);
403                         } else if (annotation &&  obj instanceof EAttributeImpl) {
404                             updEnumTypeRefAttrib(refAttribute, (EStructuralFeature) obj, eStrucClassifier);
405                         }
406                     }
407             }
408         }
409
410         return refAttribute;
411     }
412
413     private void updEnumTypeRefAttrib(HashMap<String, String> refAttribute, EStructuralFeature obj, EStructuralFeature eStrucClassifier) {
414         EClassifier refType = ((EAttributeImpl) obj).getEType();
415         if (!(refType instanceof EEnumImpl)){
416             return;
417         }
418
419         String array = arrayCheck(obj.getUpperBound());
420         String required = REQUIREDFALSE;
421         if(obj.getLowerBound() == 1){
422             required = REQUIREDTRUE;
423         }
424         refAttribute.put(eStrucClassifier.getName(), refType.getName() + array + required);
425     }
426
427     private void updRefAttributes(HashMap<String, String> refAttribute, EStructuralFeature obj, EStructuralFeature eStrucClassifier) {
428         EClass refType = ((EReference) obj).getEReferenceType();
429         if(refType.toString().contains(eProxyURI)){
430             String one = refType.toString().split(eProxyURI)[1];
431             String refValue = StringUtils.replaceEach(one.split("#")[1], new String[]{"//", ")"}, new String[]{"", ""});
432             refAttribute.put(eStrucClassifier.getName(), refValue);
433         } else {
434             String required = REQUIREDFALSE;
435             if(obj.getLowerBound() == 1){
436                 required = REQUIREDTRUE;
437             }
438             refAttribute.put(eStrucClassifier.getName(), refType.getName() + arrayCheck(obj.getUpperBound()) + required);
439         }
440     }
441
442     private boolean annotationTest(EStructuralFeature eStrucClassifier, String annotation, String type) {
443         String annotationType;
444         EAnnotation eAnnotation;
445         String onapType;
446         String onapValue;
447
448         EList<EAnnotation> value = eStrucClassifier.getEAnnotations();
449
450         for (int i = 0; i < value.size(); i++){
451             annotationType = value.get(i).getSource();
452             eAnnotation = eStrucClassifier.getEAnnotations().get(i);
453             onapType = eAnnotation.getDetails().get(0).getValue();
454             onapValue = eAnnotation.getDetails().get(0).getKey();
455
456             if (annotationType.contains(type) && onapType.contains(annotation)){
457                 return true;
458             }
459
460             if (annotationType.contains(type) && onapValue.contains(annotation)){
461                 return true;
462             }
463         }
464
465         return false;
466     }
467
468
469     private String annotationValue(EStructuralFeature eStrucClassifier, ANNOTATION_TYPE annotation, String type) {
470         String annotationType;
471         EAnnotation eAnnotation;
472         String onapType;
473         String onapValue = null;
474
475         EList<EAnnotation> value = eStrucClassifier.getEAnnotations();
476
477         for (int i = 0; i < value.size(); i++){
478             annotationType = value.get(i).getSource();
479             eAnnotation = eStrucClassifier.getEAnnotations().get(i);
480             onapType = eAnnotation.getDetails().get(0).getKey();
481             if (annotationType.contains(type) && onapType.compareToIgnoreCase(annotation.toString())==0){
482                 onapValue = eAnnotation.getDetails().get(0).getValue();
483                 if (annotation == ANNOTATION_TYPE.VALIDATION){
484                     return onapValue;
485                 } else {
486                     return onapType + "-" + onapValue;
487                 }
488             }
489         }
490
491         return onapValue;
492     }
493     public boolean isRequiredAttribute(EObject obj, String className){
494         EClassifier eClassifier = (EClassifier) obj;
495         String workingClass = eClassifier.getName().trim();
496         if (workingClass.equalsIgnoreCase(className)){
497             return  true;
498         }
499
500         return false;
501     }
502
503     private boolean isPolicyTemplate(EPackage root, String className){
504         boolean result = false;
505         for (EClassifier classifier : root.getEClassifiers()){
506             if (classifier instanceof EClass) {
507                 EClass eClass = (EClass)classifier;
508                 if (eClass.getName().contentEquals(className)) {
509                     result = checkPolicyTemplate(eClass);
510                     break;
511                 }
512             }
513         }
514         return result;
515     }
516
517     private boolean checkPolicyTemplate(EClass eClass) {
518         EList<EAnnotation> value = eClass.getEAnnotations();
519         for (EAnnotation workingValue : value){
520             EMap<String, String> keyMap = workingValue.getDetails();
521             if (keyMap.containsKey("policyTemplate")){
522                 return true;
523             }
524         }
525         return false;
526     }
527
528     private String getSubTypes(EPackage root, String className) {
529         String returnSubTypes = null;
530         for (EClassifier classifier : root.getEClassifiers()){
531             if (classifier instanceof EClass) {
532                 returnSubTypes = findSubTypes(className, returnSubTypes, (EClass) classifier);
533             }
534         }
535         return returnSubTypes;
536     }
537
538     private String findSubTypes(String className, String returnSubTypes, EClass classifier) {
539         EClass eClass = classifier;
540
541         for (EClass eSuperType : eClass.getEAllSuperTypes())
542         {
543             if (eClass.getName().contentEquals(className)){
544                 returnSubTypes = eSuperType.getName();
545             }
546         }
547         return returnSubTypes;
548     }
549
550     public Map<String, String> getAttributeList(EPackage root, String className, String superClass){
551
552         TreeIterator<EObject> treeItr = root.eAllContents();
553         boolean requiredAttribute = false;
554         HashMap<String, String> refAttribute = new HashMap<>();
555
556         //    Pulling out dependency from file
557         while (treeItr.hasNext()) {
558             EObject obj = treeItr.next();
559             if (obj instanceof EClassifier) {
560                 requiredAttribute = isRequiredAttribute(obj,  className ) || isRequiredAttribute(obj,  superClass );
561             }
562
563             if (requiredAttribute && (obj instanceof EStructuralFeature)) {
564                 EStructuralFeature eStrucClassifier = (EStructuralFeature) obj;
565                 if (!eStrucClassifier.getEAnnotations().isEmpty()) {
566                     checkStrucClassifier(refAttribute, obj, eStrucClassifier);
567                 }
568             }
569         }
570         return refAttribute;
571
572     }
573
574     private void checkStrucClassifier(HashMap<String, String> refAttribute, EObject obj, EStructuralFeature eStrucClassifier) {
575         EClassifier refType = ((EStructuralFeature) obj).getEType();
576         boolean annotation = annotationTest(eStrucClassifier, configuration, onap);
577         boolean dictionaryTest = annotationTest(eStrucClassifier, dictionary, policy);
578         if (annotation && !(obj instanceof EReference) && !(refType instanceof EEnumImpl)) {
579             updEReferenceAttrib(refAttribute, dictionaryTest, (EStructuralFeature) obj, eStrucClassifier);
580         }
581     }
582
583     private void updEReferenceAttrib(HashMap<String, String> refAttribute, boolean dictionaryTest, EStructuralFeature obj, EStructuralFeature eStrucClassifier) {
584         String eType;
585         String name = eStrucClassifier.getName();
586         if (dictionaryTest){
587             eType = annotationValue(eStrucClassifier, ANNOTATION_TYPE.DICTIONARY, policy);
588         }else {
589             eType = eStrucClassifier.getEType().getInstanceClassName();
590         }
591         String defaultValue = checkDefultValue(obj.getDefaultValueLiteral());
592         String array = arrayCheck(obj.getUpperBound());
593         String required = checkRequiredPattern(obj.getUpperBound(), obj.getLowerBound());
594         refAttribute.put(name, eType + defaultValue + required + array);
595     }
596
597     public String arrayCheck(int upperBound) {
598
599         if (upperBound == -1){
600             return MANYTRUE;
601         }
602
603         return MANYFALSE;
604     }
605
606     public List<String> getDependencyList(EClassifier eClassifier){
607         List<String> returnValue = new ArrayList<>();;
608         EList<EClass> somelist = ((EClass) eClassifier).getEAllSuperTypes();
609         if (somelist.isEmpty()){
610             return returnValue;
611         }
612         for(EClass depend: somelist){
613             if (depend.toString().contains(eProxyURI)){
614                 String one = depend.toString().split(eProxyURI)[1];
615                 String value = StringUtils.replaceEach(one.split("#")[1], new String[]{"//", ")"}, new String[]{"", ""});
616                 returnValue.add(value);
617             }
618         }
619
620         return returnValue;
621     }
622
623     public Map<String, String> buildSubList(Map<String, String> subClassAttributes, Map<String, MSAttributeObject> classMap, String className){
624         Map<String, String> missingValues = new HashMap<>();
625         Map<String, String> workingMap;
626         boolean enumType;
627
628         for ( Entry<String, String> map : classMap.get(className).getRefAttribute().entrySet()){
629             String value = map.getValue().split(":")[0];
630             if (value!=null){
631                 classMap.get(className).getEnumType();
632                 enumType = classMap.get(className).getEnumType().containsKey(value);
633                 if (!enumType){
634                     workingMap =  classMap.get(value).getRefAttribute();
635                     for ( Entry<String, String> subMab : workingMap.entrySet()){
636                         String value2 = subMab.getValue().split(":")[0];
637                         if (!subClassAttributes.containsValue(value2)){
638                             missingValues.put(subMab.getKey(), subMab.getValue());
639                         }
640                     }
641
642                 }
643             }
644         }
645
646         return missingValues;
647     }
648
649     public Map<String, Map<String, String>> recursiveReference(Map<String, MSAttributeObject> classMap, String className){
650
651         Map<String, Map<String, String>> returnObject = new HashMap<>();
652         Map<String, String> returnClass = getRefclass(classMap, className);
653         returnObject.put(className, returnClass);
654         for (Entry<String, String> reAttribute :returnClass.entrySet()){
655             if (reAttribute.getValue().split(":")[1].contains("MANY") &&
656                     classMap.get(reAttribute.getValue().split(":")[0]) != null){
657                     returnObject.putAll(recursiveReference(classMap, reAttribute.getValue().split(":")[0]));
658             }
659
660         }
661
662         return returnObject;
663
664     }
665
666     public String createJson(Map<String, MSAttributeObject> classMap, String className) {
667         boolean enumType;
668         Map<String, Map<String, String>> myObject = new HashMap<>();
669         for ( Entry<String, String> map : classMap.get(className).getRefAttribute().entrySet()){
670             String value = map.getValue().split(":")[0];
671             if (value!=null){
672                 enumType = classMap.get(className).getEnumType().containsKey(value);
673                 if (!enumType && map.getValue().split(":")[1].contains("MANY")){
674                         Map<String, Map<String, String>> testRecursive = recursiveReference(classMap, map.getValue().split(":")[0] );
675                         myObject.putAll(testRecursive);
676                 }
677             }
678         }
679
680         Gson gson = new Gson();
681         return gson.toJson(myObject);
682     }
683
684     public Map<String, String> getRefclass(Map<String, MSAttributeObject> classMap, String className){
685         HashMap<String, String> missingValues = new HashMap<>();
686
687         if (classMap.get(className).getAttribute()!=null || !classMap.get(className).getAttribute().isEmpty()){
688             missingValues.putAll(classMap.get(className).getAttribute());
689         }
690
691         if (classMap.get(className).getRefAttribute()!=null || !classMap.get(className).getRefAttribute().isEmpty()){
692             missingValues.putAll(classMap.get(className).getRefAttribute());
693         }
694
695         return missingValues;
696     }
697
698     public String createSubAttributes(List<String> dependency, Map<String, MSAttributeObject> classMap, String modelName) {
699
700         HashMap <String,  Object>  workingMap = new HashMap<>();
701         MSAttributeObject tempObject;
702         if (dependency!=null){
703             if (dependency.isEmpty()){
704                 return "{}";
705             }
706             dependency.add(modelName);
707             for (String element: dependency){
708                 tempObject = classMap.get(element);
709                 if (tempObject!=null){
710                     workingMap.putAll(classMap.get(element).getSubClass());
711                 }
712             }
713         }
714
715         return createJson(classMap, modelName);
716     }
717
718     public List<String> getFullDependencyList(List<String> dependency, Map<String,MSAttributeObject > classMap) {
719         ArrayList<String> returnList = new ArrayList<>();
720         ArrayList<String> workingList;
721         returnList.addAll(dependency);
722         for (String element : dependency ){
723             if (classMap.containsKey(element)){
724                 MSAttributeObject value = classMap.get(element);
725                 String rawValue = StringUtils.replaceEach(value.getDependency(), new String[]{"[", "]"}, new String[]{"", ""});
726                 workingList = new ArrayList<>(Arrays.asList(rawValue.split(",")));
727                 for(String depend : workingList) {
728                     updDependencyList(returnList, depend);
729                 }
730             }
731         }
732
733         return returnList;
734     }
735
736     private void updDependencyList(ArrayList<String> returnList, String depend) {
737         if (!returnList.contains(depend) && !depend.isEmpty()){
738             returnList.add(depend.trim());
739         }
740     }
741
742     /*
743      * For TOSCA Model
744      */
745     public String parseTosca (String fileName){
746         LinkedHashMap<String,String> map= new LinkedHashMap<>();
747     
748         try {
749             map=load(fileName);
750
751             if(map != null){
752                 if(map.get("error") != null){
753                     return map.get("error");
754                 }
755             }
756
757             parseDataAndPolicyNodes(map);
758
759             LinkedHashMap<String,String> dataMapForJson=parseDataNodes(map);
760
761             constructJsonForDataFields(dataMapForJson);
762
763             LinkedHashMap<String,LinkedHashMap<String,String>> mapKey= parsePolicyNodes(map);
764
765             createAttributes(mapKey);
766
767         } catch (IOException e) {
768             logger.error(e);
769         }catch(ParserException e){
770             logger.error(e);
771             return e.getMessage();
772         }
773
774         return null;
775     }
776
777     @SuppressWarnings("unchecked")
778     public LinkedHashMap<String, String> load(String fileName) throws IOException,ParserException {
779         File newConfiguration = new File(fileName);
780         StringBuilder orderInfo = new StringBuilder("[");
781         Yaml yaml = new Yaml();
782         LinkedHashMap<Object, Object> yamlMap = null;
783         try(InputStream is = new FileInputStream(newConfiguration)){
784             yamlMap = (LinkedHashMap<Object, Object>) yaml.load(is);
785         } catch (FileNotFoundException e) {
786             logger.error(e);
787         }catch(Exception e){
788             throw new ParserException("Invalid TOSCA Model format. Please make sure it is a valid YAML file");
789         }
790
791         StringBuilder sb = new StringBuilder();
792         LinkedHashMap<String, String> settings = new LinkedHashMap<>();
793         if (yamlMap == null) {
794             return settings;
795         }
796
797         String message = validations(yamlMap);
798
799         if(message != null){
800             settings.put("error", message);
801             return settings;
802         }
803
804         findNode(yamlMap);
805
806         orderedElements.stream().forEach((string) -> {
807             orderInfo.append(string);
808             orderInfo.append(",");
809             logger.info("Content: " + string);
810         });
811
812         orderInfo.append("]");
813
814         dataOrderInfo = orderInfo.toString();
815         dataOrderInfo = dataOrderInfo.replace(",]", "]");
816
817         logger.info("dataOrderInfo :" + dataOrderInfo);
818
819         List<String> path = new ArrayList <>();
820         serializeMap(settings, sb, path, yamlMap);
821         return settings;
822     }
823
824     @SuppressWarnings("unchecked")
825     private String validations(@SuppressWarnings("rawtypes") LinkedHashMap yamlMap){
826
827         boolean isNoteTypeFound = false;
828         boolean isDataTypeFound = false;
829         boolean isToscaVersionKeyFound = false;
830         boolean isToscaVersionValueFound = false;
831         @SuppressWarnings("rawtypes")
832         Map m1 = new HashMap();
833         short order =0;
834         if(yamlMap != null){
835             // Get a set of the entries
836              @SuppressWarnings("rawtypes")
837             Set set = yamlMap.entrySet();
838              // Get an iterator
839              @SuppressWarnings("rawtypes")
840             Iterator i = set.iterator();
841               // Display elements
842              while(i.hasNext()) {
843                  @SuppressWarnings("rawtypes")
844                  Entry me = (Entry)i.next();
845
846                  if("tosca_definitions_version".equals(me.getKey())){
847                      isToscaVersionKeyFound = true;
848                      order++;
849                      m1.put("tosca_definitions_version", order);
850                  }
851
852                  if("tosca_simple_yaml_1_0_0".equals(me.getValue())){
853                      isToscaVersionValueFound = true;
854                  }
855
856                  if("node_types".equals(me.getKey())){
857                      isNoteTypeFound = true;
858                      order++;
859                      m1.put("node_types", order);
860                  }
861
862                  if("data_types".equals(me.getKey())){
863                      isDataTypeFound = true;
864                      order++;
865                      m1.put("data_types", order);
866                  }
867
868              }
869
870
871              if(!isDataTypeFound){
872                  return "data_types are missing or invalid.";
873              }
874
875              if(!isToscaVersionKeyFound || !isToscaVersionValueFound){
876                  return "tosca_definitions_version is missing or invalid.";
877              }
878
879              if(!isNoteTypeFound){
880                  return "node_types are missing or invalid.";
881              }
882
883              short version = (short) m1.get("tosca_definitions_version");
884
885              if(version > 1 ){
886                 return "tosca_definitions_version should be defined first.";
887              }
888
889              short data = (short) m1.get("data_types");
890              short node = (short) m1.get("node_types");
891              if(node > data){
892                 return "node_types should be defined before data_types.";
893              }
894
895         }
896
897         return null;
898     }
899
900     @SuppressWarnings({ "unchecked", "rawtypes" })
901     private void serializeMap(LinkedHashMap<String, String> settings, StringBuilder sb, List<String> path, Map<Object, Object> yamlMap) {
902         for (Entry<Object, Object> entry : yamlMap.entrySet()) {
903
904             if (entry.getValue() instanceof Map) {
905                 path.add((String) entry.getKey());
906                 serializeMap(settings, sb, path, (Map<Object, Object>) entry.getValue());
907                 path.remove(path.size() - 1);
908             } else if (entry.getValue() instanceof List) {
909                 path.add((String) entry.getKey());
910                 serializeList(settings, sb, path, (List) entry.getValue());
911                 path.remove(path.size() - 1);
912             } else {
913                 serializeValue(settings, sb, path, (String) entry.getKey(), entry.getValue());
914             }
915         }
916     }
917
918     @SuppressWarnings("unchecked")
919     private void serializeList(LinkedHashMap<String, String> settings, StringBuilder sb, List<String> path, List<String> yamlList) {
920         int counter = 0;
921         for (Object listEle : yamlList) {
922             if (listEle instanceof Map) {
923                 path.add(Integer.toString(counter));
924                 serializeMap(settings, sb, path, (Map<Object, Object>) listEle);
925                 path.remove(path.size() - 1);
926             } else if (listEle instanceof List) {
927                 path.add(Integer.toString(counter));
928                 serializeList(settings, sb, path, (List<String>) listEle);
929                 path.remove(path.size() - 1);
930             } else {
931                 serializeValue(settings, sb, path, Integer.toString(counter), listEle);
932             }
933             counter++;
934         }
935     }
936
937     private void serializeValue(LinkedHashMap<String, String> settings, StringBuilder sb, List<String> path, String name, Object value) {
938         if (value == null) {
939             return;
940         }
941         sb.setLength(0);
942         for (String pathEle : path) {
943             sb.append(pathEle).append('.');
944         }
945         sb.append(name);
946         settings.put(sb.toString(), value.toString());
947     }
948
949
950     void parseDataAndPolicyNodes(LinkedHashMap<String,String> map){
951         for(String key:map.keySet()){
952             if(key.contains("policy.nodes.Root"))
953             {
954                 continue;
955             }
956             else if(key.contains("policy.nodes")){
957                 String wordToFind = "policy.nodes.";
958                 int indexForPolicyNode=key.indexOf(wordToFind);
959                 String subNodeString= key.substring(indexForPolicyNode+13, key.length());
960
961                 stringBetweenDots(subNodeString);
962             }
963             else if(key.contains("policy.data")){
964                 String wordToFind="policy.data.";
965                 int indexForPolicyNode=key.indexOf(wordToFind);
966                 String subNodeString= key.substring(indexForPolicyNode+12, key.length());
967
968                 stringBetweenDotsForDataFields(subNodeString);
969             }
970         }
971     }
972
973     // Second index of dot should be returned.
974     public int stringBetweenDots(String str){
975         String stringToSearch=str;
976         String[]ss=stringToSearch.split("\\.");
977         if(ss!=null){
978             int len= ss.length;
979             if(len>2){
980                 uniqueKeys.add(ss[2]);
981             }
982         }
983
984         return uniqueKeys.size();
985     }
986
987
988     public void stringBetweenDotsForDataFields(String str){
989         String stringToSearch=str;
990         String[]ss=stringToSearch.split("\\.");
991         if(ss!=null){
992             int len= ss.length;
993
994             if(len>2){
995                 uniqueDataKeys.add(ss[0]+"%"+ss[2]);
996             }
997         }
998     }
999
1000     void constructJsonForDataFields(LinkedHashMap<String,String> dataMapForJson){
1001         LinkedHashMap<String,LinkedHashMap<String,String>> dataMapKey= new LinkedHashMap <>();
1002         LinkedHashMap<String, String> hmSub;
1003         for(Entry<String, String> entry: dataMapForJson.entrySet()){
1004             String uniqueDataKey= entry.getKey();
1005             String[] uniqueDataKeySplit=uniqueDataKey.split("%");
1006             String value= dataMapForJson.get(uniqueDataKey);
1007             if(dataMapKey.containsKey(uniqueDataKeySplit[0])){
1008                 hmSub = dataMapKey.get(uniqueDataKeySplit[0]);
1009                 hmSub.put(uniqueDataKeySplit[1], value);
1010             }
1011             else{
1012                 hmSub=new LinkedHashMap <>();
1013                 hmSub.put(uniqueDataKeySplit[1], value);
1014             }
1015
1016             dataMapKey.put(uniqueDataKeySplit[0], hmSub);
1017         }
1018
1019         JSONObject mainObject= new JSONObject();
1020         JSONObject json;
1021         for(Entry<String,LinkedHashMap<String,String>> entry: dataMapKey.entrySet()){
1022             String s=entry.getKey();
1023             json= new JSONObject();
1024             HashMap<String,String> jsonHm=dataMapKey.get(s);
1025             for(Entry<String,String> entryMap:jsonHm.entrySet()){
1026                 String key=entryMap.getKey();
1027                 json.put(key, jsonHm.get(key));
1028             }
1029             mainObject.put(s,json);
1030         }
1031         Iterator<String> keysItr = mainObject.keys();
1032         while(keysItr.hasNext()) {
1033             String key = keysItr.next();
1034             String value = mainObject.get(key).toString();
1035             retmap.put(key, value);
1036         }
1037
1038         logger.info("#############################################################################");
1039         logger.info(mainObject);
1040         logger.info("###############################################################################");
1041     }
1042     LinkedHashMap<String,String> parseDataNodes(LinkedHashMap<String,String> map){
1043         LinkedHashMap<String,String> dataMapForJson=new LinkedHashMap <>();
1044         matchableValues = new HashMap <>();
1045         for(String uniqueDataKey: uniqueDataKeys){
1046             if(uniqueDataKey.contains("%")){
1047                 String[] uniqueDataKeySplit= uniqueDataKey.split("%");
1048                 String findType=DATATYPE+uniqueDataKeySplit[0]+PROPERTIES+uniqueDataKeySplit[1]+TYPE;
1049                 String typeValue=map.get(findType);
1050                 logger.info(typeValue);
1051
1052                 String findRequired=DATATYPE+uniqueDataKeySplit[0]+PROPERTIES+uniqueDataKeySplit[1]+REQUIRED;
1053                 String requiredValue= map.get(findRequired);
1054
1055                 String matchable =DATATYPE+uniqueDataKeySplit[0]+PROPERTIES+uniqueDataKeySplit[1]+MATCHABLE;
1056
1057                 String matchableValue= map.get(matchable);
1058
1059                 if(matchableValue != null && matchableValue.equalsIgnoreCase("true")){
1060                     if(uniqueDataKey.contains("%")){
1061                         String[] keys= uniqueDataKey.split("%");
1062                         String key=keys[keys.length -1];
1063                         matchableValues.put(key, MATCHINGTRUE);
1064                     }else{
1065                         matchableValues.put(uniqueDataKey, MATCHINGTRUE);
1066                     }
1067                 }
1068
1069                 if(requiredValue == null || requiredValue.isEmpty()){
1070                     requiredValue = "false";
1071                 }
1072                 if(typeValue != null && (typeValue.equalsIgnoreCase(STRING)||
1073                         typeValue.equalsIgnoreCase(INTEGER))){
1074
1075                     String findDefault=DATATYPE+uniqueDataKeySplit[0]+PROPERTIES+uniqueDataKeySplit[1]+DEFAULT;
1076                     String defaultValue= map.get(findDefault);
1077                     logger.info("defaultValue is:"+ defaultValue);
1078                     logger.info("requiredValue is:"+ requiredValue);
1079
1080                     StringBuilder attributeIndividualStringBuilder= new StringBuilder();
1081                     attributeIndividualStringBuilder.append(typeValue+DEFAULTVALUE);
1082                     attributeIndividualStringBuilder.append(defaultValue+REQUIREDVALUE);
1083                     attributeIndividualStringBuilder.append(requiredValue+MANYFALSE);
1084                     dataMapForJson.put(uniqueDataKey, attributeIndividualStringBuilder.toString());
1085                 }
1086                 else if(LIST.equalsIgnoreCase(typeValue) || MAP.equalsIgnoreCase(typeValue)){
1087                     logger.info("requiredValue is:"+ requiredValue);
1088                     String findList= DATATYPE+uniqueDataKeySplit[0]+PROPERTIES+uniqueDataKeySplit[1]+".entry_schema.type";
1089                     String listValue=map.get(findList);
1090                     if(listValue!=null){
1091                         logger.info("Type of list is:"+ listValue);
1092                         //Its userdefined
1093                         if(listValue.contains(".")){
1094                             String trimValue=listValue.substring(listValue.lastIndexOf('.')+1);
1095                             StringBuilder referenceIndividualStringBuilder= new StringBuilder();
1096                             referenceIndividualStringBuilder.append(trimValue+REQUIREDVALUE);
1097                             referenceIndividualStringBuilder.append(requiredValue+MANYTRUE);
1098                             dataMapForJson.put(uniqueDataKey, referenceIndividualStringBuilder.toString());
1099                         }//Its string
1100                         else{
1101                             StringBuilder stringListItems= new StringBuilder();
1102                             if(LIST.equalsIgnoreCase(typeValue)){
1103                                 stringListItems.append(uniqueDataKeySplit[1].toUpperCase()+REQUIREDVALUE+requiredValue +MANYFALSE);
1104                             }else if( MAP.equalsIgnoreCase(typeValue)){
1105                                 stringListItems.append(uniqueDataKeySplit[1].toUpperCase()+REQUIREDVALUE+requiredValue +MANYTRUE);
1106                             }
1107                             dataMapForJson.put(uniqueDataKey, stringListItems.toString());
1108                             boolean isConstraintsFound = false;
1109                             for(int i=0;i<10;i++){
1110                                 String findConstraints= DATATYPE+uniqueDataKeySplit[0]+PROPERTIES+uniqueDataKeySplit[1]+".entry_schema.constraints.0.valid_values."+i;
1111                                 logger.info("findConstraints => " + findConstraints);
1112                                 String constraintsValue=map.get(findConstraints);
1113                                 logger.info("constraintsValue => " + constraintsValue);
1114
1115                                 if((constraintsValue==null || constraintsValue.isEmpty()) && i==0){ //if no constraints at all ( index i as 0 can tell this )
1116                                     isConstraintsFound = false;
1117                                     //if type is list but no constraints
1118                                     String newValue = dataMapForJson.get(uniqueDataKey).replace("MANY-false", "MANY-true");
1119                                     newValue = newValue.replace(uniqueDataKeySplit[1].toUpperCase()+":", "");
1120                                     dataMapForJson.put(uniqueDataKey, newValue);
1121                                     break;
1122                                 } else{
1123                                     isConstraintsFound = true;
1124                                     if(i == 0){ // only need to add one time for the same attribute
1125                                        dataListBuffer.append(uniqueDataKeySplit[1].toUpperCase()+"=[");
1126                                     }
1127
1128                                     if(constraintsValue==null){
1129                                         constraintsValue = "";
1130                                     }else if (constraintsValue.contains("=")) {
1131                                         constraintsValue = constraintsValue.replace("=", "equal-sign");
1132                                     }
1133
1134                                     dataConstraints.add(constraintsValue);
1135                                     dataListBuffer.append(constraintsValue+",");
1136                                 }
1137                             }
1138                             if(isConstraintsFound){
1139                                 dataListBuffer.append("]#");
1140                             }
1141                         }
1142                     }else{
1143                         logger.info("entry_schema.type is not defined correctly");
1144                     }
1145                 }
1146                 else{
1147                     String findUserDefined=DATATYPE+uniqueDataKeySplit[0]+"."+"properties"+"."+uniqueDataKeySplit[1]+TYPE;
1148                     String userDefinedValue=map.get(findUserDefined);
1149                     String trimValue=userDefinedValue.substring(userDefinedValue.lastIndexOf('.')+1);
1150                     StringBuilder referenceIndividualStringBuilder= new StringBuilder();
1151                     referenceIndividualStringBuilder.append(trimValue+REQUIREDVALUE);
1152                     referenceIndividualStringBuilder.append(requiredValue+MANYFALSE);
1153                     dataMapForJson.put(uniqueDataKey, referenceIndividualStringBuilder.toString());
1154
1155                 }
1156             }
1157         }
1158
1159         return dataMapForJson;
1160     }
1161
1162
1163     LinkedHashMap<String, LinkedHashMap<String, String>> parsePolicyNodes(Map<String,String> map) throws ParserException{
1164         LinkedHashMap<String,LinkedHashMap<String,String>> mapKey= new LinkedHashMap <>();
1165         for(String uniqueKey: uniqueKeys){
1166             LinkedHashMap<String,String> hm;
1167
1168             for(Entry<String,String> entry:map.entrySet()){
1169                 String key=entry.getKey();
1170                 if(key.contains(uniqueKey) && key.contains("policy.nodes")){
1171                     if(mapKey.containsKey(uniqueKey)){
1172                         hm = mapKey.get(uniqueKey);
1173                         String keyStr= key.substring(key.lastIndexOf('.')+1);
1174                         String valueStr= map.get(key);
1175                         if("type".equalsIgnoreCase(keyStr) && ((key.contains("entry_schema.0.type") || key.contains("entry_schema.type") && valueStr.contains("policy.data.")))){
1176                            throw new ParserException("For using user defined object type, Please make sure no space between 'type:' and object " + valueStr );
1177
1178                         }
1179                         if("type".equals(keyStr)){
1180                             if(!key.contains("entry_schema"))
1181                             {
1182                                 hm.put(keyStr,valueStr);
1183                             }
1184                         }else{
1185                             hm.put(keyStr,valueStr);
1186                         }
1187
1188                     } else {
1189                         hm = new LinkedHashMap <>();
1190                         String keyStr= key.substring(key.lastIndexOf('.')+1);
1191                         String valueStr= map.get(key);
1192                         if(key.contains(".objective.")){
1193                             throw new ParserException("Attribute objective is a key word. Please use a different name");
1194                         }
1195                         if(("type").equals(keyStr)){
1196                             if(!key.contains("entry_schema"))
1197                             {
1198                                 hm.put(keyStr,valueStr);
1199                             }
1200                         }else{
1201                             hm.put(keyStr,valueStr);
1202                         }
1203                         mapKey.put(uniqueKey, hm);
1204                     }
1205                 }
1206             }
1207         }
1208         return mapKey;
1209     }
1210
1211     void createAttributes(LinkedHashMap<String,LinkedHashMap<String,String>> mapKey){
1212         StringBuilder attributeStringBuilder= new StringBuilder();
1213         StringBuilder referenceStringBuilder= new StringBuilder();
1214         StringBuilder listBuffer= new StringBuilder();
1215         List<String> constraints= new ArrayList<>();
1216         for(Entry<String,LinkedHashMap<String,String>> entry: mapKey.entrySet()){
1217             String keySetString= entry.getKey();
1218             LinkedHashMap<String,String> keyValues=mapKey.get(keySetString);
1219             if(STRING.equalsIgnoreCase(keyValues.get("type"))||
1220                     INTEGER.equalsIgnoreCase(keyValues.get("type"))){
1221                 StringBuilder attributeIndividualStringBuilder= new StringBuilder();
1222                 attributeIndividualStringBuilder.append(keySetString+"=");
1223                 attributeIndividualStringBuilder.append(keyValues.get("type")+DEFAULTVALUE);
1224                 attributeIndividualStringBuilder.append(keyValues.get("default")+REQUIREDVALUE);
1225                 attributeIndividualStringBuilder.append(keyValues.get("required")+MANYFALSE);
1226                 attributeStringBuilder.append(attributeIndividualStringBuilder+",");
1227                 if("true".equalsIgnoreCase(keyValues.get(MATCHABLEKEY))){
1228                     matchableValues.put(keySetString, MATCHINGTRUE);
1229                 }
1230             }
1231             else if(LIST.equalsIgnoreCase(keyValues.get("type"))){
1232
1233                 if(("true").equalsIgnoreCase(keyValues.get(MATCHABLEKEY))){
1234                     matchableValues.put(keySetString, MATCHINGTRUE);
1235                 }
1236                 //List Datatype
1237                 Set<String> keys= keyValues.keySet();
1238                 Iterator<String> itr=keys.iterator();
1239                 boolean isDefinedType = false;
1240                 while(itr.hasNext()){
1241                     String key= itr.next();
1242                     if((!("type").equals(key) ||("required").equals(key)))
1243                     {
1244                         String value= keyValues.get(key);
1245                         //The "." in the value determines if its a string or a user defined type.
1246                         if (!value.contains(".")){
1247                             //This is string
1248                             if(StringUtils.isNumeric(key) ){  //only integer key for the value of Constrains
1249                                 constraints.add(keyValues.get(key));
1250                             }
1251                         }else{
1252                             //This is user defined type
1253                             String trimValue=value.substring(value.lastIndexOf('.')+1);
1254                             StringBuilder referenceIndividualStringBuilder= new StringBuilder();
1255                             referenceIndividualStringBuilder.append(keySetString+"="+trimValue+MANYTRUE);
1256                             referenceStringBuilder.append(referenceIndividualStringBuilder+",");
1257                             isDefinedType = true;
1258                         }
1259                     }
1260
1261                 }
1262
1263                 if(!isDefinedType && LIST.equalsIgnoreCase(keyValues.get("type"))){ //type is not user defined and is a list but no constraints defined.
1264                     if(constraints == null || constraints.isEmpty()){
1265                         referenceStringBuilder.append(keySetString+"=MANY-true"+",");
1266                     }
1267                 }
1268             }else{
1269                 //User defined Datatype.
1270                 if("true".equalsIgnoreCase(keyValues.get(MATCHABLEKEY))){
1271                     matchableValues.put(keySetString, MATCHINGTRUE);
1272                 }
1273                 String value=keyValues.get("type");
1274                 if(value != null && !value.isEmpty()){
1275                     String trimValue=value.substring(value.lastIndexOf('.')+1);
1276                     StringBuilder referenceIndividualStringBuilder= new StringBuilder();
1277                     referenceIndividualStringBuilder.append(keySetString+"="+trimValue+MANYFALSE);
1278                     referenceStringBuilder.append(referenceIndividualStringBuilder+",");
1279                 }else{
1280                     logger.info("keyValues.get(type) is null/empty");
1281                 }
1282
1283             }
1284             if(constraints!=null && !constraints.isEmpty()){
1285                 //List handling.
1286                 listBuffer.append(keySetString.toUpperCase()+"=[");
1287                 for(String str:constraints){
1288                     listBuffer.append(str+",");
1289                 }
1290                 listBuffer.append("]#");
1291                 logger.info(listBuffer);
1292
1293
1294                 StringBuilder referenceIndividualStringBuilder= new StringBuilder();
1295                 referenceIndividualStringBuilder.append(keySetString+"="+keySetString.toUpperCase()+MANYFALSE);
1296                 referenceStringBuilder.append(referenceIndividualStringBuilder+",");
1297                 constraints.clear();
1298             }
1299         }
1300
1301         dataListBuffer.append(listBuffer);
1302
1303
1304         logger.info("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
1305         logger.info("Whole attribute String is:"+attributeStringBuilder);
1306         logger.info("Whole reference String is:"+referenceStringBuilder);
1307         logger.info("List String is:"+listBuffer);
1308         logger.info("Data list buffer is:"+dataListBuffer);
1309         logger.info("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
1310
1311         this.listConstraints=dataListBuffer.toString();
1312         this.referenceAttributes=referenceStringBuilder.toString();
1313         this.attributeString=attributeStringBuilder.toString();
1314     }
1315
1316     @SuppressWarnings("unchecked")
1317     public void findNode(LinkedHashMap<Object, Object> map) {
1318
1319         map.forEach((key,value) -> {
1320             // if the value is properties and its type is map object, then save all the keys
1321             if(key.equals("properties") && value instanceof Map){
1322                 saveNodes((LinkedHashMap<?, ?>)value);
1323             }
1324
1325             if(!key.equals("policy.nodes.Root") && value instanceof Map){
1326                 //value is a Map object, then make a recursive call
1327                 findNode((LinkedHashMap<Object, Object>) value);
1328             }
1329         });
1330
1331     }
1332
1333     public void saveNodes(LinkedHashMap<?, ?> map) {
1334
1335         map.forEach((key,value) -> {
1336
1337             orderedElements.add((String)key);
1338
1339         });
1340
1341     }
1342
1343     public String getAttributeString() {
1344         return attributeString;
1345     }
1346     public void setAttributeString(String attributeString) {
1347         this.attributeString = attributeString;
1348     }
1349
1350     public LinkedHashMap<String, Object> getRetmap() {
1351         return retmap;
1352     }
1353
1354     public void setRetmap(LinkedHashMap<String, Object> retmap) {
1355         this.retmap = retmap;
1356     }
1357     public Map<String, String> getMatchableValues() {
1358         return matchableValues;
1359     }
1360
1361     public void setMatchableValues(Map<String, String> matchableValues) {
1362         this.matchableValues = matchableValues;
1363     }
1364     public String getReferenceAttributes() {
1365         return referenceAttributes;
1366     }
1367
1368     public void setReferenceAttributes(String referenceAttributes) {
1369         this.referenceAttributes = referenceAttributes;
1370     }
1371     public String getListConstraints() {
1372         return listConstraints;
1373     }
1374
1375     public void setListConstraints(String listConstraints) {
1376         this.listConstraints = listConstraints;
1377     }
1378     public String getDataOrderInfo() {
1379         return dataOrderInfo;
1380     }
1381
1382     public void setDataOrderInfo(String dataOrderInfo) {
1383         this.dataOrderInfo = dataOrderInfo;
1384     }
1385
1386 }