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