Merge "Included Policy GUI Enhancements and validations"
[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 Map<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;
101                 String returnValue;
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 = classMap;
155
156                 for (Entry<String, MSAttributeObject> updateClass :  newClass.entrySet()){
157                         Map<String, String> valueMap = updateClass.getValue().getMatchingSet();
158                         String keymap = updateClass.getKey();
159                         if (valueMap.containsKey(key)){
160                                 Map<String, String> modifyMap = classMap.get(keymap).getMatchingSet();
161                                 modifyMap.remove(key);
162                                 modifyMap.putAll(tempAttribute);
163                                 classMap.get(keymap).setMatchingSet(modifyMap);
164                         }
165
166                 }
167         }
168
169         private void addEnumClassMap() {
170                 for (Entry<String, MSAttributeObject> value :classMap.entrySet()){
171                         value.getValue().setEnumType(enumMap);
172                 }
173         }
174
175         private EPackage getEpackage(String xmiFile) {
176                 ResourceSet resSet = new ResourceSetImpl();
177                 Resource.Factory.Registry reg = Resource.Factory.Registry.INSTANCE;
178                 Map<String, Object> m = reg.getExtensionToFactoryMap();
179                 m.put("xmi", new XMIResourceFactoryImpl());
180                 Resource resource = resSet.getResource(URI.createFileURI(xmiFile), true);
181                 try {
182                         resource.load(Collections.emptyMap());
183                 } catch (IOException e) {
184                         logger.error("Error loading Encore Resource for new Model" + e);
185                 }
186
187                 EPackage root = (EPackage) resource.getContents().get(0);
188
189                 return root;
190         }
191
192         private HashMap<String, String> getEEnum(EObject obj) {
193                 List<String> valueList = new ArrayList<>();
194                 HashMap<String, String> returnMap = new HashMap<>();
195                 EEnum eenum = (EEnum)obj;
196
197                 String name = eenum.getName();
198                 for (EEnumLiteral eEnumLiteral : eenum.getELiterals())
199                 {
200                         Enumerator instance = eEnumLiteral.getInstance();
201                         String value = instance.getLiteral();
202                         valueList.add(value);
203                 }
204                 returnMap.put(name, valueList.toString());
205                 return returnMap;
206         }
207
208         public void getAttributes(String className, String dependency, EPackage root) {
209                 List<String> dpendList = new ArrayList<>();
210                 if (dependency!=null){
211                         dpendList = new ArrayList<>(Arrays.asList(dependency.split(",")));
212                 }
213                 MSAttributeObject msAttributeObject = new MSAttributeObject();
214                 msAttributeObject.setClassName(className);
215                 String extendClass = getSubTypes(root, className);
216                 Map<String, String> returnRefList = getRefAttributeList(root, className, extendClass);
217                 Map<String, String> returnAttributeList = getAttributeList(root, className, extendClass);
218                 Map<String, Object> returnSubList = getSubAttributeList(root, className, extendClass);
219                 HashMap<String, String> returnAnnotation = getAnnotation(root, className, extendClass);
220                 msAttributeObject.setAttribute(returnAttributeList);
221                 msAttributeObject.setRefAttribute(returnRefList);
222                 msAttributeObject.setSubClass(returnSubList);
223                 msAttributeObject.setDependency(dpendList.toString());
224                 msAttributeObject.addMatchingSet(returnAnnotation);
225                 msAttributeObject.setPolicyTempalate(isPolicyTemplate(root, className));
226
227                 this.classMap.put(className, msAttributeObject);        
228         }
229
230         private HashMap<String, String> getAnnotation(EPackage root, String className, String extendClass) {
231                 TreeIterator<EObject> treeItr = root.eAllContents();
232                 boolean requiredAttribute = false; 
233                 boolean requiredMatchAttribute = false;
234                 HashMap<String, String> annotationSet = new HashMap<>();
235                 String  matching;
236                 String range;
237                 String dictionary;
238
239                 //    Pulling out dependency from file
240                 while (treeItr.hasNext()) {         
241                         EObject obj = treeItr.next();
242                         if (obj instanceof EClassifier) {
243                                 requiredAttribute = isRequiredAttribute(obj,  className );
244                                 requiredMatchAttribute = isRequiredAttribute(obj,  extendClass );
245                         }
246
247                         if (requiredAttribute){
248                                 if (obj instanceof EStructuralFeature) {
249                                         EStructuralFeature eStrucClassifier = (EStructuralFeature) obj;
250                                         if (!eStrucClassifier.getEAnnotations().isEmpty()) {
251                                                 matching  = annotationValue(eStrucClassifier, ANNOTATION_TYPE.MATCHING, policy);
252                                                 if (matching!=null){
253                                                         annotationSet.put(eStrucClassifier.getName(), matching);
254                                                 }
255                                                 range  = annotationValue(eStrucClassifier, ANNOTATION_TYPE.VALIDATION, policy);
256                                                 if (range!=null){
257                                                         annotationSet.put(eStrucClassifier.getName(), range);
258                                                 }
259                                                 dictionary = annotationValue(eStrucClassifier, ANNOTATION_TYPE.DICTIONARY, policy);
260                                                 if (dictionary!=null){
261                                                         annotationSet.put(eStrucClassifier.getName(), dictionary);
262                                                 }
263                                         }
264                                 }
265                         } else if (requiredMatchAttribute){
266                                 if (obj instanceof EStructuralFeature) {
267                                         EStructuralFeature eStrucClassifier = (EStructuralFeature) obj;
268                                         if (!eStrucClassifier.getEAnnotations().isEmpty()) {
269                                                 matching  = annotationValue(eStrucClassifier, ANNOTATION_TYPE.MATCHING, policy);
270                                                 if (matching!=null){
271                                                         if (obj instanceof EReference){
272                                                                 EClass refType = ((EReference) obj).getEReferenceType();
273                                                                 annotationSet.put(refType.getName(), matching);
274                                                                 matchingClass.put(refType.getName(), matching);
275                                                         }else{
276                                                                 annotationSet.put(eStrucClassifier.getName(), matching);
277                                                         }
278                                                 }
279                                         }
280                                 }
281                         }
282                 }
283                 return annotationSet;
284         }
285
286         private Map<String, Object> getSubAttributeList(EPackage root, String className , String superClass) {
287                 TreeIterator<EObject> treeItr = root.eAllContents();
288                 boolean requiredAttribute = false; 
289                 Map<String, Object> subAttribute = new HashMap<>();
290                 int rollingCount = 0;
291                 int processClass = 0;
292                 boolean annotation;
293
294                 //    Pulling out dependency from file
295                 while (treeItr.hasNext() && rollingCount < 2) {  
296
297                         EObject obj = treeItr.next();
298                         if (obj instanceof EClassifier) {
299                                 if (isRequiredAttribute(obj,  className ) || isRequiredAttribute(obj,  superClass )){
300                                         requiredAttribute = true;
301                                 }else {
302                                         requiredAttribute = false;
303                                 }
304                                 if (requiredAttribute){
305                                         processClass++;
306                                 }
307                                 rollingCount = rollingCount+processClass;
308                         }
309
310                         if (requiredAttribute)   {
311                                 if (obj instanceof EStructuralFeature) {
312                                         EStructuralFeature eStrucClassifier = (EStructuralFeature) obj;
313                                         if (!eStrucClassifier.getEAnnotations().isEmpty()) {
314                                                 annotation = annotationTest(eStrucClassifier, configuration, onap);
315                                                 if (annotation &&  obj instanceof EReference) {
316                                                         EClass refType = ((EReference) obj).getEReferenceType();
317                                                         if(!refType.toString().contains(eProxyURI)){
318                                                                 String required = ":required-false";
319                                                                 if(eStrucClassifier.getLowerBound() == 1){
320                                                                         required = ":required-true";
321                                                                 }
322                                                                 subAttribute.put(eStrucClassifier.getName(), refType.getName() + required);                                             
323                                                         }
324                                                 }       
325                                         }
326                                 }
327                         }
328                 }
329                 return subAttribute;
330         }
331
332         public String checkDefultValue(String defultValue) {
333                 if (defultValue!=null){
334                         return ":defaultValue-"+ defultValue;
335                 }
336                 return ":defaultValue-NA";
337
338         }
339
340         public String checkRequiredPattern(int upper, int lower) {      
341
342                 String pattern = XACMLProperties.getProperty(XACMLRestProperties.PROP_XCORE_REQUIRED_PATTERN);
343
344                 if (pattern!=null){
345                         if (upper == Integer.parseInt(pattern.split(",")[1]) && lower==Integer.parseInt(pattern.split(",")[0])){
346                                 return ":required-true";
347                         }
348                 }
349
350                 return ":required-false";
351         }
352
353         public JSONObject buildJavaObject(Map<String, String> map){
354
355                 JSONObject returnValue = new JSONObject(map);
356
357                 return returnValue;
358
359         }
360
361         public Map<String, String> getRefAttributeList(EPackage root, String className, String superClass){
362
363                 TreeIterator<EObject> treeItr = root.eAllContents();
364                 boolean requiredAttribute = false; 
365                 HashMap<String, String> refAttribute = new HashMap<>();
366                 int rollingCount = 0;
367                 int processClass = 0;
368                 boolean annotation;
369                 //    Pulling out dependency from file
370                 while (treeItr.hasNext()) {         
371                         EObject obj = treeItr.next();
372                         if (obj instanceof EClassifier) {
373                                 if (isRequiredAttribute(obj,  className ) || isRequiredAttribute(obj,  superClass )){
374                                         requiredAttribute = true;
375                                 }else {
376                                         requiredAttribute = false;
377                                 }       
378                                 if (requiredAttribute){
379                                         processClass++;
380                                 }
381                                 rollingCount = rollingCount+processClass;
382                         }
383
384                         if (requiredAttribute)   {
385                                 if (obj instanceof EStructuralFeature) {
386                                         EStructuralFeature eStrucClassifier = (EStructuralFeature) obj;
387                                         if (!eStrucClassifier.getEAnnotations().isEmpty()) {
388                                                 annotation = annotationTest(eStrucClassifier, configuration, onap);
389                                                 if ( annotation &&  obj instanceof EReference) {
390                                                         EClass refType = ((EReference) obj).getEReferenceType();
391                                                         if(refType.toString().contains(eProxyURI)){
392                                                                 String one = refType.toString().split(eProxyURI)[1];
393                                                                 String refValue = StringUtils.replaceEach(one.split("#")[1], new String[]{"//", ")"}, new String[]{"", ""});                                                    
394                                                                 refAttribute.put(eStrucClassifier.getName(), refValue);                                                 
395                                                         } else {
396                                                                 String array = arrayCheck(((EStructuralFeature) obj).getUpperBound());
397                                                                 String required = ":required-false";
398                                                                 if(((EStructuralFeature) obj).getLowerBound() == 1){
399                                                                         required = ":required-true";
400                                                                 }
401                                                                 refAttribute.put(eStrucClassifier.getName(), refType.getName() + array + required);
402                                                         }
403                                                 } else if (annotation &&  obj instanceof EAttributeImpl){
404                                                         EClassifier refType = ((EAttributeImpl) obj).getEType();
405                                                         if (refType instanceof EEnumImpl){
406                                                                 String array = arrayCheck(((EStructuralFeature) obj).getUpperBound());
407                                                                 String required = ":required-false";
408                                                                 if(((EStructuralFeature) obj).getLowerBound() == 1){
409                                                                         required = ":required-true";
410                                                                 }
411                                                                 refAttribute.put(eStrucClassifier.getName(), refType.getName() + array + required);                                                     
412                                                         }
413                                                 }       
414                                         }
415                                 }
416                         }
417                 }
418                 
419                 return refAttribute;
420         }
421
422         private boolean annotationTest(EStructuralFeature eStrucClassifier, String annotation, String type) {
423                 String annotationType;
424                 EAnnotation eAnnotation;
425                 String onapType;
426                 String onapValue;
427
428                 EList<EAnnotation> value = eStrucClassifier.getEAnnotations();
429
430                 for (int i = 0; i < value.size(); i++){
431                         annotationType = value.get(i).getSource();
432                         eAnnotation = eStrucClassifier.getEAnnotations().get(i);
433                         onapType = eAnnotation.getDetails().get(0).getValue();
434                         onapValue = eAnnotation.getDetails().get(0).getKey();
435                         if (annotationType.contains(type) && onapType.contains(annotation)){
436                                 return true;
437                         } else if (annotationType.contains(type) && onapValue.contains(annotation)){
438                                 return true;
439                         }
440                 }
441
442                 return false;
443         }
444
445
446         private String annotationValue(EStructuralFeature eStrucClassifier, ANNOTATION_TYPE annotation, String type) {
447                 String annotationType;
448                 EAnnotation eAnnotation;
449                 String onapType;
450                 String onapValue = null;
451
452                 EList<EAnnotation> value = eStrucClassifier.getEAnnotations();
453
454                 for (int i = 0; i < value.size(); i++){
455                         annotationType = value.get(i).getSource();
456                         eAnnotation = eStrucClassifier.getEAnnotations().get(i);
457                         onapType = eAnnotation.getDetails().get(0).getKey();
458                         if (annotationType.contains(type) && onapType.compareToIgnoreCase(annotation.toString())==0){
459                                 onapValue = eAnnotation.getDetails().get(0).getValue();
460                                 if (annotation == ANNOTATION_TYPE.VALIDATION){
461                                         return onapValue;
462                                 } else {
463                                         return onapType + "-" + onapValue;
464                                 }
465                         }
466                 }
467
468                 return onapValue;
469         }
470         public boolean isRequiredAttribute(EObject obj, String className){
471                 EClassifier eClassifier = (EClassifier) obj;
472                 String workingClass = eClassifier.getName();
473                 workingClass.trim();
474                 if (workingClass.equalsIgnoreCase(className)){
475                         return  true;
476                 }
477
478                 return false;
479         } 
480
481         private boolean isPolicyTemplate(EPackage root, String className){
482
483                 for (EClassifier classifier : root.getEClassifiers()){ 
484                         if (classifier instanceof EClass) { 
485                                 EClass eClass = (EClass)classifier; 
486                                 if (eClass.getName().contentEquals(className)){
487                                         EList<EAnnotation> value = eClass.getEAnnotations();
488                                         for (EAnnotation workingValue : value){
489                                                 EMap<String, String> keyMap = workingValue.getDetails();        
490                                                 if (keyMap.containsKey("policyTemplate")){
491                                                         return true;
492                                                 }
493                                         }       
494                                 }
495                         }
496                 }
497                 return false;
498         }
499         private String getSubTypes(EPackage root, String className) {
500                 String returnSubTypes = null;
501                 for (EClassifier classifier : root.getEClassifiers()){ 
502                         if (classifier instanceof EClass) { 
503                                 EClass eClass = (EClass)classifier; 
504
505                                 for (EClass eSuperType : eClass.getEAllSuperTypes()) 
506                                 { 
507                                         if (eClass.getName().contentEquals(className)){
508                                                 returnSubTypes = eSuperType.getName();
509                                         }
510                                 } 
511                         } 
512                 } 
513                 return returnSubTypes;
514         } 
515
516         public Map<String, String> getAttributeList(EPackage root, String className, String superClass){
517
518                 TreeIterator<EObject> treeItr = root.eAllContents();
519                 boolean requiredAttribute = false; 
520                 HashMap<String, String> refAttribute = new HashMap<>();
521                 boolean annotation;
522                 boolean dictionaryTest;
523                 String defaultValue;
524                 String eType;
525
526                 //    Pulling out dependency from file
527                 while (treeItr.hasNext()) {         
528                         EObject obj = treeItr.next();
529                         if (obj instanceof EClassifier) {
530                                 if (isRequiredAttribute(obj,  className ) || isRequiredAttribute(obj,  superClass )){
531                                         requiredAttribute = true;
532                                 }else {
533                                         requiredAttribute = false;
534                                 }
535
536                         }
537
538                         if (requiredAttribute){
539                                 if (obj instanceof EStructuralFeature) {
540                                         EStructuralFeature eStrucClassifier = (EStructuralFeature) obj;
541                                         if (!eStrucClassifier.getEAnnotations().isEmpty()) {
542                                                 annotation = annotationTest(eStrucClassifier, configuration, onap);
543                                                 dictionaryTest = annotationTest(eStrucClassifier, dictionary, policy);
544                                                 EClassifier refType = ((EStructuralFeature) obj).getEType();
545                                                 if (annotation && !(obj instanceof EReference) && !(refType instanceof EEnumImpl)) {
546                                                         String name = eStrucClassifier.getName();
547                                                         if (dictionaryTest){
548                                                                 eType = annotationValue(eStrucClassifier, ANNOTATION_TYPE.DICTIONARY, policy);
549                                                         }else {
550                                                                 eType = eStrucClassifier.getEType().getInstanceClassName();
551                                                         }
552                                                         defaultValue = checkDefultValue(((EStructuralFeature) obj).getDefaultValueLiteral());
553
554                                                         String array = arrayCheck(((EStructuralFeature) obj).getUpperBound());
555                                                         String required = checkRequiredPattern(((EStructuralFeature) obj).getUpperBound(), ((EStructuralFeature) obj).getLowerBound());
556                                                         String attributeValue =  eType + defaultValue + required + array;
557                                                         refAttribute.put(name, attributeValue); 
558                                                 }
559                                         }
560                                 }
561                         }
562                 }
563                 return refAttribute;
564
565         }
566
567         public String arrayCheck(int upperBound) {
568
569                 if (upperBound == -1){
570                         return ":MANY-true";
571                 }
572
573                 return ":MANY-false";
574         }
575
576         public List<String> getDependencyList(EClassifier eClassifier, String className){
577                 List<String> returnValue = new ArrayList<>();;
578                 EList<EClass> somelist = ((EClass) eClassifier).getEAllSuperTypes();
579                 if (somelist.isEmpty()){
580                         return returnValue;
581                 }
582                 for(EClass depend: somelist){
583                         if (depend.toString().contains(eProxyURI)){
584                                 String one = depend.toString().split(eProxyURI)[1];
585                                 String value = StringUtils.replaceEach(one.split("#")[1], new String[]{"//", ")"}, new String[]{"", ""});
586                                 returnValue.add(value);
587                         }
588                 }
589
590                 return returnValue;
591         }
592
593         public Map<String, String> buildSubList(Map<String, String> subClassAttributes, Map<String, MSAttributeObject> classMap, String className){
594                 Map<String, String> missingValues = new HashMap<>();
595                 Map<String, String> workingMap;
596                 boolean enumType;
597
598                 for ( Entry<String, String> map : classMap.get(className).getRefAttribute().entrySet()){
599                         String value = map.getValue().split(":")[0];
600                         if (value!=null){
601                                 classMap.get(className).getEnumType();
602                                 enumType = classMap.get(className).getEnumType().containsKey(value);
603                                 if (!enumType){
604                                         workingMap =  classMap.get(value).getRefAttribute();
605                                         for ( Entry<String, String> subMab : workingMap.entrySet()){
606                                                 String value2 = subMab.getValue().split(":")[0];
607                                                 if (!subClassAttributes.containsValue(value2)){
608                                                         missingValues.put(subMab.getKey(), subMab.getValue());
609                                                 }
610                                         }
611
612                                 }
613                         }
614                 }
615
616                 return missingValues;
617         }
618
619         public Map<String, Map<String, String>> recursiveReference(Map<String, MSAttributeObject> classMap, String className){
620
621                 Map<String, Map<String, String>> returnObject = new HashMap<>();
622                 Map<String, String> returnClass = getRefclass(classMap, className);
623                 returnObject.put(className, returnClass);
624                 for (Entry<String, String> reAttribute :returnClass.entrySet()){
625                         if (reAttribute.getValue().split(":")[1].contains("MANY")){
626                                 if (classMap.get(reAttribute.getValue().split(":")[0]) != null){
627                                         returnObject.putAll(recursiveReference(classMap, reAttribute.getValue().split(":")[0]));
628                                 }
629                         }
630
631                 }
632
633                 return returnObject;
634
635         }
636
637         public String createJson(Map<String, Object> subClassAttributes, Map<String, MSAttributeObject> classMap, String className) {
638                 boolean enumType;
639                 Map<String, Map<String, String>> myObject = new HashMap<>();
640                 for ( Entry<String, String> map : classMap.get(className).getRefAttribute().entrySet()){
641                         String value = map.getValue().split(":")[0];
642                         if (value!=null){
643                                 enumType = classMap.get(className).getEnumType().containsKey(value);
644                                 if (!enumType){
645                                         if (map.getValue().split(":")[1].contains("MANY")){
646                                                 Map<String, Map<String, String>> testRecursive = recursiveReference(classMap, map.getValue().split(":")[0] );
647                                                 myObject.putAll(testRecursive);
648                                         }
649                                 }
650                         }
651                 }
652
653                 Gson gson = new Gson(); 
654                 String json = gson.toJson(myObject); 
655
656                 return json;            
657         }
658
659         public Map<String, String> getRefclass(Map<String, MSAttributeObject> classMap, String className){
660                 HashMap<String, String> missingValues = new HashMap<>();
661
662                 if (classMap.get(className).getAttribute()!=null || !classMap.get(className).getAttribute().isEmpty()){
663                         missingValues.putAll(classMap.get(className).getAttribute());
664                 }
665
666                 if (classMap.get(className).getRefAttribute()!=null || !classMap.get(className).getRefAttribute().isEmpty()){
667                         missingValues.putAll(classMap.get(className).getRefAttribute());
668                 }
669
670                 return missingValues;   
671         }
672
673         public String createSubAttributes(List<String> dependency, Map<String, MSAttributeObject> classMap, String modelName) {
674
675                 HashMap <String,  Object>  workingMap = new HashMap<>();
676                 MSAttributeObject tempObject;
677                 if (dependency!=null){
678                         if (dependency.isEmpty()){
679                                 return "{}";
680                         }       
681                         dependency.add(modelName);
682                         for (String element: dependency){
683                                 tempObject = classMap.get(element);
684                                 if (tempObject!=null){
685                                         workingMap.putAll(classMap.get(element).getSubClass());
686                                 }
687                         }
688                 }
689
690                 String returnValue = createJson(workingMap, classMap, modelName);                       
691                 return returnValue;
692         }
693
694         public List<String> getFullDependencyList(List<String> dependency, Map<String,MSAttributeObject > classMap) {
695                 ArrayList<String> returnList = new ArrayList<>();
696                 ArrayList<String> workingList;
697                 returnList.addAll(dependency);
698                 for (String element : dependency ){
699                         if (classMap.containsKey(element)){
700                                 MSAttributeObject value = classMap.get(element);
701                                 String rawValue = StringUtils.replaceEach(value.getDependency(), new String[]{"[", "]"}, new String[]{"", ""});
702                                 workingList = new ArrayList<>(Arrays.asList(rawValue.split(",")));
703                                 for(String depend : workingList){
704                                         if (!returnList.contains(depend) && !depend.isEmpty()){
705                                                 returnList.add(depend.trim());
706                                         }
707                                 }
708                         }
709                 }
710
711                 return returnList;
712         }
713 }