fa2c51d18d329db7b942f002ba5a9c5f1b9f1bfa
[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 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.rest.util;
22
23 import java.io.IOException;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.Collections;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Map.Entry;
31
32 import org.apache.commons.lang.StringUtils;
33 import org.apache.commons.logging.Log;
34 import org.apache.commons.logging.LogFactory;
35 import org.eclipse.emf.common.util.EList;
36 import org.eclipse.emf.common.util.EMap;
37 import org.eclipse.emf.common.util.Enumerator;
38 import org.eclipse.emf.common.util.TreeIterator;
39 import org.eclipse.emf.common.util.URI;
40 import org.eclipse.emf.ecore.EAnnotation;
41 import org.eclipse.emf.ecore.EClass;
42 import org.eclipse.emf.ecore.EClassifier;
43 import org.eclipse.emf.ecore.EEnum;
44 import org.eclipse.emf.ecore.EEnumLiteral;
45 import org.eclipse.emf.ecore.EObject;
46 import org.eclipse.emf.ecore.EPackage;
47 import org.eclipse.emf.ecore.EReference;
48 import org.eclipse.emf.ecore.EStructuralFeature;
49 import org.eclipse.emf.ecore.impl.EAttributeImpl;
50 import org.eclipse.emf.ecore.impl.EEnumImpl;
51 import org.eclipse.emf.ecore.resource.Resource;
52 import org.eclipse.emf.ecore.resource.ResourceSet;
53 import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
54 import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
55 import org.json.JSONObject;
56 import org.onap.policy.rest.XACMLRestProperties;
57
58 import com.att.research.xacml.util.XACMLProperties;
59 import com.google.gson.Gson;
60
61
62 public class MSModelUtils {
63
64         private static final Log logger = LogFactory.getLog(MSModelUtils.class);
65
66         private HashMap<String,MSAttributeObject > classMap = new HashMap<>();
67         private HashMap<String, String> enumMap = new HashMap<>();
68         private HashMap<String, String> matchingClass = new HashMap<>();
69         private String configuration = "configuration";
70         private String dictionary = "dictionary";
71         private String onap = "";
72         private String policy = "";
73         private String eProxyURI = "eProxyURI:";
74         
75         public MSModelUtils(String onap, String policy){
76                 this.onap = onap;
77                 this.policy = policy;
78         }
79
80         private enum ANNOTATION_TYPE{
81                 MATCHING, VALIDATION, DICTIONARY
82         };
83
84         public enum MODEL_TYPE {
85                 XMI
86         };
87
88
89         public HashMap<String, MSAttributeObject> processEpackage(String file, MODEL_TYPE model){
90                 if (model == MODEL_TYPE.XMI ){
91                         processXMIEpackage(file);
92                 }
93                 return classMap;
94
95         } 
96
97         private void processXMIEpackage(String xmiFile){
98                 EPackage root = getEpackage(xmiFile);
99                 TreeIterator<EObject> treeItr = root.eAllContents();
100                 String className = null;
101                 String returnValue = null;
102
103                 //    Pulling out dependency from file
104                 while (treeItr.hasNext()) {         
105                         EObject obj = (EObject) treeItr.next();
106                         if (obj instanceof EClassifier) {
107                                 EClassifier eClassifier = (EClassifier) obj;
108                                 className = eClassifier.getName();
109
110                                 if (obj instanceof EEnum) {
111                                         enumMap.putAll(getEEnum(obj));
112                                 }else if (obj instanceof EClass) {
113                                         String temp = getDependencyList(eClassifier, className).toString();
114                                         returnValue = StringUtils.replaceEach(temp, new String[]{"[", "]"}, new String[]{"", ""});
115                                         getAttributes(className, returnValue, root);
116                                 }                                       
117                         }
118                 }
119
120                 if (!enumMap.isEmpty()){
121                         addEnumClassMap();
122                 }
123                 if (!matchingClass.isEmpty()){
124                         CheckForMatchingClass();
125                 }
126         }
127
128         private void CheckForMatchingClass() {
129                 HashMap<String, String> tempAttribute = new HashMap<>();
130
131                 for (Entry<String, String> set : matchingClass.entrySet()){
132                         String key = set.getKey();
133                         if (classMap.containsKey(key)){
134                                 Map<String, String> listAttributes = classMap.get(key).getAttribute();
135                                 Map<String, String> listRef = classMap.get(key).getRefAttribute();
136                                 for (  Entry<String, String> eSet : listAttributes.entrySet()){
137                                         String key2 = eSet.getKey();
138                                         tempAttribute.put(key2, "matching-true");
139                                 }
140                                 for (  Entry<String, String> eSet : listRef.entrySet()){
141                                         String key3 = eSet.getKey();
142                                         tempAttribute.put(key3, "matching-true");
143                                 }
144
145                         }
146                         UpdateMatching(tempAttribute, key);
147                 }
148
149         }
150
151
152
153         private void UpdateMatching(HashMap<String, String> tempAttribute, String key) {
154                 Map<String, MSAttributeObject> newClass = null;
155
156                 newClass = classMap;
157
158                 for (Entry<String, MSAttributeObject> updateClass :  newClass.entrySet()){
159                         HashMap<String, String> valueMap = updateClass.getValue().getMatchingSet();
160                         String keymap = updateClass.getKey();
161                         if (valueMap.containsKey(key)){
162                                 HashMap<String, String> modifyMap = classMap.get(keymap).getMatchingSet();
163                                 modifyMap.remove(key);
164                                 modifyMap.putAll(tempAttribute);
165                                 classMap.get(keymap).setMatchingSet(modifyMap);
166                         }
167
168                 }
169         }
170
171         private void addEnumClassMap() {
172                 for (Entry<String, MSAttributeObject> value :classMap.entrySet()){
173                         value.getValue().setEnumType(enumMap);
174                 }
175         }
176
177         private EPackage getEpackage(String xmiFile) {
178                 ResourceSet resSet = new ResourceSetImpl();
179                 Resource.Factory.Registry reg = Resource.Factory.Registry.INSTANCE;
180                 Map<String, Object> m = reg.getExtensionToFactoryMap();
181                 m.put("xmi", new XMIResourceFactoryImpl());
182                 Resource resource = resSet.getResource(URI.createFileURI(xmiFile), true);
183                 try {
184                         resource.load(Collections.EMPTY_MAP);
185                 } catch (IOException e) {
186                         logger.error("Error loading Encore Resource for new Model" + e);
187                 }
188
189                 EPackage root = (EPackage) resource.getContents().get(0);
190
191                 return root;
192         }
193
194         private HashMap<String, String> getEEnum(EObject obj) {
195                 List<String> valueList = new ArrayList<>();
196                 HashMap<String, String> returnMap = new HashMap<>();
197                 EEnum eenum = (EEnum)obj;
198
199                 String name = eenum.getName();
200                 for (EEnumLiteral eEnumLiteral : eenum.getELiterals())
201                 {
202                         Enumerator instance = eEnumLiteral.getInstance();
203                         String value = instance.getLiteral();
204                         valueList.add(value);
205                 }
206                 returnMap.put(name, valueList.toString());
207                 return returnMap;
208         }
209
210         public void getAttributes(String className, String dependency, EPackage root) {
211                 List<String> dpendList = new ArrayList<>();
212                 if (dependency!=null){
213                         dpendList = new ArrayList<String>(Arrays.asList(dependency.split(",")));
214                 }
215                 MSAttributeObject msAttributeObject = new MSAttributeObject();
216                 msAttributeObject.setClassName(className);
217                 String extendClass = getSubTypes(root, className);
218                 HashMap<String, String> returnRefList = getRefAttributeList(root, className, extendClass);
219                 HashMap<String, String> returnAttributeList = getAttributeList(root, className, extendClass);
220                 HashMap<String, Object> returnSubList = getSubAttributeList(root, className, extendClass);
221                 HashMap<String, String> returnAnnotation = getAnnotation(root, className, extendClass);
222                 msAttributeObject.setAttribute(returnAttributeList);
223                 msAttributeObject.setRefAttribute(returnRefList);
224                 msAttributeObject.setSubClass(returnSubList);
225                 msAttributeObject.setDependency(dpendList.toString());
226                 msAttributeObject.addMatchingSet(returnAnnotation);
227                 msAttributeObject.setPolicyTempalate(isPolicyTemplate(root, className));
228
229                 this.classMap.put(className, msAttributeObject);        
230         }
231
232         private HashMap<String, String> getAnnotation(EPackage root, String className, String extendClass) {
233                 TreeIterator<EObject> treeItr = root.eAllContents();
234                 boolean requiredAttribute = false; 
235                 boolean requiredMatchAttribute = false;
236                 HashMap<String, String> annotationSet = new HashMap<>();
237                 String  matching  = null;
238                 String range   = null;
239                 String dictionary = null;
240
241                 //    Pulling out dependency from file
242                 while (treeItr.hasNext()) {         
243                         EObject obj = treeItr.next();
244                         if (obj instanceof EClassifier) {
245                                 requiredAttribute = isRequiredAttribute(obj,  className );
246                                 requiredMatchAttribute = isRequiredAttribute(obj,  extendClass );
247                         }
248
249                         if (requiredAttribute){
250                                 if (obj instanceof EStructuralFeature) {
251                                         EStructuralFeature eStrucClassifier = (EStructuralFeature) obj;
252                                         if (eStrucClassifier.getEAnnotations().size() != 0) {
253                                                 matching  = annotationValue(eStrucClassifier, ANNOTATION_TYPE.MATCHING, policy);
254                                                 if (matching!=null){
255                                                         annotationSet.put(eStrucClassifier.getName(), matching);
256                                                 }
257                                                 range  = annotationValue(eStrucClassifier, ANNOTATION_TYPE.VALIDATION, policy);
258                                                 if (range!=null){
259                                                         annotationSet.put(eStrucClassifier.getName(), range);
260                                                 }
261                                                 dictionary = annotationValue(eStrucClassifier, ANNOTATION_TYPE.DICTIONARY, policy);
262                                                 if (dictionary!=null){
263                                                         annotationSet.put(eStrucClassifier.getName(), dictionary);
264                                                 }
265                                         }
266                                 }
267                         } else if (requiredMatchAttribute){
268                                 if (obj instanceof EStructuralFeature) {
269                                         EStructuralFeature eStrucClassifier = (EStructuralFeature) obj;
270                                         if (eStrucClassifier.getEAnnotations().size() != 0) {
271                                                 matching  = annotationValue(eStrucClassifier, ANNOTATION_TYPE.MATCHING, policy);
272                                                 if (matching!=null){
273                                                         if (obj instanceof EReference){
274                                                                 EClass refType = ((EReference) obj).getEReferenceType();
275                                                                 annotationSet.put(refType.getName(), matching);
276                                                                 matchingClass.put(refType.getName(), matching);
277                                                         }else{
278                                                                 annotationSet.put(eStrucClassifier.getName(), matching);
279                                                         }
280                                                 }
281                                         }
282                                 }
283                         }
284                 }
285                 return annotationSet;
286         }
287
288         private HashMap<String, Object> getSubAttributeList(EPackage root, String className , String superClass) {
289                 TreeIterator<EObject> treeItr = root.eAllContents();
290                 boolean requiredAttribute = false; 
291                 HashMap<String, Object> subAttribute = new HashMap<String, Object>();
292                 int rollingCount = 0;
293                 int processClass = 0;
294                 boolean annotation = false;
295
296                 //    Pulling out dependency from file
297                 while (treeItr.hasNext() && rollingCount < 2) {  
298
299                         EObject obj = treeItr.next();
300                         if (obj instanceof EClassifier) {
301                                 if (isRequiredAttribute(obj,  className ) || isRequiredAttribute(obj,  superClass )){
302                                         requiredAttribute = true;
303                                 }else {
304                                         requiredAttribute = false;
305                                 }
306                                 if (requiredAttribute){
307                                         processClass++;
308                                 }
309                                 rollingCount = rollingCount+processClass;
310                         }
311
312                         if (requiredAttribute)   {
313                                 if (obj instanceof EStructuralFeature) {
314                                         EStructuralFeature eStrucClassifier = (EStructuralFeature) obj;
315                                         if (eStrucClassifier.getEAnnotations().size() != 0) {
316                                                 annotation = annotationTest(eStrucClassifier, configuration, onap);
317                                                 if (annotation &&  obj instanceof EReference) {
318                                                         EClass refType = ((EReference) obj).getEReferenceType();
319                                                         if(!refType.toString().contains(eProxyURI)){
320                                                                 subAttribute.put(eStrucClassifier.getName(), refType.getName());                                                
321                                                         }
322                                                 }       
323                                         }
324                                 }
325                         }
326                 }
327                 return subAttribute;
328         }
329
330         public String checkDefultValue(String defultValue) {
331                 if (defultValue!=null){
332                         return ":defaultValue-"+ defultValue;
333                 }
334                 return ":defaultValue-NA";
335
336         }
337
338         public String checkRequiredPattern(int upper, int lower) {      
339
340                 String pattern = XACMLProperties.getProperty(XACMLRestProperties.PROP_XCORE_REQUIRED_PATTERN);
341
342                 if (pattern!=null){
343                         if (upper == Integer.parseInt(pattern.split(",")[1]) && lower==Integer.parseInt(pattern.split(",")[0])){
344                                 return ":required-true";
345                         }
346                 }
347
348                 return ":required-false";
349         }
350
351         public JSONObject buildJavaObject(HashMap<String, String> map, String attributeType){
352
353                 JSONObject returnValue = new JSONObject(map);
354
355                 return returnValue;
356
357         }
358
359         public HashMap<String, String> getRefAttributeList(EPackage root, String className, String superClass){
360
361                 TreeIterator<EObject> treeItr = root.eAllContents();
362                 boolean requiredAttribute = false; 
363                 HashMap<String, String> refAttribute = new HashMap<>();
364                 int rollingCount = 0;
365                 int processClass = 0;
366                 boolean annotation = false;
367                 //    Pulling out dependency from file
368                 while (treeItr.hasNext()) {         
369                         EObject obj = treeItr.next();
370                         if (obj instanceof EClassifier) {
371                                 if (isRequiredAttribute(obj,  className ) || isRequiredAttribute(obj,  superClass )){
372                                         requiredAttribute = true;
373                                 }else {
374                                         requiredAttribute = false;
375                                 }       
376                                 if (requiredAttribute){
377                                         processClass++;
378                                 }
379                                 rollingCount = rollingCount+processClass;
380                         }
381
382                         if (requiredAttribute)   {
383                                 if (obj instanceof EStructuralFeature) {
384                                         EStructuralFeature eStrucClassifier = (EStructuralFeature) obj;
385                                         if (eStrucClassifier.getEAnnotations().size() != 0) {
386                                                 annotation = annotationTest(eStrucClassifier, configuration, onap);
387                                                 if ( annotation &&  obj instanceof EReference) {
388                                                         EClass refType = ((EReference) obj).getEReferenceType();
389                                                         if(refType.toString().contains(eProxyURI)){
390                                                                 String one = refType.toString().split(eProxyURI)[1];
391                                                                 String refValue = StringUtils.replaceEach(one.split("#")[1], new String[]{"//", ")"}, new String[]{"", ""});                                                    
392                                                                 refAttribute.put(eStrucClassifier.getName(), refValue);                                                 
393                                                         } else {
394                                                                 String array = arrayCheck(((EStructuralFeature) obj).getUpperBound());
395                                                                 refAttribute.put(eStrucClassifier.getName(), refType.getName() + array);
396                                                         }
397                                                 } else if (annotation &&  obj instanceof EAttributeImpl){
398                                                         EClassifier refType = ((EAttributeImpl) obj).getEType();
399                                                         if (refType instanceof EEnumImpl){
400                                                                 String array = arrayCheck(((EStructuralFeature) obj).getUpperBound());
401                                                                 refAttribute.put(eStrucClassifier.getName(), refType.getName() + array);                                                        }
402                                                 }       
403                                         }
404                                 }
405                         }
406                 }
407                 return refAttribute;
408         }
409
410         private boolean annotationTest(EStructuralFeature eStrucClassifier, String annotation, String type) {
411                 String annotationType = null;
412                 EAnnotation eAnnotation = null;
413                 String onapType = null;
414                 String onapValue = null;
415
416                 EList<EAnnotation> value = eStrucClassifier.getEAnnotations();
417
418                 for (int i = 0; i < value.size(); i++){
419                         annotationType = value.get(i).getSource();
420                         eAnnotation = eStrucClassifier.getEAnnotations().get(i);
421                         onapType = eAnnotation.getDetails().get(0).getValue();
422                         onapValue = eAnnotation.getDetails().get(0).getKey();
423                         if (annotationType.contains(type) && onapType.contains(annotation)){
424                                 return true;
425                         } else if (annotationType.contains(type) && onapValue.contains(annotation)){
426                                 return true;
427                         }
428                 }
429
430                 return false;
431         }
432
433
434         private String annotationValue(EStructuralFeature eStrucClassifier, ANNOTATION_TYPE annotation, String type) {
435                 String annotationType = null;
436                 EAnnotation eAnnotation = null;
437                 String onapType = null;
438                 String onapValue = null;
439
440                 EList<EAnnotation> value = eStrucClassifier.getEAnnotations();
441
442                 for (int i = 0; i < value.size(); i++){
443                         annotationType = value.get(i).getSource();
444                         eAnnotation = eStrucClassifier.getEAnnotations().get(i);
445                         onapType = eAnnotation.getDetails().get(0).getKey();
446                         if (annotationType.contains(type) && onapType.compareToIgnoreCase(annotation.toString())==0){
447                                 onapValue = eAnnotation.getDetails().get(0).getValue();
448                                 if (annotation == ANNOTATION_TYPE.VALIDATION){
449                                         return onapValue;
450                                 } else {
451                                         return onapType + "-" + onapValue;
452                                 }
453                         }
454                 }
455
456                 return onapValue;
457         }
458         public boolean isRequiredAttribute(EObject obj, String className){
459                 EClassifier eClassifier = (EClassifier) obj;
460                 String workingClass = eClassifier.getName();
461                 workingClass.trim();
462                 if (workingClass.equalsIgnoreCase(className)){
463                         return  true;
464                 }
465
466                 return false;
467         } 
468
469         private boolean isPolicyTemplate(EPackage root, String className){
470
471                 for (EClassifier classifier : root.getEClassifiers()){ 
472                         if (classifier instanceof EClass) { 
473                                 EClass eClass = (EClass)classifier; 
474                                 if (eClass.getName().contentEquals(className)){
475                                         EList<EAnnotation> value = eClass.getEAnnotations();
476                                         for (EAnnotation workingValue : value){
477                                                 EMap<String, String> keyMap = workingValue.getDetails();        
478                                                 if (keyMap.containsKey("policyTemplate")){
479                                                         return true;
480                                                 }
481                                         }       
482                                 }
483                         }
484                 }
485                 return false;
486         }
487         private String getSubTypes(EPackage root, String className) {
488                 String returnSubTypes = null;
489                 for (EClassifier classifier : root.getEClassifiers()){ 
490                         if (classifier instanceof EClass) { 
491                                 EClass eClass = (EClass)classifier; 
492
493                                 for (EClass eSuperType : eClass.getEAllSuperTypes()) 
494                                 { 
495                                         if (eClass.getName().contentEquals(className)){
496                                                 returnSubTypes = eSuperType.getName();
497                                         }
498                                 } 
499                         } 
500                 } 
501                 return returnSubTypes;
502         } 
503
504         public HashMap<String, String> getAttributeList(EPackage root, String className, String superClass){
505
506                 TreeIterator<EObject> treeItr = root.eAllContents();
507                 boolean requiredAttribute = false; 
508                 HashMap<String, String> refAttribute = new HashMap<>();
509                 boolean annotation = false;
510                 boolean dictionaryTest = false;
511                 String defaultValue = null;
512                 String eType = null;
513
514                 //    Pulling out dependency from file
515                 while (treeItr.hasNext()) {         
516                         EObject obj = treeItr.next();
517                         if (obj instanceof EClassifier) {
518                                 if (isRequiredAttribute(obj,  className ) || isRequiredAttribute(obj,  superClass )){
519                                         requiredAttribute = true;
520                                 }else {
521                                         requiredAttribute = false;
522                                 }
523
524                         }
525
526                         if (requiredAttribute){
527                                 if (obj instanceof EStructuralFeature) {
528                                         EStructuralFeature eStrucClassifier = (EStructuralFeature) obj;
529                                         if (eStrucClassifier.getEAnnotations().size() != 0) {
530                                                 annotation = annotationTest(eStrucClassifier, configuration, onap);
531                                                 dictionaryTest = annotationTest(eStrucClassifier, dictionary, policy);
532                                                 EClassifier refType = ((EStructuralFeature) obj).getEType();
533                                                 if (annotation && !(obj instanceof EReference) && !(refType instanceof EEnumImpl)) {
534                                                         String name = eStrucClassifier.getName();
535                                                         if (dictionaryTest){
536                                                                 eType = annotationValue(eStrucClassifier, ANNOTATION_TYPE.DICTIONARY, policy);
537                                                         }else {
538                                                                 eType = eStrucClassifier.getEType().getInstanceClassName();
539                                                         }
540                                                         defaultValue = checkDefultValue(((EStructuralFeature) obj).getDefaultValueLiteral());
541
542                                                         String array = arrayCheck(((EStructuralFeature) obj).getUpperBound());
543                                                         String required = checkRequiredPattern(((EStructuralFeature) obj).getUpperBound(), ((EStructuralFeature) obj).getLowerBound());
544                                                         String attributeValue =  eType + defaultValue + required + array;
545                                                         refAttribute.put(name, attributeValue); 
546                                                 }
547                                         }
548                                 }
549                         }
550                 }
551                 return refAttribute;
552
553         }
554
555         public String arrayCheck(int upperBound) {
556
557                 if (upperBound == -1){
558                         return ":MANY-true";
559                 }
560
561                 return ":MANY-false";
562         }
563
564         public List<String> getDependencyList(EClassifier eClassifier, String className){
565                 List<String> returnValue = new ArrayList<>();;
566                 EList<EClass> somelist = ((EClass) eClassifier).getEAllSuperTypes();
567                 if (somelist.isEmpty()){
568                         return returnValue;
569                 }
570                 for(EClass depend: somelist){
571                         if (depend.toString().contains(eProxyURI)){
572                                 String one = depend.toString().split(eProxyURI)[1];
573                                 String value = StringUtils.replaceEach(one.split("#")[1], new String[]{"//", ")"}, new String[]{"", ""});
574                                 returnValue.add(value);
575                         }
576                 }
577
578                 return returnValue;
579         }
580
581         public Map<String, String> buildSubList(HashMap<String, String> subClassAttributes, HashMap<String, MSAttributeObject> classMap, String className){
582                 Map<String, String> missingValues = new HashMap<>();
583                 Map<String, String> workingMap = new HashMap<>();
584                 boolean enumType;
585
586                 for ( Entry<String, String> map : classMap.get(className).getRefAttribute().entrySet()){
587                         String value = map.getValue().split(":")[0];
588                         if (value!=null){
589                                 classMap.get(className).getEnumType();
590                                 enumType = classMap.get(className).getEnumType().containsKey(value);
591                                 if (!enumType){
592                                         workingMap =  classMap.get(value).getRefAttribute();
593                                         for ( Entry<String, String> subMab : workingMap.entrySet()){
594                                                 String value2 = subMab.getValue().split(":")[0];
595                                                 if (!subClassAttributes.containsValue(value2)){
596                                                         missingValues.put(subMab.getKey(), subMab.getValue());
597                                                 }
598                                         }
599
600                                 }
601                         }
602                 }
603
604                 return missingValues;
605         }
606
607         public Map<String, HashMap<String, String>> recursiveReference(HashMap<String, MSAttributeObject> classMap, String className){
608
609                 Map<String, HashMap<String, String>> returnObject = new HashMap<>();
610                 HashMap<String, String> returnClass = getRefclass(classMap, className);
611                 returnObject.put(className, returnClass);
612                 for (Entry<String, String> reAttribute :returnClass.entrySet()){
613                         if (reAttribute.getValue().split(":")[1].contains("MANY")){
614                                 if (classMap.get(reAttribute.getValue().split(":")[0]) != null){
615                                         returnObject.putAll(recursiveReference(classMap, reAttribute.getValue().split(":")[0]));
616                                 }
617                         }
618
619                 }
620
621                 return returnObject;
622
623         }
624
625         public String createJson(HashMap<String, Object> subClassAttributes, HashMap<String, MSAttributeObject> classMap, String className) { 
626                 boolean enumType;
627                 Map<String, HashMap<String, String>> myObject = new HashMap<>();
628                 for ( Entry<String, String> map : classMap.get(className).getRefAttribute().entrySet()){
629                         String value = map.getValue().split(":")[0];
630                         if (value!=null){
631                                 enumType = classMap.get(className).getEnumType().containsKey(value);
632                                 if (!enumType){
633                                         if (map.getValue().split(":")[1].contains("MANY")){
634                                                 Map<String, HashMap<String, String>> testRecursive = recursiveReference(classMap, map.getValue().split(":")[0] );
635                                                 myObject.putAll(testRecursive);
636                                         }
637                                 }
638                         }
639                 }
640
641                 Gson gson = new Gson(); 
642                 String json = gson.toJson(myObject); 
643
644                 return json;            
645         }
646
647         public HashMap<String, String> getRefclass(HashMap<String, MSAttributeObject> classMap, String className){
648                 HashMap<String, String> missingValues = new HashMap<>();
649
650                 if (classMap.get(className).getAttribute()!=null || !classMap.get(className).getAttribute().isEmpty()){
651                         missingValues.putAll(classMap.get(className).getAttribute());
652                 }
653
654                 if (classMap.get(className).getRefAttribute()!=null || !classMap.get(className).getRefAttribute().isEmpty()){
655                         missingValues.putAll(classMap.get(className).getRefAttribute());
656                 }
657
658                 return missingValues;   
659         }
660
661         public String createSubAttributes(ArrayList<String> dependency, HashMap<String, MSAttributeObject> classMap, String modelName) {
662
663                 HashMap <String,  Object>  workingMap = new HashMap<>();
664                 MSAttributeObject tempObject = new MSAttributeObject();
665                 if (dependency!=null){
666                         if (dependency.size()==0){
667                                 return "{}";
668                         }       
669                         dependency.add(modelName);
670                         for (String element: dependency){
671                                 tempObject = classMap.get(element);
672                                 if (tempObject!=null){
673                                         workingMap.putAll(classMap.get(element).getSubClass());
674                                 }
675                         }
676                 }
677
678                 String returnValue = createJson(workingMap, classMap, modelName);                       
679                 return returnValue;
680         }
681
682         public ArrayList<String> getFullDependencyList(ArrayList<String> dependency, HashMap<String,MSAttributeObject > classMap) {
683                 ArrayList<String> returnList = new ArrayList<>();
684                 ArrayList<String> workingList = new ArrayList<>();
685                 returnList.addAll(dependency);
686                 for (String element : dependency ){
687                         if (classMap.containsKey(element)){
688                                 MSAttributeObject value = classMap.get(element);
689                                 String rawValue = StringUtils.replaceEach(value.getDependency(), new String[]{"[", "]"}, new String[]{"", ""});
690                                 workingList = new ArrayList<String>(Arrays.asList(rawValue.split(",")));        
691                                 for(String depend : workingList){
692                                         if (!returnList.contains(depend) && !depend.isEmpty()){
693                                                 returnList.add(depend.trim());
694                                         }
695                                 }
696                         }
697                 }
698
699                 return returnList;
700         }
701 }