/*PLEASE DO NOT EDIT THIS CODE*/ /*This code was generated using the UMPLE 1.35.0.7523.c616a4dce modeling language!*/ package example; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.sql.*; import java.lang.reflect.Constructor; // line 16 "../ToJsonComplexTest.ump" public class Student extends Person { //------------------------ // MEMBER VARIABLES //------------------------ //Student Attributes private float tuitionPaid; //Student Associations private University university; private List<Registration> registrations; //------------------------ // CONSTRUCTOR //------------------------ public Student(int aId, String aName, float aTuitionPaid, University aUniversity) { super(aId, aName); tuitionPaid = aTuitionPaid; boolean didAddUniversity = setUniversity(aUniversity); if (!didAddUniversity) { throw new RuntimeException("Unable to create student due to university. See https://manual.umple.org?RE002ViolationofAssociationMultiplicity.html"); } registrations = new ArrayList<Registration>(); } //------------------------ // INTERFACE //------------------------ public boolean setTuitionPaid(float aTuitionPaid) { boolean wasSet = false; tuitionPaid = aTuitionPaid; wasSet = true; return wasSet; } public float getTuitionPaid() { return tuitionPaid; } /* Code from template association_GetOne */ public University getUniversity() { return university; } /* Code from template association_GetMany */ public Registration getRegistration(int index) { Registration aRegistration = registrations.get(index); return aRegistration; } public List<Registration> getRegistrations() { List<Registration> newRegistrations = Collections.unmodifiableList(registrations); return newRegistrations; } public int numberOfRegistrations() { int number = registrations.size(); return number; } public boolean hasRegistrations() { boolean has = registrations.size() > 0; return has; } public int indexOfRegistration(Registration aRegistration) { int index = registrations.indexOf(aRegistration); return index; } /* Code from template association_SetOneToMany */ public boolean setUniversity(University aUniversity) { boolean wasSet = false; if (aUniversity == null) { return wasSet; } University existingUniversity = university; university = aUniversity; if (existingUniversity != null && !existingUniversity.equals(aUniversity)) { existingUniversity.removeStudent(this); } university.addStudent(this); wasSet = true; return wasSet; } /* Code from template association_MinimumNumberOfMethod */ public static int minimumNumberOfRegistrations() { return 0; } /* Code from template association_AddManyToOne */ public Registration addRegistration(CourseSection aCourseSection) { return new Registration(this, aCourseSection); } public boolean addRegistration(Registration aRegistration) { boolean wasAdded = false; if (registrations.contains(aRegistration)) { return false; } Student existingStudent = aRegistration.getStudent(); boolean isNewStudent = existingStudent != null && !this.equals(existingStudent); if (isNewStudent) { aRegistration.setStudent(this); } else { registrations.add(aRegistration); } wasAdded = true; return wasAdded; } public boolean removeRegistration(Registration aRegistration) { boolean wasRemoved = false; //Unable to remove aRegistration, as it must always have a student if (!this.equals(aRegistration.getStudent())) { registrations.remove(aRegistration); wasRemoved = true; } return wasRemoved; } /* Code from template association_AddIndexControlFunctions */ public boolean addRegistrationAt(Registration aRegistration, int index) { boolean wasAdded = false; if(addRegistration(aRegistration)) { if(index < 0 ) { index = 0; } if(index > numberOfRegistrations()) { index = numberOfRegistrations() - 1; } registrations.remove(aRegistration); registrations.add(index, aRegistration); wasAdded = true; } return wasAdded; } public boolean addOrMoveRegistrationAt(Registration aRegistration, int index) { boolean wasAdded = false; if(registrations.contains(aRegistration)) { if(index < 0 ) { index = 0; } if(index > numberOfRegistrations()) { index = numberOfRegistrations() - 1; } registrations.remove(aRegistration); registrations.add(index, aRegistration); wasAdded = true; } else { wasAdded = addRegistrationAt(aRegistration, index); } return wasAdded; } public void delete() { University placeholderUniversity = university; this.university = null; if(placeholderUniversity != null) { placeholderUniversity.removeStudent(this); } for(int i=registrations.size(); i > 0; i--) { Registration aRegistration = registrations.get(i - 1); aRegistration.delete(); } super.delete(); } public String toString() { return super.toString() + "["+ "tuitionPaid" + ":" + getTuitionPaid()+ "]" + System.getProperties().getProperty("line.separator") + " " + "university = "+(getUniversity()!=null?Integer.toHexString(System.identityHashCode(getUniversity())):"null"); } /* * Generate Json for this object and connected objects visited objects to enable avoidance of infinite loops * * @return a string in Json format of this object */ public String toJson() { HashSet<Object> visitedList = new HashSet<Object>(); StringBuilder toJsonOutput = new StringBuilder(); toJsonOutput.append("{\n"); this.toJsonHelper(toJsonOutput, visitedList,1,true); toJsonOutput.append("\n}"); return(toJsonOutput.toString()); } /* * Helper function to generate Json for this object and connected objects visited objects to enable avoidance of infinite loops * * @param toJsonOutput Output is aded to this as the network of objects is traversed * @param visitedList Every concrete object visited is added so we don't re-outpu * @param nestLevel As we output deeper objects, indent them more * @param atConcreteClass false when we are recursing to a superclass * so we get the superclass data * @return whether or not anything was output (so we can tell whether we need to output a comma) */ public boolean toJsonHelper(StringBuilder toJsonOutput, HashSet<Object> visitedList, int nestLevel, boolean atConcreteClass){ String indent = " ".repeat(nestLevel); boolean alreadyVisited = false; boolean haveOutputItem = false; if(atConcreteClass) { // This will not be true in a super call; output header toJsonOutput.append(indent+"\""+this.toString().split("@")[0]+ "\" : {\n"+indent+ " \"umpleObjectID\" : \""+System.identityHashCode(this)+"\""); // Check if we have already visited this object. If so we will not output details alreadyVisited = visitedList.contains(this); if(!alreadyVisited) { toJsonOutput.append(",\n"); visitedList.add(this); } } // There is no superclass of this class if(alreadyVisited) { toJsonOutput.append("\n"); } else { // Check if this class has a superclass. If it does, we make a call to output superclass content // This will keep calling super so the topmost attributes and associations appear first haveOutputItem = super.toJsonHelper(toJsonOutput, visitedList, nestLevel, false); // When an object has not already been visited, output its details if(haveOutputItem){ //toJsonOutput.append(",\n"); } if(haveOutputItem){ toJsonOutput.append(",\n"); } toJsonOutput.append(indent); toJsonOutput.append(" \""); toJsonOutput.append("tuitionPaid"); toJsonOutput.append("\" : \""); String primValue_0=""+getTuitionPaid()+""; toJsonOutput.append(primValue_0.replace("\\","\\\\").replace("\"","\\\"")); toJsonOutput.append("\""); haveOutputItem=true; //haveOutputItem = false; //haveOutputItem = false; if(haveOutputItem) { toJsonOutput.append(",\n"); } toJsonOutput.append(indent); toJsonOutput.append("\n"+indent); toJsonOutput.append(" \""); toJsonOutput.append("university"); toJsonOutput.append("\""); toJsonOutput.append(" : "); toJsonOutput.append("\n"); toJsonOutput.append(indent+" {"); toJsonOutput.append("\n");University anotherItem_0 = getUniversity(); anotherItem_0.toJsonHelper(toJsonOutput, visitedList, nestLevel+2, true); toJsonOutput.append("\n"); toJsonOutput.append(indent+" }"); haveOutputItem=true; if(haveOutputItem) { toJsonOutput.append(",\n"); } toJsonOutput.append(indent); toJsonOutput.append(" \""); toJsonOutput.append("registrations"); toJsonOutput.append("\""); toJsonOutput.append(" : ["); toJsonOutput.append("\n"); haveOutputItem = false; try{ for (Registration anItem_1 :getRegistrations()){ if(haveOutputItem) { toJsonOutput.append(",\n"); } toJsonOutput.append(indent+" {"); toJsonOutput.append("\n"); anItem_1.toJsonHelper(toJsonOutput, visitedList,nestLevel+2,true); toJsonOutput.append("\n"); toJsonOutput.append(indent+" }"); haveOutputItem=true; } }catch (NullPointerException e){ } toJsonOutput.append("\n"); toJsonOutput.append(indent+" ]"); haveOutputItem=true; toJsonOutput.append(indent+" \n"); } // Finalize the output of the concrete class if(atConcreteClass) { if(!alreadyVisited) { toJsonOutput.append("\n"); } toJsonOutput.append(indent+"}"); } haveOutputItem = true; return haveOutputItem; } /* * Deserialize Json string to instantiate Objects from top-level class * * @param umpleObjectIDMap<String, Object> mapping parsed objectID (from Json string) with newly instantiated object's objectID * * @param String aJsonString is the string in json format that is to be processed and turned into an object * * @return newly instantiated Object */ public static Student fromJson(String aJsonString){ // process the input jsonString so that it can further processed using regex aJsonString=aJsonString.replace("\n","").replace(" ",""); // a map to store the umpleObjectID present in jsonString Map<String, Object> umpleObjectIDMap=new HashMap<>(); // instantiate a new object Student anObject = new Student(aJsonString, umpleObjectIDMap); return anObject; } /* * A new constructor specifically implemented if -s genJson is specified * * @param String aJsonString is the string in json format that is to be processed and turned into an object * * @param umpleObjectIDMap<String, Integer> mapping parsed objectID (from Json string) with newly instantiated object's objectID */ @SuppressWarnings("unchecked") public Student(String aJsonString, Map<String, Object> umpleObjectIDMap){ // Initialize a HashMap to store the parsed result // key is the attribute name present in the jsonString // value is the attribute value present in the jsonString super(aJsonString,umpleObjectIDMap); boolean visitedSuperClass=true; HashMap<String,String> parsedResult = new HashMap<String,String>(); parsedResult = fromJsonParser(aJsonString); if(!parsedResult.isEmpty()){ boolean classExist; boolean classChildExist; String parsedClassName=parsedResult.get("className"); String childName=this.getClass().getSimpleName(); classExist="Student".equals(parsedClassName); classChildExist=childName.equals(parsedClassName); // if top-level class does not exist, throw exception if(!classExist&&!classChildExist){ throw new IllegalArgumentException("Top-level class \""+parsedClassName+"\" does not exist, please check the input json string"); } String umpleObjectId=parsedResult.get("umpleObjectID"); // Check if the object has already been visited and created //if((umpleObjectIDMap.get(umpleObjectId)==null)||visitedSuperClass){ try{ visitedSuperClass=false; // map the old objectID (in jsonString) with the newly created object's hashCode in umpleObjectIDMap umpleObjectIDMap.put(umpleObjectId,this); String jsonKey=""; jsonKey="tuitionPaid"; //more types should be considered here float valueFloat=Float.parseFloat(parsedResult.get(jsonKey)); this.tuitionPaid=valueFloat; // below for-loop check the association class of the top level class jsonKey="university"; String newJsonString_0=parsedResult.get(jsonKey); String newIDRegex_0="\\\"umpleObjectID\\\"\\:\\\"[0-9]*\\\""; String newUmpleID_0=fromJsonParserHelper(newJsonString_0,newIDRegex_0); //Multiple associations if(!umpleObjectIDMap.containsKey(newUmpleID_0)){ String newClassNameOne_0=fromJsonParserClassName(newJsonString_0); Class clazzOne_0=Class.forName(newClassNameOne_0); Constructor constructorOne_0=clazzOne_0.getConstructor(String.class, Map.class); Object objectNewOne_0=constructorOne_0.newInstance(newJsonString_0,umpleObjectIDMap); University oneAssoObj_0=(University)objectNewOne_0; university=oneAssoObj_0; } else{ university=(University)umpleObjectIDMap.get(newUmpleID_0); } jsonKey="registrations"; String newJsonString_1=parsedResult.get(jsonKey); String newIDRegex_1="\\\"umpleObjectID\\\"\\:\\\"[0-9]*\\\""; String newUmpleID_1=fromJsonParserHelper(newJsonString_1,newIDRegex_1); //Multiple associations List<String> multiAssoObjList_1 = new ArrayList<String>(); multiAssoObjList_1=fromJsonParserList(newJsonString_1); registrations=new ArrayList<Registration>(); for(String obj: multiAssoObjList_1){ newUmpleID_1=fromJsonParserHelper(obj,newIDRegex_1); String newClassName_1=fromJsonParserClassName(obj); if(!umpleObjectIDMap.containsKey(newUmpleID_1)){ boolean subClassFound=false; Class clazz_1=Class.forName(newClassName_1); Constructor constructor_1=clazz_1.getConstructor(String.class, Map.class); Object objectNew_1=constructor_1.newInstance(obj,umpleObjectIDMap); registrations.add((Registration)objectNew_1); } else{ registrations.add((Registration)umpleObjectIDMap.get(newUmpleID_1)); } } }catch(Exception e){ } //} } } /* * A json parser to parse the input jsonString, if -s genJson is specified * * @param String aJsonString is the string in json format that is to be processed and turned into an object * * @ return HashMap<String,String> that stores paresed result, key is the attribute(or associations) of an object, value is the attribute value or association string */ public static HashMap<String,String> fromJsonParser(String jsonString){ HashMap<String,String> parsedResultMap = new HashMap<String,String>(); try{ //Below (String, Pattern, Matcher) are the regex strings and their patterns and matcher used to process a jsonString // topLevelString is the regex representing the topLevel class name String topLevelString = "\\{\\\"[A-Z]\\w*\\\":"; Pattern topLevelPattern = Pattern.compile(topLevelString); Matcher topLevelMatcher = topLevelPattern.matcher(jsonString); String quotes="\\\""; String colon="\\:"; String colonSquareBracket="\\:\\["; if(topLevelMatcher.find()){ //actual string that represent the topLevel className String topLevelStringFound=topLevelMatcher.group(0); String className=topLevelStringFound.split(quotes)[1]; parsedResultMap.put("className", className); jsonString=jsonString.split(topLevelString,2)[1]; //objIDString is the regex representing umpleObjectID that could be found in jsonString String objIDString = "\"umpleObjectID\"\\:\"[0-9]*\","; Pattern objIDPattern = Pattern.compile(objIDString); Matcher objIDMatcher = objIDPattern.matcher(jsonString); if(objIDMatcher.find()){ String objIDFound=objIDMatcher.group(0); parsedResultMap.put("umpleObjectID", objIDFound.split(colon)[1].split(quotes)[1]); jsonString=jsonString.replaceFirst(objIDFound,""); } String timeString="\\\"\\w*\\\"\\:\\\"\\d{2}:\\d{2}\\:\\d{2}\\\""; Pattern timeStringPattern=Pattern.compile(timeString); Matcher timeStringPatternMatcher=timeStringPattern.matcher(jsonString); if(timeStringPatternMatcher.find()){ String timeStringFound=timeStringPatternMatcher.group(0); parsedResultMap.put(timeStringFound.split(colon,2)[0].split(quotes)[1], timeStringFound.split(colon,2)[1].split(quotes)[1]); } // pairString is the regex for an object's attribute and attribute value, the string parsed will be in key-value formate String pairString = "(\\\"(?!umpleObjectID)[^\\\"]+)\\\":\\\"((?:\\\\\\\"|[^\\\"])*)"; Pattern pairPattern=Pattern.compile(pairString); Matcher pairMatcher=pairPattern.matcher(jsonString); String associationString="(?=\\\"\\w*\\\"\\:\\[\\{)(?:(?=.*?\\[\\{(?!.*?\\1)(.*\\}\\](?!.*\\2).*))(?=.*?\\}\\](?!.*?\\2)(.*)).)+?.*?(?=\\1)[^\\[]*(?=\\2$)"; Pattern associationPattern=Pattern.compile(associationString); String newObjJsonString="(?=\\,\\\"\\w*\\\"\\:\\{)(?:(?=.*?\\{\\\"(?!.*?\\1)(.*\\}(?!.*\\2).*))(?=.*?\\}(?!.*?\\2)(.*)).)+?.*?(?=\\1)[^\\{]*(?=\\2$)"; Pattern newObjJsonPattern=Pattern.compile(newObjJsonString); String quoteColonQuote="\\\"\\:\\\""; //Keep on parsing the attribute's key-value pair, //until a List (multi-associations) pattern or a newObject parttern (single association) is found while(pairMatcher.find()){ String pairStringFound=pairMatcher.group(0); if(parsedResultMap.get(pairStringFound.split(colon)[0].split(quotes)[1])==null){ String keyPair=pairStringFound.split(colon)[0].split(quotes)[1]; String valuePair=pairStringFound.split(quoteColonQuote,2)[1]; keyPair=keyPair.replace("\\\\","\\").replace("\\\"","\""); valuePair=valuePair.replace("\\\\","\\").replace("\\\"","\""); parsedResultMap.put(keyPair,valuePair); jsonString=jsonString.replaceFirst(pairString, ""); } int lastIndex = 0; while (lastIndex<jsonString.length()){ String remainingJson=jsonString.substring(lastIndex); Matcher associationMatcher=associationPattern.matcher(jsonString); Matcher newObjJsonMatcher=newObjJsonPattern.matcher(jsonString); boolean assoFound=associationMatcher.find(); boolean newObjFound=newObjJsonMatcher.find(); if (assoFound&&(!newObjFound||associationMatcher.start()<newObjJsonMatcher.start())){ String assoStringFound=associationMatcher.group(0); String associationName=assoStringFound.split(colon,2)[0].split(quotes)[1];; String associationItems=assoStringFound.split(colonSquareBracket,2)[1]; parsedResultMap.put(associationName, associationItems); jsonString=jsonString.replaceFirst(associationString, ""); } else if (newObjFound){ String newObjJsonFound=newObjJsonMatcher.group(0); String newObjName=newObjJsonFound.split(colon,2)[0].split(quotes)[1]; String newObjItems=newObjJsonFound.split(colon,2)[1]; parsedResultMap.put(newObjName, newObjItems); jsonString=jsonString.replaceFirst(newObjJsonString, ""); }else{ break; } } } } return parsedResultMap; }catch(NullPointerException e){ return parsedResultMap; } } public static String fromJsonParserHelper(String jsonString, String regexString){ String umpleID = ""; String quo="\\\""; try{ Pattern umpleIDPattern=Pattern.compile(regexString); Matcher umpleIDMatcher=umpleIDPattern.matcher(jsonString); if(umpleIDMatcher.find()){ String umpleIDStringFound=umpleIDMatcher.group(0); String idString="\\\"\\d*\\\""; Pattern idPattern=Pattern.compile(idString); Matcher idMatcher=idPattern.matcher(umpleIDStringFound); if(idMatcher.find()){ umpleID=idMatcher.group(0).split(quo)[1]; } } return umpleID; } catch(NullPointerException e){ return umpleID; } } public static List<String> fromJsonParserList(String objListString){ List<String> objList=new ArrayList<String>(); try{ String objString="(?:(?=.*?\\{(?!.*?\\1)(.*\\}(?!.*\\2).*))(?=.*?\\}(?!.*?\\2)(.*)).)+?.*?(?=\\1)[^\\{]*(?=\\2$)"; Pattern objStringPattern=Pattern.compile(objString); Matcher objStringMatcher=objStringPattern.matcher(objListString); while(objStringMatcher.find()){ objList.add(objStringMatcher.group(0)); } return objList; }catch(NullPointerException e){ return objList; } } public static String fromJsonParserClassName(String objNameString){ String nextName=""; String quotes="\\\""; try{ String nextNameString="\\{\\\"[A-Z]\\w*\\\":"; Pattern nextNamePattern=Pattern.compile(nextNameString); Matcher nextNameMatcher=nextNamePattern.matcher(objNameString); if(nextNameMatcher.find()){ nextName=nextNameMatcher.group(0).split(quotes)[1]; } return nextName; }catch(NullPointerException e){ return nextName; } } } /*PLEASE DO NOT EDIT THIS CODE*/ /*This code was generated using the UMPLE 1.35.0.7523.c616a4dce modeling language!*/ package example; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.sql.*; import java.lang.reflect.Constructor; // line 4 "../ToJsonComplexTest.ump" public class University { //------------------------ // STATIC VARIABLES //------------------------ private static University theInstance = null; //------------------------ // MEMBER VARIABLES //------------------------ //University Attributes private String name; private float tuition; //University Associations private List<Course> courses; private List<Student> students; //------------------------ // CONSTRUCTOR //------------------------ private University() { name = null; tuition = 0.0f; courses = new ArrayList<Course>(); students = new ArrayList<Student>(); } public static University getInstance() { if(theInstance == null) { theInstance = new University(); } return theInstance; } //------------------------ // INTERFACE //------------------------ public boolean setName(String aName) { boolean wasSet = false; name = aName; wasSet = true; return wasSet; } public boolean setTuition(float aTuition) { boolean wasSet = false; tuition = aTuition; wasSet = true; return wasSet; } public String getName() { return name; } public float getTuition() { return tuition; } /* Code from template association_GetMany */ public Course getCourse(int index) { Course aCourse = courses.get(index); return aCourse; } public List<Course> getCourses() { List<Course> newCourses = Collections.unmodifiableList(courses); return newCourses; } public int numberOfCourses() { int number = courses.size(); return number; } public boolean hasCourses() { boolean has = courses.size() > 0; return has; } public int indexOfCourse(Course aCourse) { int index = courses.indexOf(aCourse); return index; } /* Code from template association_GetMany */ public Student getStudent(int index) { Student aStudent = students.get(index); return aStudent; } public List<Student> getStudents() { List<Student> newStudents = Collections.unmodifiableList(students); return newStudents; } public int numberOfStudents() { int number = students.size(); return number; } public boolean hasStudents() { boolean has = students.size() > 0; return has; } public int indexOfStudent(Student aStudent) { int index = students.indexOf(aStudent); return index; } /* Code from template association_MinimumNumberOfMethod */ public static int minimumNumberOfCourses() { return 0; } /* Code from template association_AddManyToOne */ public Course addCourse(String aTitle) { return new Course(aTitle, this); } public boolean addCourse(Course aCourse) { boolean wasAdded = false; if (courses.contains(aCourse)) { return false; } University existingUniversity = aCourse.getUniversity(); boolean isNewUniversity = existingUniversity != null && !this.equals(existingUniversity); if (isNewUniversity) { aCourse.setUniversity(this); } else { courses.add(aCourse); } wasAdded = true; return wasAdded; } public boolean removeCourse(Course aCourse) { boolean wasRemoved = false; //Unable to remove aCourse, as it must always have a university if (!this.equals(aCourse.getUniversity())) { courses.remove(aCourse); wasRemoved = true; } return wasRemoved; } /* Code from template association_AddIndexControlFunctions */ public boolean addCourseAt(Course aCourse, int index) { boolean wasAdded = false; if(addCourse(aCourse)) { if(index < 0 ) { index = 0; } if(index > numberOfCourses()) { index = numberOfCourses() - 1; } courses.remove(aCourse); courses.add(index, aCourse); wasAdded = true; } return wasAdded; } public boolean addOrMoveCourseAt(Course aCourse, int index) { boolean wasAdded = false; if(courses.contains(aCourse)) { if(index < 0 ) { index = 0; } if(index > numberOfCourses()) { index = numberOfCourses() - 1; } courses.remove(aCourse); courses.add(index, aCourse); wasAdded = true; } else { wasAdded = addCourseAt(aCourse, index); } return wasAdded; } /* Code from template association_MinimumNumberOfMethod */ public static int minimumNumberOfStudents() { return 0; } /* Code from template association_AddManyToOne */ public Student addStudent(int aId, String aName, float aTuitionPaid) { return new Student(aId, aName, aTuitionPaid, this); } public boolean addStudent(Student aStudent) { boolean wasAdded = false; if (students.contains(aStudent)) { return false; } University existingUniversity = aStudent.getUniversity(); boolean isNewUniversity = existingUniversity != null && !this.equals(existingUniversity); if (isNewUniversity) { aStudent.setUniversity(this); } else { students.add(aStudent); } wasAdded = true; return wasAdded; } public boolean removeStudent(Student aStudent) { boolean wasRemoved = false; //Unable to remove aStudent, as it must always have a university if (!this.equals(aStudent.getUniversity())) { students.remove(aStudent); wasRemoved = true; } return wasRemoved; } /* Code from template association_AddIndexControlFunctions */ public boolean addStudentAt(Student aStudent, int index) { boolean wasAdded = false; if(addStudent(aStudent)) { if(index < 0 ) { index = 0; } if(index > numberOfStudents()) { index = numberOfStudents() - 1; } students.remove(aStudent); students.add(index, aStudent); wasAdded = true; } return wasAdded; } public boolean addOrMoveStudentAt(Student aStudent, int index) { boolean wasAdded = false; if(students.contains(aStudent)) { if(index < 0 ) { index = 0; } if(index > numberOfStudents()) { index = numberOfStudents() - 1; } students.remove(aStudent); students.add(index, aStudent); wasAdded = true; } else { wasAdded = addStudentAt(aStudent, index); } return wasAdded; } public void delete() { for(int i=courses.size(); i > 0; i--) { Course aCourse = courses.get(i - 1); aCourse.delete(); } for(int i=students.size(); i > 0; i--) { Student aStudent = students.get(i - 1); aStudent.delete(); } } public String toString() { return super.toString() + "["+ "name" + ":" + getName()+ "," + "tuition" + ":" + getTuition()+ "]"; } /* * Generate Json for this object and connected objects visited objects to enable avoidance of infinite loops * * @return a string in Json format of this object */ public String toJson() { HashSet<Object> visitedList = new HashSet<Object>(); StringBuilder toJsonOutput = new StringBuilder(); toJsonOutput.append("{\n"); this.toJsonHelper(toJsonOutput, visitedList,1,true); toJsonOutput.append("\n}"); return(toJsonOutput.toString()); } /* * Helper function to generate Json for this object and connected objects visited objects to enable avoidance of infinite loops * * @param toJsonOutput Output is aded to this as the network of objects is traversed * @param visitedList Every concrete object visited is added so we don't re-outpu * @param nestLevel As we output deeper objects, indent them more * @param atConcreteClass false when we are recursing to a superclass * so we get the superclass data * @return whether or not anything was output (so we can tell whether we need to output a comma) */ public boolean toJsonHelper(StringBuilder toJsonOutput, HashSet<Object> visitedList, int nestLevel, boolean atConcreteClass){ String indent = " ".repeat(nestLevel); boolean alreadyVisited = false; boolean haveOutputItem = false; if(atConcreteClass) { // This will not be true in a super call; output header toJsonOutput.append(indent+"\""+this.toString().split("@")[0]+ "\" : {\n"+indent+ " \"umpleObjectID\" : \""+System.identityHashCode(this)+"\""); // Check if we have already visited this object. If so we will not output details alreadyVisited = visitedList.contains(this); if(!alreadyVisited) { toJsonOutput.append(",\n"); visitedList.add(this); } } // There is no superclass of this class if(alreadyVisited) { toJsonOutput.append("\n"); } else { // Check if this class has a superclass. If it does, we make a call to output superclass content // This will keep calling super so the topmost attributes and associations appear first // When an object has not already been visited, output its details if(haveOutputItem){ //toJsonOutput.append(",\n"); } if(haveOutputItem){ toJsonOutput.append(",\n"); } toJsonOutput.append(indent); toJsonOutput.append(" \""); toJsonOutput.append("name"); toJsonOutput.append("\" : \""); String primValue_0=""+getName()+""; toJsonOutput.append(primValue_0.replace("\\","\\\\").replace("\"","\\\"")); toJsonOutput.append("\""); haveOutputItem=true; if(haveOutputItem){ toJsonOutput.append(",\n"); } toJsonOutput.append(indent); toJsonOutput.append(" \""); toJsonOutput.append("tuition"); toJsonOutput.append("\" : \""); String primValue_1=""+getTuition()+""; toJsonOutput.append(primValue_1.replace("\\","\\\\").replace("\"","\\\"")); toJsonOutput.append("\""); haveOutputItem=true; //haveOutputItem = false; //haveOutputItem = false; if(haveOutputItem) { toJsonOutput.append(",\n"); } toJsonOutput.append(indent); toJsonOutput.append(" \""); toJsonOutput.append("courses"); toJsonOutput.append("\""); toJsonOutput.append(" : ["); toJsonOutput.append("\n"); haveOutputItem = false; try{ for (Course anItem_0 :getCourses()){ if(haveOutputItem) { toJsonOutput.append(",\n"); } toJsonOutput.append(indent+" {"); toJsonOutput.append("\n"); anItem_0.toJsonHelper(toJsonOutput, visitedList,nestLevel+2,true); toJsonOutput.append("\n"); toJsonOutput.append(indent+" }"); haveOutputItem=true; } }catch (NullPointerException e){ } toJsonOutput.append("\n"); toJsonOutput.append(indent+" ]"); haveOutputItem=true; if(haveOutputItem) { toJsonOutput.append(",\n"); } toJsonOutput.append(indent); toJsonOutput.append(" \""); toJsonOutput.append("students"); toJsonOutput.append("\""); toJsonOutput.append(" : ["); toJsonOutput.append("\n"); haveOutputItem = false; try{ for (Student anItem_1 :getStudents()){ if(haveOutputItem) { toJsonOutput.append(",\n"); } toJsonOutput.append(indent+" {"); toJsonOutput.append("\n"); anItem_1.toJsonHelper(toJsonOutput, visitedList,nestLevel+2,true); toJsonOutput.append("\n"); toJsonOutput.append(indent+" }"); haveOutputItem=true; } }catch (NullPointerException e){ } toJsonOutput.append("\n"); toJsonOutput.append(indent+" ]"); haveOutputItem=true; toJsonOutput.append(indent+" \n"); } // Finalize the output of the concrete class if(atConcreteClass) { if(!alreadyVisited) { toJsonOutput.append("\n"); } toJsonOutput.append(indent+"}"); } haveOutputItem = true; return haveOutputItem; } /* * Deserialize Json string to instantiate Objects from top-level class * * @param umpleObjectIDMap<String, Object> mapping parsed objectID (from Json string) with newly instantiated object's objectID * * @param String aJsonString is the string in json format that is to be processed and turned into an object * * @return newly instantiated Object */ public static University fromJson(String aJsonString){ // process the input jsonString so that it can further processed using regex aJsonString=aJsonString.replace("\n","").replace(" ",""); // a map to store the umpleObjectID present in jsonString Map<String, Object> umpleObjectIDMap=new HashMap<>(); // instantiate a new object University anObject = new University(aJsonString, umpleObjectIDMap); return anObject; } /* * A new constructor specifically implemented if -s genJson is specified * * @param String aJsonString is the string in json format that is to be processed and turned into an object * * @param umpleObjectIDMap<String, Integer> mapping parsed objectID (from Json string) with newly instantiated object's objectID */ @SuppressWarnings("unchecked") public University(String aJsonString, Map<String, Object> umpleObjectIDMap){ // Initialize a HashMap to store the parsed result // key is the attribute name present in the jsonString // value is the attribute value present in the jsonString boolean visitedSuperClass=false; HashMap<String,String> parsedResult = new HashMap<String,String>(); parsedResult = fromJsonParser(aJsonString); if(!parsedResult.isEmpty()){ boolean classExist; boolean classChildExist; String parsedClassName=parsedResult.get("className"); String childName=this.getClass().getSimpleName(); classExist="University".equals(parsedClassName); classChildExist=childName.equals(parsedClassName); // if top-level class does not exist, throw exception if(!classExist&&!classChildExist){ throw new IllegalArgumentException("Top-level class \""+parsedClassName+"\" does not exist, please check the input json string"); } String umpleObjectId=parsedResult.get("umpleObjectID"); // Check if the object has already been visited and created //if((umpleObjectIDMap.get(umpleObjectId)==null)||visitedSuperClass){ try{ visitedSuperClass=false; // map the old objectID (in jsonString) with the newly created object's hashCode in umpleObjectIDMap umpleObjectIDMap.put(umpleObjectId,this); String jsonKey=""; jsonKey="name"; //more types should be considered here this.name=parsedResult.get(jsonKey); jsonKey="tuition"; //more types should be considered here float valueFloat=Float.parseFloat(parsedResult.get(jsonKey)); this.tuition=valueFloat; // below for-loop check the association class of the top level class jsonKey="courses"; String newJsonString_0=parsedResult.get(jsonKey); String newIDRegex_0="\\\"umpleObjectID\\\"\\:\\\"[0-9]*\\\""; String newUmpleID_0=fromJsonParserHelper(newJsonString_0,newIDRegex_0); //Multiple associations List<String> multiAssoObjList_0 = new ArrayList<String>(); multiAssoObjList_0=fromJsonParserList(newJsonString_0); courses=new ArrayList<Course>(); for(String obj: multiAssoObjList_0){ newUmpleID_0=fromJsonParserHelper(obj,newIDRegex_0); String newClassName_0=fromJsonParserClassName(obj); if(!umpleObjectIDMap.containsKey(newUmpleID_0)){ boolean subClassFound=false; Class clazz_0=Class.forName(newClassName_0); Constructor constructor_0=clazz_0.getConstructor(String.class, Map.class); Object objectNew_0=constructor_0.newInstance(obj,umpleObjectIDMap); courses.add((Course)objectNew_0); } else{ courses.add((Course)umpleObjectIDMap.get(newUmpleID_0)); } } jsonKey="students"; String newJsonString_1=parsedResult.get(jsonKey); String newIDRegex_1="\\\"umpleObjectID\\\"\\:\\\"[0-9]*\\\""; String newUmpleID_1=fromJsonParserHelper(newJsonString_1,newIDRegex_1); //Multiple associations List<String> multiAssoObjList_1 = new ArrayList<String>(); multiAssoObjList_1=fromJsonParserList(newJsonString_1); students=new ArrayList<Student>(); for(String obj: multiAssoObjList_1){ newUmpleID_1=fromJsonParserHelper(obj,newIDRegex_1); String newClassName_1=fromJsonParserClassName(obj); if(!umpleObjectIDMap.containsKey(newUmpleID_1)){ boolean subClassFound=false; Class clazz_1=Class.forName(newClassName_1); Constructor constructor_1=clazz_1.getConstructor(String.class, Map.class); Object objectNew_1=constructor_1.newInstance(obj,umpleObjectIDMap); students.add((Student)objectNew_1); } else{ students.add((Student)umpleObjectIDMap.get(newUmpleID_1)); } } }catch(Exception e){ } //} } } /* * A json parser to parse the input jsonString, if -s genJson is specified * * @param String aJsonString is the string in json format that is to be processed and turned into an object * * @ return HashMap<String,String> that stores paresed result, key is the attribute(or associations) of an object, value is the attribute value or association string */ public static HashMap<String,String> fromJsonParser(String jsonString){ HashMap<String,String> parsedResultMap = new HashMap<String,String>(); try{ //Below (String, Pattern, Matcher) are the regex strings and their patterns and matcher used to process a jsonString // topLevelString is the regex representing the topLevel class name String topLevelString = "\\{\\\"[A-Z]\\w*\\\":"; Pattern topLevelPattern = Pattern.compile(topLevelString); Matcher topLevelMatcher = topLevelPattern.matcher(jsonString); String quotes="\\\""; String colon="\\:"; String colonSquareBracket="\\:\\["; if(topLevelMatcher.find()){ //actual string that represent the topLevel className String topLevelStringFound=topLevelMatcher.group(0); String className=topLevelStringFound.split(quotes)[1]; parsedResultMap.put("className", className); jsonString=jsonString.split(topLevelString,2)[1]; //objIDString is the regex representing umpleObjectID that could be found in jsonString String objIDString = "\"umpleObjectID\"\\:\"[0-9]*\","; Pattern objIDPattern = Pattern.compile(objIDString); Matcher objIDMatcher = objIDPattern.matcher(jsonString); if(objIDMatcher.find()){ String objIDFound=objIDMatcher.group(0); parsedResultMap.put("umpleObjectID", objIDFound.split(colon)[1].split(quotes)[1]); jsonString=jsonString.replaceFirst(objIDFound,""); } String timeString="\\\"\\w*\\\"\\:\\\"\\d{2}:\\d{2}\\:\\d{2}\\\""; Pattern timeStringPattern=Pattern.compile(timeString); Matcher timeStringPatternMatcher=timeStringPattern.matcher(jsonString); if(timeStringPatternMatcher.find()){ String timeStringFound=timeStringPatternMatcher.group(0); parsedResultMap.put(timeStringFound.split(colon,2)[0].split(quotes)[1], timeStringFound.split(colon,2)[1].split(quotes)[1]); } // pairString is the regex for an object's attribute and attribute value, the string parsed will be in key-value formate String pairString = "(\\\"(?!umpleObjectID)[^\\\"]+)\\\":\\\"((?:\\\\\\\"|[^\\\"])*)"; Pattern pairPattern=Pattern.compile(pairString); Matcher pairMatcher=pairPattern.matcher(jsonString); String associationString="(?=\\\"\\w*\\\"\\:\\[\\{)(?:(?=.*?\\[\\{(?!.*?\\1)(.*\\}\\](?!.*\\2).*))(?=.*?\\}\\](?!.*?\\2)(.*)).)+?.*?(?=\\1)[^\\[]*(?=\\2$)"; Pattern associationPattern=Pattern.compile(associationString); String newObjJsonString="(?=\\,\\\"\\w*\\\"\\:\\{)(?:(?=.*?\\{\\\"(?!.*?\\1)(.*\\}(?!.*\\2).*))(?=.*?\\}(?!.*?\\2)(.*)).)+?.*?(?=\\1)[^\\{]*(?=\\2$)"; Pattern newObjJsonPattern=Pattern.compile(newObjJsonString); String quoteColonQuote="\\\"\\:\\\""; //Keep on parsing the attribute's key-value pair, //until a List (multi-associations) pattern or a newObject parttern (single association) is found while(pairMatcher.find()){ String pairStringFound=pairMatcher.group(0); if(parsedResultMap.get(pairStringFound.split(colon)[0].split(quotes)[1])==null){ String keyPair=pairStringFound.split(colon)[0].split(quotes)[1]; String valuePair=pairStringFound.split(quoteColonQuote,2)[1]; keyPair=keyPair.replace("\\\\","\\").replace("\\\"","\""); valuePair=valuePair.replace("\\\\","\\").replace("\\\"","\""); parsedResultMap.put(keyPair,valuePair); jsonString=jsonString.replaceFirst(pairString, ""); } int lastIndex = 0; while (lastIndex<jsonString.length()){ String remainingJson=jsonString.substring(lastIndex); Matcher associationMatcher=associationPattern.matcher(jsonString); Matcher newObjJsonMatcher=newObjJsonPattern.matcher(jsonString); boolean assoFound=associationMatcher.find(); boolean newObjFound=newObjJsonMatcher.find(); if (assoFound&&(!newObjFound||associationMatcher.start()<newObjJsonMatcher.start())){ String assoStringFound=associationMatcher.group(0); String associationName=assoStringFound.split(colon,2)[0].split(quotes)[1];; String associationItems=assoStringFound.split(colonSquareBracket,2)[1]; parsedResultMap.put(associationName, associationItems); jsonString=jsonString.replaceFirst(associationString, ""); } else if (newObjFound){ String newObjJsonFound=newObjJsonMatcher.group(0); String newObjName=newObjJsonFound.split(colon,2)[0].split(quotes)[1]; String newObjItems=newObjJsonFound.split(colon,2)[1]; parsedResultMap.put(newObjName, newObjItems); jsonString=jsonString.replaceFirst(newObjJsonString, ""); }else{ break; } } } } return parsedResultMap; }catch(NullPointerException e){ return parsedResultMap; } } public static String fromJsonParserHelper(String jsonString, String regexString){ String umpleID = ""; String quo="\\\""; try{ Pattern umpleIDPattern=Pattern.compile(regexString); Matcher umpleIDMatcher=umpleIDPattern.matcher(jsonString); if(umpleIDMatcher.find()){ String umpleIDStringFound=umpleIDMatcher.group(0); String idString="\\\"\\d*\\\""; Pattern idPattern=Pattern.compile(idString); Matcher idMatcher=idPattern.matcher(umpleIDStringFound); if(idMatcher.find()){ umpleID=idMatcher.group(0).split(quo)[1]; } } return umpleID; } catch(NullPointerException e){ return umpleID; } } public static List<String> fromJsonParserList(String objListString){ List<String> objList=new ArrayList<String>(); try{ String objString="(?:(?=.*?\\{(?!.*?\\1)(.*\\}(?!.*\\2).*))(?=.*?\\}(?!.*?\\2)(.*)).)+?.*?(?=\\1)[^\\{]*(?=\\2$)"; Pattern objStringPattern=Pattern.compile(objString); Matcher objStringMatcher=objStringPattern.matcher(objListString); while(objStringMatcher.find()){ objList.add(objStringMatcher.group(0)); } return objList; }catch(NullPointerException e){ return objList; } } public static String fromJsonParserClassName(String objNameString){ String nextName=""; String quotes="\\\""; try{ String nextNameString="\\{\\\"[A-Z]\\w*\\\":"; Pattern nextNamePattern=Pattern.compile(nextNameString); Matcher nextNameMatcher=nextNamePattern.matcher(objNameString); if(nextNameMatcher.find()){ nextName=nextNameMatcher.group(0).split(quotes)[1]; } return nextName; }catch(NullPointerException e){ return nextName; } } } /*PLEASE DO NOT EDIT THIS CODE*/ /*This code was generated using the UMPLE 1.35.0.7523.c616a4dce modeling language!*/ package example; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.sql.*; import java.lang.reflect.Constructor; // line 26 "../ToJsonComplexTest.ump" public class Employee extends Person { //------------------------ // MEMBER VARIABLES //------------------------ //Employee Attributes private double salary; private String job; //Employee Associations private List<CourseSection> teaches; //------------------------ // CONSTRUCTOR //------------------------ public Employee(int aId, String aName, double aSalary) { super(aId, aName); salary = aSalary; job = null; teaches = new ArrayList<CourseSection>(); } //------------------------ // INTERFACE //------------------------ public boolean setSalary(double aSalary) { boolean wasSet = false; salary = aSalary; wasSet = true; return wasSet; } public boolean setJob(String aJob) { boolean wasSet = false; job = aJob; wasSet = true; return wasSet; } public double getSalary() { return salary; } public String getJob() { return job; } /* Code from template association_GetMany */ public CourseSection getTeache(int index) { CourseSection aTeache = teaches.get(index); return aTeache; } public List<CourseSection> getTeaches() { List<CourseSection> newTeaches = Collections.unmodifiableList(teaches); return newTeaches; } public int numberOfTeaches() { int number = teaches.size(); return number; } public boolean hasTeaches() { boolean has = teaches.size() > 0; return has; } public int indexOfTeache(CourseSection aTeache) { int index = teaches.indexOf(aTeache); return index; } /* Code from template association_MinimumNumberOfMethod */ public static int minimumNumberOfTeaches() { return 0; } /* Code from template association_AddManyToManyMethod */ public boolean addTeache(CourseSection aTeache) { boolean wasAdded = false; if (teaches.contains(aTeache)) { return false; } teaches.add(aTeache); if (aTeache.indexOfEmployee(this) != -1) { wasAdded = true; } else { wasAdded = aTeache.addEmployee(this); if (!wasAdded) { teaches.remove(aTeache); } } return wasAdded; } /* Code from template association_RemoveMany */ public boolean removeTeache(CourseSection aTeache) { boolean wasRemoved = false; if (!teaches.contains(aTeache)) { return wasRemoved; } int oldIndex = teaches.indexOf(aTeache); teaches.remove(oldIndex); if (aTeache.indexOfEmployee(this) == -1) { wasRemoved = true; } else { wasRemoved = aTeache.removeEmployee(this); if (!wasRemoved) { teaches.add(oldIndex,aTeache); } } return wasRemoved; } /* Code from template association_AddIndexControlFunctions */ public boolean addTeacheAt(CourseSection aTeache, int index) { boolean wasAdded = false; if(addTeache(aTeache)) { if(index < 0 ) { index = 0; } if(index > numberOfTeaches()) { index = numberOfTeaches() - 1; } teaches.remove(aTeache); teaches.add(index, aTeache); wasAdded = true; } return wasAdded; } public boolean addOrMoveTeacheAt(CourseSection aTeache, int index) { boolean wasAdded = false; if(teaches.contains(aTeache)) { if(index < 0 ) { index = 0; } if(index > numberOfTeaches()) { index = numberOfTeaches() - 1; } teaches.remove(aTeache); teaches.add(index, aTeache); wasAdded = true; } else { wasAdded = addTeacheAt(aTeache, index); } return wasAdded; } public void delete() { ArrayList<CourseSection> copyOfTeaches = new ArrayList<CourseSection>(teaches); teaches.clear(); for(CourseSection aTeache : copyOfTeaches) { aTeache.removeEmployee(this); } super.delete(); } public String toString() { return super.toString() + "["+ "salary" + ":" + getSalary()+ "," + "job" + ":" + getJob()+ "]"; } /* * Generate Json for this object and connected objects visited objects to enable avoidance of infinite loops * * @return a string in Json format of this object */ public String toJson() { HashSet<Object> visitedList = new HashSet<Object>(); StringBuilder toJsonOutput = new StringBuilder(); toJsonOutput.append("{\n"); this.toJsonHelper(toJsonOutput, visitedList,1,true); toJsonOutput.append("\n}"); return(toJsonOutput.toString()); } /* * Helper function to generate Json for this object and connected objects visited objects to enable avoidance of infinite loops * * @param toJsonOutput Output is aded to this as the network of objects is traversed * @param visitedList Every concrete object visited is added so we don't re-outpu * @param nestLevel As we output deeper objects, indent them more * @param atConcreteClass false when we are recursing to a superclass * so we get the superclass data * @return whether or not anything was output (so we can tell whether we need to output a comma) */ public boolean toJsonHelper(StringBuilder toJsonOutput, HashSet<Object> visitedList, int nestLevel, boolean atConcreteClass){ String indent = " ".repeat(nestLevel); boolean alreadyVisited = false; boolean haveOutputItem = false; if(atConcreteClass) { // This will not be true in a super call; output header toJsonOutput.append(indent+"\""+this.toString().split("@")[0]+ "\" : {\n"+indent+ " \"umpleObjectID\" : \""+System.identityHashCode(this)+"\""); // Check if we have already visited this object. If so we will not output details alreadyVisited = visitedList.contains(this); if(!alreadyVisited) { toJsonOutput.append(",\n"); visitedList.add(this); } } // There is no superclass of this class if(alreadyVisited) { toJsonOutput.append("\n"); } else { // Check if this class has a superclass. If it does, we make a call to output superclass content // This will keep calling super so the topmost attributes and associations appear first haveOutputItem = super.toJsonHelper(toJsonOutput, visitedList, nestLevel, false); // When an object has not already been visited, output its details if(haveOutputItem){ //toJsonOutput.append(",\n"); } if(haveOutputItem){ toJsonOutput.append(",\n"); } toJsonOutput.append(indent); toJsonOutput.append(" \""); toJsonOutput.append("salary"); toJsonOutput.append("\" : \""); String primValue_0=""+getSalary()+""; toJsonOutput.append(primValue_0.replace("\\","\\\\").replace("\"","\\\"")); toJsonOutput.append("\""); haveOutputItem=true; if(haveOutputItem){ toJsonOutput.append(",\n"); } toJsonOutput.append(indent); toJsonOutput.append(" \""); toJsonOutput.append("job"); toJsonOutput.append("\" : \""); String primValue_1=""+getJob()+""; toJsonOutput.append(primValue_1.replace("\\","\\\\").replace("\"","\\\"")); toJsonOutput.append("\""); haveOutputItem=true; //haveOutputItem = false; //haveOutputItem = false; if(haveOutputItem) { toJsonOutput.append(",\n"); } toJsonOutput.append(indent); toJsonOutput.append(" \""); toJsonOutput.append("teaches"); toJsonOutput.append("\""); toJsonOutput.append(" : ["); toJsonOutput.append("\n"); haveOutputItem = false; try{ for (CourseSection anItem_0 :getTeaches()){ if(haveOutputItem) { toJsonOutput.append(",\n"); } toJsonOutput.append(indent+" {"); toJsonOutput.append("\n"); anItem_0.toJsonHelper(toJsonOutput, visitedList,nestLevel+2,true); toJsonOutput.append("\n"); toJsonOutput.append(indent+" }"); haveOutputItem=true; } }catch (NullPointerException e){ } toJsonOutput.append("\n"); toJsonOutput.append(indent+" ]"); haveOutputItem=true; toJsonOutput.append(indent+" \n"); } // Finalize the output of the concrete class if(atConcreteClass) { if(!alreadyVisited) { toJsonOutput.append("\n"); } toJsonOutput.append(indent+"}"); } haveOutputItem = true; return haveOutputItem; } /* * Deserialize Json string to instantiate Objects from top-level class * * @param umpleObjectIDMap<String, Object> mapping parsed objectID (from Json string) with newly instantiated object's objectID * * @param String aJsonString is the string in json format that is to be processed and turned into an object * * @return newly instantiated Object */ public static Employee fromJson(String aJsonString){ // process the input jsonString so that it can further processed using regex aJsonString=aJsonString.replace("\n","").replace(" ",""); // a map to store the umpleObjectID present in jsonString Map<String, Object> umpleObjectIDMap=new HashMap<>(); // instantiate a new object Employee anObject = new Employee(aJsonString, umpleObjectIDMap); return anObject; } /* * A new constructor specifically implemented if -s genJson is specified * * @param String aJsonString is the string in json format that is to be processed and turned into an object * * @param umpleObjectIDMap<String, Integer> mapping parsed objectID (from Json string) with newly instantiated object's objectID */ @SuppressWarnings("unchecked") public Employee(String aJsonString, Map<String, Object> umpleObjectIDMap){ // Initialize a HashMap to store the parsed result // key is the attribute name present in the jsonString // value is the attribute value present in the jsonString super(aJsonString,umpleObjectIDMap); boolean visitedSuperClass=true; HashMap<String,String> parsedResult = new HashMap<String,String>(); parsedResult = fromJsonParser(aJsonString); if(!parsedResult.isEmpty()){ boolean classExist; boolean classChildExist; String parsedClassName=parsedResult.get("className"); String childName=this.getClass().getSimpleName(); classExist="Employee".equals(parsedClassName); classChildExist=childName.equals(parsedClassName); // if top-level class does not exist, throw exception if(!classExist&&!classChildExist){ throw new IllegalArgumentException("Top-level class \""+parsedClassName+"\" does not exist, please check the input json string"); } String umpleObjectId=parsedResult.get("umpleObjectID"); // Check if the object has already been visited and created //if((umpleObjectIDMap.get(umpleObjectId)==null)||visitedSuperClass){ try{ visitedSuperClass=false; // map the old objectID (in jsonString) with the newly created object's hashCode in umpleObjectIDMap umpleObjectIDMap.put(umpleObjectId,this); String jsonKey=""; jsonKey="salary"; //more types should be considered here double valueDouble =Double.valueOf(parsedResult.get(jsonKey)); this.salary=valueDouble; jsonKey="job"; //more types should be considered here this.job=parsedResult.get(jsonKey); // below for-loop check the association class of the top level class jsonKey="teaches"; String newJsonString_0=parsedResult.get(jsonKey); String newIDRegex_0="\\\"umpleObjectID\\\"\\:\\\"[0-9]*\\\""; String newUmpleID_0=fromJsonParserHelper(newJsonString_0,newIDRegex_0); //Multiple associations List<String> multiAssoObjList_0 = new ArrayList<String>(); multiAssoObjList_0=fromJsonParserList(newJsonString_0); teaches=new ArrayList<CourseSection>(); for(String obj: multiAssoObjList_0){ newUmpleID_0=fromJsonParserHelper(obj,newIDRegex_0); String newClassName_0=fromJsonParserClassName(obj); if(!umpleObjectIDMap.containsKey(newUmpleID_0)){ boolean subClassFound=false; Class clazz_0=Class.forName(newClassName_0); Constructor constructor_0=clazz_0.getConstructor(String.class, Map.class); Object objectNew_0=constructor_0.newInstance(obj,umpleObjectIDMap); teaches.add((CourseSection)objectNew_0); } else{ teaches.add((CourseSection)umpleObjectIDMap.get(newUmpleID_0)); } } }catch(Exception e){ } //} } } /* * A json parser to parse the input jsonString, if -s genJson is specified * * @param String aJsonString is the string in json format that is to be processed and turned into an object * * @ return HashMap<String,String> that stores paresed result, key is the attribute(or associations) of an object, value is the attribute value or association string */ public static HashMap<String,String> fromJsonParser(String jsonString){ HashMap<String,String> parsedResultMap = new HashMap<String,String>(); try{ //Below (String, Pattern, Matcher) are the regex strings and their patterns and matcher used to process a jsonString // topLevelString is the regex representing the topLevel class name String topLevelString = "\\{\\\"[A-Z]\\w*\\\":"; Pattern topLevelPattern = Pattern.compile(topLevelString); Matcher topLevelMatcher = topLevelPattern.matcher(jsonString); String quotes="\\\""; String colon="\\:"; String colonSquareBracket="\\:\\["; if(topLevelMatcher.find()){ //actual string that represent the topLevel className String topLevelStringFound=topLevelMatcher.group(0); String className=topLevelStringFound.split(quotes)[1]; parsedResultMap.put("className", className); jsonString=jsonString.split(topLevelString,2)[1]; //objIDString is the regex representing umpleObjectID that could be found in jsonString String objIDString = "\"umpleObjectID\"\\:\"[0-9]*\","; Pattern objIDPattern = Pattern.compile(objIDString); Matcher objIDMatcher = objIDPattern.matcher(jsonString); if(objIDMatcher.find()){ String objIDFound=objIDMatcher.group(0); parsedResultMap.put("umpleObjectID", objIDFound.split(colon)[1].split(quotes)[1]); jsonString=jsonString.replaceFirst(objIDFound,""); } String timeString="\\\"\\w*\\\"\\:\\\"\\d{2}:\\d{2}\\:\\d{2}\\\""; Pattern timeStringPattern=Pattern.compile(timeString); Matcher timeStringPatternMatcher=timeStringPattern.matcher(jsonString); if(timeStringPatternMatcher.find()){ String timeStringFound=timeStringPatternMatcher.group(0); parsedResultMap.put(timeStringFound.split(colon,2)[0].split(quotes)[1], timeStringFound.split(colon,2)[1].split(quotes)[1]); } // pairString is the regex for an object's attribute and attribute value, the string parsed will be in key-value formate String pairString = "(\\\"(?!umpleObjectID)[^\\\"]+)\\\":\\\"((?:\\\\\\\"|[^\\\"])*)"; Pattern pairPattern=Pattern.compile(pairString); Matcher pairMatcher=pairPattern.matcher(jsonString); String associationString="(?=\\\"\\w*\\\"\\:\\[\\{)(?:(?=.*?\\[\\{(?!.*?\\1)(.*\\}\\](?!.*\\2).*))(?=.*?\\}\\](?!.*?\\2)(.*)).)+?.*?(?=\\1)[^\\[]*(?=\\2$)"; Pattern associationPattern=Pattern.compile(associationString); String newObjJsonString="(?=\\,\\\"\\w*\\\"\\:\\{)(?:(?=.*?\\{\\\"(?!.*?\\1)(.*\\}(?!.*\\2).*))(?=.*?\\}(?!.*?\\2)(.*)).)+?.*?(?=\\1)[^\\{]*(?=\\2$)"; Pattern newObjJsonPattern=Pattern.compile(newObjJsonString); String quoteColonQuote="\\\"\\:\\\""; //Keep on parsing the attribute's key-value pair, //until a List (multi-associations) pattern or a newObject parttern (single association) is found while(pairMatcher.find()){ String pairStringFound=pairMatcher.group(0); if(parsedResultMap.get(pairStringFound.split(colon)[0].split(quotes)[1])==null){ String keyPair=pairStringFound.split(colon)[0].split(quotes)[1]; String valuePair=pairStringFound.split(quoteColonQuote,2)[1]; keyPair=keyPair.replace("\\\\","\\").replace("\\\"","\""); valuePair=valuePair.replace("\\\\","\\").replace("\\\"","\""); parsedResultMap.put(keyPair,valuePair); jsonString=jsonString.replaceFirst(pairString, ""); } int lastIndex = 0; while (lastIndex<jsonString.length()){ String remainingJson=jsonString.substring(lastIndex); Matcher associationMatcher=associationPattern.matcher(jsonString); Matcher newObjJsonMatcher=newObjJsonPattern.matcher(jsonString); boolean assoFound=associationMatcher.find(); boolean newObjFound=newObjJsonMatcher.find(); if (assoFound&&(!newObjFound||associationMatcher.start()<newObjJsonMatcher.start())){ String assoStringFound=associationMatcher.group(0); String associationName=assoStringFound.split(colon,2)[0].split(quotes)[1];; String associationItems=assoStringFound.split(colonSquareBracket,2)[1]; parsedResultMap.put(associationName, associationItems); jsonString=jsonString.replaceFirst(associationString, ""); } else if (newObjFound){ String newObjJsonFound=newObjJsonMatcher.group(0); String newObjName=newObjJsonFound.split(colon,2)[0].split(quotes)[1]; String newObjItems=newObjJsonFound.split(colon,2)[1]; parsedResultMap.put(newObjName, newObjItems); jsonString=jsonString.replaceFirst(newObjJsonString, ""); }else{ break; } } } } return parsedResultMap; }catch(NullPointerException e){ return parsedResultMap; } } public static String fromJsonParserHelper(String jsonString, String regexString){ String umpleID = ""; String quo="\\\""; try{ Pattern umpleIDPattern=Pattern.compile(regexString); Matcher umpleIDMatcher=umpleIDPattern.matcher(jsonString); if(umpleIDMatcher.find()){ String umpleIDStringFound=umpleIDMatcher.group(0); String idString="\\\"\\d*\\\""; Pattern idPattern=Pattern.compile(idString); Matcher idMatcher=idPattern.matcher(umpleIDStringFound); if(idMatcher.find()){ umpleID=idMatcher.group(0).split(quo)[1]; } } return umpleID; } catch(NullPointerException e){ return umpleID; } } public static List<String> fromJsonParserList(String objListString){ List<String> objList=new ArrayList<String>(); try{ String objString="(?:(?=.*?\\{(?!.*?\\1)(.*\\}(?!.*\\2).*))(?=.*?\\}(?!.*?\\2)(.*)).)+?.*?(?=\\1)[^\\{]*(?=\\2$)"; Pattern objStringPattern=Pattern.compile(objString); Matcher objStringMatcher=objStringPattern.matcher(objListString); while(objStringMatcher.find()){ objList.add(objStringMatcher.group(0)); } return objList; }catch(NullPointerException e){ return objList; } } public static String fromJsonParserClassName(String objNameString){ String nextName=""; String quotes="\\\""; try{ String nextNameString="\\{\\\"[A-Z]\\w*\\\":"; Pattern nextNamePattern=Pattern.compile(nextNameString); Matcher nextNameMatcher=nextNamePattern.matcher(objNameString); if(nextNameMatcher.find()){ nextName=nextNameMatcher.group(0).split(quotes)[1]; } return nextName; }catch(NullPointerException e){ return nextName; } } } /*PLEASE DO NOT EDIT THIS CODE*/ /*This code was generated using the UMPLE 1.35.0.7523.c616a4dce modeling language!*/ package example; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.sql.*; import java.lang.reflect.Constructor; // line 37 "../ToJsonComplexTest.ump" public class Course { //------------------------ // MEMBER VARIABLES //------------------------ //Course Attributes private String title; //Course Associations private University university; private List<CourseSection> courseSections; //------------------------ // CONSTRUCTOR //------------------------ public Course(String aTitle, University aUniversity) { title = aTitle; boolean didAddUniversity = setUniversity(aUniversity); if (!didAddUniversity) { throw new RuntimeException("Unable to create course due to university. See https://manual.umple.org?RE002ViolationofAssociationMultiplicity.html"); } courseSections = new ArrayList<CourseSection>(); } //------------------------ // INTERFACE //------------------------ public boolean setTitle(String aTitle) { boolean wasSet = false; title = aTitle; wasSet = true; return wasSet; } public String getTitle() { return title; } /* Code from template association_GetOne */ public University getUniversity() { return university; } /* Code from template association_GetMany */ public CourseSection getCourseSection(int index) { CourseSection aCourseSection = courseSections.get(index); return aCourseSection; } public List<CourseSection> getCourseSections() { List<CourseSection> newCourseSections = Collections.unmodifiableList(courseSections); return newCourseSections; } public int numberOfCourseSections() { int number = courseSections.size(); return number; } public boolean hasCourseSections() { boolean has = courseSections.size() > 0; return has; } public int indexOfCourseSection(CourseSection aCourseSection) { int index = courseSections.indexOf(aCourseSection); return index; } /* Code from template association_SetOneToMany */ public boolean setUniversity(University aUniversity) { boolean wasSet = false; if (aUniversity == null) { return wasSet; } University existingUniversity = university; university = aUniversity; if (existingUniversity != null && !existingUniversity.equals(aUniversity)) { existingUniversity.removeCourse(this); } university.addCourse(this); wasSet = true; return wasSet; } /* Code from template association_MinimumNumberOfMethod */ public static int minimumNumberOfCourseSections() { return 0; } /* Code from template association_AddManyToOne */ public CourseSection addCourseSection(String aCode) { return new CourseSection(aCode, this); } public boolean addCourseSection(CourseSection aCourseSection) { boolean wasAdded = false; if (courseSections.contains(aCourseSection)) { return false; } Course existingCourse = aCourseSection.getCourse(); boolean isNewCourse = existingCourse != null && !this.equals(existingCourse); if (isNewCourse) { aCourseSection.setCourse(this); } else { courseSections.add(aCourseSection); } wasAdded = true; return wasAdded; } public boolean removeCourseSection(CourseSection aCourseSection) { boolean wasRemoved = false; //Unable to remove aCourseSection, as it must always have a course if (!this.equals(aCourseSection.getCourse())) { courseSections.remove(aCourseSection); wasRemoved = true; } return wasRemoved; } /* Code from template association_AddIndexControlFunctions */ public boolean addCourseSectionAt(CourseSection aCourseSection, int index) { boolean wasAdded = false; if(addCourseSection(aCourseSection)) { if(index < 0 ) { index = 0; } if(index > numberOfCourseSections()) { index = numberOfCourseSections() - 1; } courseSections.remove(aCourseSection); courseSections.add(index, aCourseSection); wasAdded = true; } return wasAdded; } public boolean addOrMoveCourseSectionAt(CourseSection aCourseSection, int index) { boolean wasAdded = false; if(courseSections.contains(aCourseSection)) { if(index < 0 ) { index = 0; } if(index > numberOfCourseSections()) { index = numberOfCourseSections() - 1; } courseSections.remove(aCourseSection); courseSections.add(index, aCourseSection); wasAdded = true; } else { wasAdded = addCourseSectionAt(aCourseSection, index); } return wasAdded; } public void delete() { University placeholderUniversity = university; this.university = null; if(placeholderUniversity != null) { placeholderUniversity.removeCourse(this); } for(int i=courseSections.size(); i > 0; i--) { CourseSection aCourseSection = courseSections.get(i - 1); aCourseSection.delete(); } } public String toString() { return super.toString() + "["+ "title" + ":" + getTitle()+ "]" + System.getProperties().getProperty("line.separator") + " " + "university = "+(getUniversity()!=null?Integer.toHexString(System.identityHashCode(getUniversity())):"null"); } /* * Generate Json for this object and connected objects visited objects to enable avoidance of infinite loops * * @return a string in Json format of this object */ public String toJson() { HashSet<Object> visitedList = new HashSet<Object>(); StringBuilder toJsonOutput = new StringBuilder(); toJsonOutput.append("{\n"); this.toJsonHelper(toJsonOutput, visitedList,1,true); toJsonOutput.append("\n}"); return(toJsonOutput.toString()); } /* * Helper function to generate Json for this object and connected objects visited objects to enable avoidance of infinite loops * * @param toJsonOutput Output is aded to this as the network of objects is traversed * @param visitedList Every concrete object visited is added so we don't re-outpu * @param nestLevel As we output deeper objects, indent them more * @param atConcreteClass false when we are recursing to a superclass * so we get the superclass data * @return whether or not anything was output (so we can tell whether we need to output a comma) */ public boolean toJsonHelper(StringBuilder toJsonOutput, HashSet<Object> visitedList, int nestLevel, boolean atConcreteClass){ String indent = " ".repeat(nestLevel); boolean alreadyVisited = false; boolean haveOutputItem = false; if(atConcreteClass) { // This will not be true in a super call; output header toJsonOutput.append(indent+"\""+this.toString().split("@")[0]+ "\" : {\n"+indent+ " \"umpleObjectID\" : \""+System.identityHashCode(this)+"\""); // Check if we have already visited this object. If so we will not output details alreadyVisited = visitedList.contains(this); if(!alreadyVisited) { toJsonOutput.append(",\n"); visitedList.add(this); } } // There is no superclass of this class if(alreadyVisited) { toJsonOutput.append("\n"); } else { // Check if this class has a superclass. If it does, we make a call to output superclass content // This will keep calling super so the topmost attributes and associations appear first // When an object has not already been visited, output its details if(haveOutputItem){ //toJsonOutput.append(",\n"); } if(haveOutputItem){ toJsonOutput.append(",\n"); } toJsonOutput.append(indent); toJsonOutput.append(" \""); toJsonOutput.append("title"); toJsonOutput.append("\" : \""); String primValue_0=""+getTitle()+""; toJsonOutput.append(primValue_0.replace("\\","\\\\").replace("\"","\\\"")); toJsonOutput.append("\""); haveOutputItem=true; //haveOutputItem = false; //haveOutputItem = false; if(haveOutputItem) { toJsonOutput.append(",\n"); } toJsonOutput.append(indent); toJsonOutput.append("\n"+indent); toJsonOutput.append(" \""); toJsonOutput.append("university"); toJsonOutput.append("\""); toJsonOutput.append(" : "); toJsonOutput.append("\n"); toJsonOutput.append(indent+" {"); toJsonOutput.append("\n");University anotherItem_0 = getUniversity(); anotherItem_0.toJsonHelper(toJsonOutput, visitedList, nestLevel+2, true); toJsonOutput.append("\n"); toJsonOutput.append(indent+" }"); haveOutputItem=true; if(haveOutputItem) { toJsonOutput.append(",\n"); } toJsonOutput.append(indent); toJsonOutput.append(" \""); toJsonOutput.append("courseSections"); toJsonOutput.append("\""); toJsonOutput.append(" : ["); toJsonOutput.append("\n"); haveOutputItem = false; try{ for (CourseSection anItem_1 :getCourseSections()){ if(haveOutputItem) { toJsonOutput.append(",\n"); } toJsonOutput.append(indent+" {"); toJsonOutput.append("\n"); anItem_1.toJsonHelper(toJsonOutput, visitedList,nestLevel+2,true); toJsonOutput.append("\n"); toJsonOutput.append(indent+" }"); haveOutputItem=true; } }catch (NullPointerException e){ } toJsonOutput.append("\n"); toJsonOutput.append(indent+" ]"); haveOutputItem=true; toJsonOutput.append(indent+" \n"); } // Finalize the output of the concrete class if(atConcreteClass) { if(!alreadyVisited) { toJsonOutput.append("\n"); } toJsonOutput.append(indent+"}"); } haveOutputItem = true; return haveOutputItem; } /* * Deserialize Json string to instantiate Objects from top-level class * * @param umpleObjectIDMap<String, Object> mapping parsed objectID (from Json string) with newly instantiated object's objectID * * @param String aJsonString is the string in json format that is to be processed and turned into an object * * @return newly instantiated Object */ public static Course fromJson(String aJsonString){ // process the input jsonString so that it can further processed using regex aJsonString=aJsonString.replace("\n","").replace(" ",""); // a map to store the umpleObjectID present in jsonString Map<String, Object> umpleObjectIDMap=new HashMap<>(); // instantiate a new object Course anObject = new Course(aJsonString, umpleObjectIDMap); return anObject; } /* * A new constructor specifically implemented if -s genJson is specified * * @param String aJsonString is the string in json format that is to be processed and turned into an object * * @param umpleObjectIDMap<String, Integer> mapping parsed objectID (from Json string) with newly instantiated object's objectID */ @SuppressWarnings("unchecked") public Course(String aJsonString, Map<String, Object> umpleObjectIDMap){ // Initialize a HashMap to store the parsed result // key is the attribute name present in the jsonString // value is the attribute value present in the jsonString boolean visitedSuperClass=false; HashMap<String,String> parsedResult = new HashMap<String,String>(); parsedResult = fromJsonParser(aJsonString); if(!parsedResult.isEmpty()){ boolean classExist; boolean classChildExist; String parsedClassName=parsedResult.get("className"); String childName=this.getClass().getSimpleName(); classExist="Course".equals(parsedClassName); classChildExist=childName.equals(parsedClassName); // if top-level class does not exist, throw exception if(!classExist&&!classChildExist){ throw new IllegalArgumentException("Top-level class \""+parsedClassName+"\" does not exist, please check the input json string"); } String umpleObjectId=parsedResult.get("umpleObjectID"); // Check if the object has already been visited and created //if((umpleObjectIDMap.get(umpleObjectId)==null)||visitedSuperClass){ try{ visitedSuperClass=false; // map the old objectID (in jsonString) with the newly created object's hashCode in umpleObjectIDMap umpleObjectIDMap.put(umpleObjectId,this); String jsonKey=""; jsonKey="title"; //more types should be considered here this.title=parsedResult.get(jsonKey); // below for-loop check the association class of the top level class jsonKey="university"; String newJsonString_0=parsedResult.get(jsonKey); String newIDRegex_0="\\\"umpleObjectID\\\"\\:\\\"[0-9]*\\\""; String newUmpleID_0=fromJsonParserHelper(newJsonString_0,newIDRegex_0); //Multiple associations if(!umpleObjectIDMap.containsKey(newUmpleID_0)){ String newClassNameOne_0=fromJsonParserClassName(newJsonString_0); Class clazzOne_0=Class.forName(newClassNameOne_0); Constructor constructorOne_0=clazzOne_0.getConstructor(String.class, Map.class); Object objectNewOne_0=constructorOne_0.newInstance(newJsonString_0,umpleObjectIDMap); University oneAssoObj_0=(University)objectNewOne_0; university=oneAssoObj_0; } else{ university=(University)umpleObjectIDMap.get(newUmpleID_0); } jsonKey="courseSections"; String newJsonString_1=parsedResult.get(jsonKey); String newIDRegex_1="\\\"umpleObjectID\\\"\\:\\\"[0-9]*\\\""; String newUmpleID_1=fromJsonParserHelper(newJsonString_1,newIDRegex_1); //Multiple associations List<String> multiAssoObjList_1 = new ArrayList<String>(); multiAssoObjList_1=fromJsonParserList(newJsonString_1); courseSections=new ArrayList<CourseSection>(); for(String obj: multiAssoObjList_1){ newUmpleID_1=fromJsonParserHelper(obj,newIDRegex_1); String newClassName_1=fromJsonParserClassName(obj); if(!umpleObjectIDMap.containsKey(newUmpleID_1)){ boolean subClassFound=false; Class clazz_1=Class.forName(newClassName_1); Constructor constructor_1=clazz_1.getConstructor(String.class, Map.class); Object objectNew_1=constructor_1.newInstance(obj,umpleObjectIDMap); courseSections.add((CourseSection)objectNew_1); } else{ courseSections.add((CourseSection)umpleObjectIDMap.get(newUmpleID_1)); } } }catch(Exception e){ } //} } } /* * A json parser to parse the input jsonString, if -s genJson is specified * * @param String aJsonString is the string in json format that is to be processed and turned into an object * * @ return HashMap<String,String> that stores paresed result, key is the attribute(or associations) of an object, value is the attribute value or association string */ public static HashMap<String,String> fromJsonParser(String jsonString){ HashMap<String,String> parsedResultMap = new HashMap<String,String>(); try{ //Below (String, Pattern, Matcher) are the regex strings and their patterns and matcher used to process a jsonString // topLevelString is the regex representing the topLevel class name String topLevelString = "\\{\\\"[A-Z]\\w*\\\":"; Pattern topLevelPattern = Pattern.compile(topLevelString); Matcher topLevelMatcher = topLevelPattern.matcher(jsonString); String quotes="\\\""; String colon="\\:"; String colonSquareBracket="\\:\\["; if(topLevelMatcher.find()){ //actual string that represent the topLevel className String topLevelStringFound=topLevelMatcher.group(0); String className=topLevelStringFound.split(quotes)[1]; parsedResultMap.put("className", className); jsonString=jsonString.split(topLevelString,2)[1]; //objIDString is the regex representing umpleObjectID that could be found in jsonString String objIDString = "\"umpleObjectID\"\\:\"[0-9]*\","; Pattern objIDPattern = Pattern.compile(objIDString); Matcher objIDMatcher = objIDPattern.matcher(jsonString); if(objIDMatcher.find()){ String objIDFound=objIDMatcher.group(0); parsedResultMap.put("umpleObjectID", objIDFound.split(colon)[1].split(quotes)[1]); jsonString=jsonString.replaceFirst(objIDFound,""); } String timeString="\\\"\\w*\\\"\\:\\\"\\d{2}:\\d{2}\\:\\d{2}\\\""; Pattern timeStringPattern=Pattern.compile(timeString); Matcher timeStringPatternMatcher=timeStringPattern.matcher(jsonString); if(timeStringPatternMatcher.find()){ String timeStringFound=timeStringPatternMatcher.group(0); parsedResultMap.put(timeStringFound.split(colon,2)[0].split(quotes)[1], timeStringFound.split(colon,2)[1].split(quotes)[1]); } // pairString is the regex for an object's attribute and attribute value, the string parsed will be in key-value formate String pairString = "(\\\"(?!umpleObjectID)[^\\\"]+)\\\":\\\"((?:\\\\\\\"|[^\\\"])*)"; Pattern pairPattern=Pattern.compile(pairString); Matcher pairMatcher=pairPattern.matcher(jsonString); String associationString="(?=\\\"\\w*\\\"\\:\\[\\{)(?:(?=.*?\\[\\{(?!.*?\\1)(.*\\}\\](?!.*\\2).*))(?=.*?\\}\\](?!.*?\\2)(.*)).)+?.*?(?=\\1)[^\\[]*(?=\\2$)"; Pattern associationPattern=Pattern.compile(associationString); String newObjJsonString="(?=\\,\\\"\\w*\\\"\\:\\{)(?:(?=.*?\\{\\\"(?!.*?\\1)(.*\\}(?!.*\\2).*))(?=.*?\\}(?!.*?\\2)(.*)).)+?.*?(?=\\1)[^\\{]*(?=\\2$)"; Pattern newObjJsonPattern=Pattern.compile(newObjJsonString); String quoteColonQuote="\\\"\\:\\\""; //Keep on parsing the attribute's key-value pair, //until a List (multi-associations) pattern or a newObject parttern (single association) is found while(pairMatcher.find()){ String pairStringFound=pairMatcher.group(0); if(parsedResultMap.get(pairStringFound.split(colon)[0].split(quotes)[1])==null){ String keyPair=pairStringFound.split(colon)[0].split(quotes)[1]; String valuePair=pairStringFound.split(quoteColonQuote,2)[1]; keyPair=keyPair.replace("\\\\","\\").replace("\\\"","\""); valuePair=valuePair.replace("\\\\","\\").replace("\\\"","\""); parsedResultMap.put(keyPair,valuePair); jsonString=jsonString.replaceFirst(pairString, ""); } int lastIndex = 0; while (lastIndex<jsonString.length()){ String remainingJson=jsonString.substring(lastIndex); Matcher associationMatcher=associationPattern.matcher(jsonString); Matcher newObjJsonMatcher=newObjJsonPattern.matcher(jsonString); boolean assoFound=associationMatcher.find(); boolean newObjFound=newObjJsonMatcher.find(); if (assoFound&&(!newObjFound||associationMatcher.start()<newObjJsonMatcher.start())){ String assoStringFound=associationMatcher.group(0); String associationName=assoStringFound.split(colon,2)[0].split(quotes)[1];; String associationItems=assoStringFound.split(colonSquareBracket,2)[1]; parsedResultMap.put(associationName, associationItems); jsonString=jsonString.replaceFirst(associationString, ""); } else if (newObjFound){ String newObjJsonFound=newObjJsonMatcher.group(0); String newObjName=newObjJsonFound.split(colon,2)[0].split(quotes)[1]; String newObjItems=newObjJsonFound.split(colon,2)[1]; parsedResultMap.put(newObjName, newObjItems); jsonString=jsonString.replaceFirst(newObjJsonString, ""); }else{ break; } } } } return parsedResultMap; }catch(NullPointerException e){ return parsedResultMap; } } public static String fromJsonParserHelper(String jsonString, String regexString){ String umpleID = ""; String quo="\\\""; try{ Pattern umpleIDPattern=Pattern.compile(regexString); Matcher umpleIDMatcher=umpleIDPattern.matcher(jsonString); if(umpleIDMatcher.find()){ String umpleIDStringFound=umpleIDMatcher.group(0); String idString="\\\"\\d*\\\""; Pattern idPattern=Pattern.compile(idString); Matcher idMatcher=idPattern.matcher(umpleIDStringFound); if(idMatcher.find()){ umpleID=idMatcher.group(0).split(quo)[1]; } } return umpleID; } catch(NullPointerException e){ return umpleID; } } public static List<String> fromJsonParserList(String objListString){ List<String> objList=new ArrayList<String>(); try{ String objString="(?:(?=.*?\\{(?!.*?\\1)(.*\\}(?!.*\\2).*))(?=.*?\\}(?!.*?\\2)(.*)).)+?.*?(?=\\1)[^\\{]*(?=\\2$)"; Pattern objStringPattern=Pattern.compile(objString); Matcher objStringMatcher=objStringPattern.matcher(objListString); while(objStringMatcher.find()){ objList.add(objStringMatcher.group(0)); } return objList; }catch(NullPointerException e){ return objList; } } public static String fromJsonParserClassName(String objNameString){ String nextName=""; String quotes="\\\""; try{ String nextNameString="\\{\\\"[A-Z]\\w*\\\":"; Pattern nextNamePattern=Pattern.compile(nextNameString); Matcher nextNameMatcher=nextNamePattern.matcher(objNameString); if(nextNameMatcher.find()){ nextName=nextNameMatcher.group(0).split(quotes)[1]; } return nextName; }catch(NullPointerException e){ return nextName; } } } /*PLEASE DO NOT EDIT THIS CODE*/ /*This code was generated using the UMPLE 1.35.0.7523.c616a4dce modeling language!*/ package example; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.sql.*; import java.lang.reflect.Constructor; // line 41 "../ToJsonComplexTest.ump" public class CourseSection { //------------------------ // MEMBER VARIABLES //------------------------ //CourseSection Attributes private String code; //CourseSection Associations private Course course; private List<Employee> employees; private List<Registration> registrations; //------------------------ // CONSTRUCTOR //------------------------ public CourseSection(String aCode, Course aCourse) { code = aCode; boolean didAddCourse = setCourse(aCourse); if (!didAddCourse) { throw new RuntimeException("Unable to create courseSection due to course. See https://manual.umple.org?RE002ViolationofAssociationMultiplicity.html"); } employees = new ArrayList<Employee>(); registrations = new ArrayList<Registration>(); } //------------------------ // INTERFACE //------------------------ public boolean setCode(String aCode) { boolean wasSet = false; code = aCode; wasSet = true; return wasSet; } public String getCode() { return code; } /* Code from template association_GetOne */ public Course getCourse() { return course; } /* Code from template association_GetMany */ public Employee getEmployee(int index) { Employee aEmployee = employees.get(index); return aEmployee; } public List<Employee> getEmployees() { List<Employee> newEmployees = Collections.unmodifiableList(employees); return newEmployees; } public int numberOfEmployees() { int number = employees.size(); return number; } public boolean hasEmployees() { boolean has = employees.size() > 0; return has; } public int indexOfEmployee(Employee aEmployee) { int index = employees.indexOf(aEmployee); return index; } /* Code from template association_GetMany */ public Registration getRegistration(int index) { Registration aRegistration = registrations.get(index); return aRegistration; } public List<Registration> getRegistrations() { List<Registration> newRegistrations = Collections.unmodifiableList(registrations); return newRegistrations; } public int numberOfRegistrations() { int number = registrations.size(); return number; } public boolean hasRegistrations() { boolean has = registrations.size() > 0; return has; } public int indexOfRegistration(Registration aRegistration) { int index = registrations.indexOf(aRegistration); return index; } /* Code from template association_SetOneToMany */ public boolean setCourse(Course aCourse) { boolean wasSet = false; if (aCourse == null) { return wasSet; } Course existingCourse = course; course = aCourse; if (existingCourse != null && !existingCourse.equals(aCourse)) { existingCourse.removeCourseSection(this); } course.addCourseSection(this); wasSet = true; return wasSet; } /* Code from template association_MinimumNumberOfMethod */ public static int minimumNumberOfEmployees() { return 0; } /* Code from template association_AddManyToManyMethod */ public boolean addEmployee(Employee aEmployee) { boolean wasAdded = false; if (employees.contains(aEmployee)) { return false; } employees.add(aEmployee); if (aEmployee.indexOfTeache(this) != -1) { wasAdded = true; } else { wasAdded = aEmployee.addTeache(this); if (!wasAdded) { employees.remove(aEmployee); } } return wasAdded; } /* Code from template association_RemoveMany */ public boolean removeEmployee(Employee aEmployee) { boolean wasRemoved = false; if (!employees.contains(aEmployee)) { return wasRemoved; } int oldIndex = employees.indexOf(aEmployee); employees.remove(oldIndex); if (aEmployee.indexOfTeache(this) == -1) { wasRemoved = true; } else { wasRemoved = aEmployee.removeTeache(this); if (!wasRemoved) { employees.add(oldIndex,aEmployee); } } return wasRemoved; } /* Code from template association_AddIndexControlFunctions */ public boolean addEmployeeAt(Employee aEmployee, int index) { boolean wasAdded = false; if(addEmployee(aEmployee)) { if(index < 0 ) { index = 0; } if(index > numberOfEmployees()) { index = numberOfEmployees() - 1; } employees.remove(aEmployee); employees.add(index, aEmployee); wasAdded = true; } return wasAdded; } public boolean addOrMoveEmployeeAt(Employee aEmployee, int index) { boolean wasAdded = false; if(employees.contains(aEmployee)) { if(index < 0 ) { index = 0; } if(index > numberOfEmployees()) { index = numberOfEmployees() - 1; } employees.remove(aEmployee); employees.add(index, aEmployee); wasAdded = true; } else { wasAdded = addEmployeeAt(aEmployee, index); } return wasAdded; } /* Code from template association_MinimumNumberOfMethod */ public static int minimumNumberOfRegistrations() { return 0; } /* Code from template association_AddManyToOne */ public Registration addRegistration(Student aStudent) { return new Registration(aStudent, this); } public boolean addRegistration(Registration aRegistration) { boolean wasAdded = false; if (registrations.contains(aRegistration)) { return false; } CourseSection existingCourseSection = aRegistration.getCourseSection(); boolean isNewCourseSection = existingCourseSection != null && !this.equals(existingCourseSection); if (isNewCourseSection) { aRegistration.setCourseSection(this); } else { registrations.add(aRegistration); } wasAdded = true; return wasAdded; } public boolean removeRegistration(Registration aRegistration) { boolean wasRemoved = false; //Unable to remove aRegistration, as it must always have a courseSection if (!this.equals(aRegistration.getCourseSection())) { registrations.remove(aRegistration); wasRemoved = true; } return wasRemoved; } /* Code from template association_AddIndexControlFunctions */ public boolean addRegistrationAt(Registration aRegistration, int index) { boolean wasAdded = false; if(addRegistration(aRegistration)) { if(index < 0 ) { index = 0; } if(index > numberOfRegistrations()) { index = numberOfRegistrations() - 1; } registrations.remove(aRegistration); registrations.add(index, aRegistration); wasAdded = true; } return wasAdded; } public boolean addOrMoveRegistrationAt(Registration aRegistration, int index) { boolean wasAdded = false; if(registrations.contains(aRegistration)) { if(index < 0 ) { index = 0; } if(index > numberOfRegistrations()) { index = numberOfRegistrations() - 1; } registrations.remove(aRegistration); registrations.add(index, aRegistration); wasAdded = true; } else { wasAdded = addRegistrationAt(aRegistration, index); } return wasAdded; } public void delete() { Course placeholderCourse = course; this.course = null; if(placeholderCourse != null) { placeholderCourse.removeCourseSection(this); } ArrayList<Employee> copyOfEmployees = new ArrayList<Employee>(employees); employees.clear(); for(Employee aEmployee : copyOfEmployees) { aEmployee.removeTeache(this); } for(int i=registrations.size(); i > 0; i--) { Registration aRegistration = registrations.get(i - 1); aRegistration.delete(); } } public String toString() { return super.toString() + "["+ "code" + ":" + getCode()+ "]" + System.getProperties().getProperty("line.separator") + " " + "course = "+(getCourse()!=null?Integer.toHexString(System.identityHashCode(getCourse())):"null"); } /* * Generate Json for this object and connected objects visited objects to enable avoidance of infinite loops * * @return a string in Json format of this object */ public String toJson() { HashSet<Object> visitedList = new HashSet<Object>(); StringBuilder toJsonOutput = new StringBuilder(); toJsonOutput.append("{\n"); this.toJsonHelper(toJsonOutput, visitedList,1,true); toJsonOutput.append("\n}"); return(toJsonOutput.toString()); } /* * Helper function to generate Json for this object and connected objects visited objects to enable avoidance of infinite loops * * @param toJsonOutput Output is aded to this as the network of objects is traversed * @param visitedList Every concrete object visited is added so we don't re-outpu * @param nestLevel As we output deeper objects, indent them more * @param atConcreteClass false when we are recursing to a superclass * so we get the superclass data * @return whether or not anything was output (so we can tell whether we need to output a comma) */ public boolean toJsonHelper(StringBuilder toJsonOutput, HashSet<Object> visitedList, int nestLevel, boolean atConcreteClass){ String indent = " ".repeat(nestLevel); boolean alreadyVisited = false; boolean haveOutputItem = false; if(atConcreteClass) { // This will not be true in a super call; output header toJsonOutput.append(indent+"\""+this.toString().split("@")[0]+ "\" : {\n"+indent+ " \"umpleObjectID\" : \""+System.identityHashCode(this)+"\""); // Check if we have already visited this object. If so we will not output details alreadyVisited = visitedList.contains(this); if(!alreadyVisited) { toJsonOutput.append(",\n"); visitedList.add(this); } } // There is no superclass of this class if(alreadyVisited) { toJsonOutput.append("\n"); } else { // Check if this class has a superclass. If it does, we make a call to output superclass content // This will keep calling super so the topmost attributes and associations appear first // When an object has not already been visited, output its details if(haveOutputItem){ //toJsonOutput.append(",\n"); } if(haveOutputItem){ toJsonOutput.append(",\n"); } toJsonOutput.append(indent); toJsonOutput.append(" \""); toJsonOutput.append("code"); toJsonOutput.append("\" : \""); String primValue_0=""+getCode()+""; toJsonOutput.append(primValue_0.replace("\\","\\\\").replace("\"","\\\"")); toJsonOutput.append("\""); haveOutputItem=true; //haveOutputItem = false; //haveOutputItem = false; if(haveOutputItem) { toJsonOutput.append(",\n"); } toJsonOutput.append(indent); toJsonOutput.append("\n"+indent); toJsonOutput.append(" \""); toJsonOutput.append("course"); toJsonOutput.append("\""); toJsonOutput.append(" : "); toJsonOutput.append("\n"); toJsonOutput.append(indent+" {"); toJsonOutput.append("\n");Course anotherItem_0 = getCourse(); anotherItem_0.toJsonHelper(toJsonOutput, visitedList, nestLevel+2, true); toJsonOutput.append("\n"); toJsonOutput.append(indent+" }"); haveOutputItem=true; if(haveOutputItem) { toJsonOutput.append(",\n"); } toJsonOutput.append(indent); toJsonOutput.append(" \""); toJsonOutput.append("employees"); toJsonOutput.append("\""); toJsonOutput.append(" : ["); toJsonOutput.append("\n"); haveOutputItem = false; try{ for (Employee anItem_1 :getEmployees()){ if(haveOutputItem) { toJsonOutput.append(",\n"); } toJsonOutput.append(indent+" {"); toJsonOutput.append("\n"); anItem_1.toJsonHelper(toJsonOutput, visitedList,nestLevel+2,true); toJsonOutput.append("\n"); toJsonOutput.append(indent+" }"); haveOutputItem=true; } }catch (NullPointerException e){ } toJsonOutput.append("\n"); toJsonOutput.append(indent+" ]"); haveOutputItem=true; if(haveOutputItem) { toJsonOutput.append(",\n"); } toJsonOutput.append(indent); toJsonOutput.append(" \""); toJsonOutput.append("registrations"); toJsonOutput.append("\""); toJsonOutput.append(" : ["); toJsonOutput.append("\n"); haveOutputItem = false; try{ for (Registration anItem_2 :getRegistrations()){ if(haveOutputItem) { toJsonOutput.append(",\n"); } toJsonOutput.append(indent+" {"); toJsonOutput.append("\n"); anItem_2.toJsonHelper(toJsonOutput, visitedList,nestLevel+2,true); toJsonOutput.append("\n"); toJsonOutput.append(indent+" }"); haveOutputItem=true; } }catch (NullPointerException e){ } toJsonOutput.append("\n"); toJsonOutput.append(indent+" ]"); haveOutputItem=true; toJsonOutput.append(indent+" \n"); } // Finalize the output of the concrete class if(atConcreteClass) { if(!alreadyVisited) { toJsonOutput.append("\n"); } toJsonOutput.append(indent+"}"); } haveOutputItem = true; return haveOutputItem; } /* * Deserialize Json string to instantiate Objects from top-level class * * @param umpleObjectIDMap<String, Object> mapping parsed objectID (from Json string) with newly instantiated object's objectID * * @param String aJsonString is the string in json format that is to be processed and turned into an object * * @return newly instantiated Object */ public static CourseSection fromJson(String aJsonString){ // process the input jsonString so that it can further processed using regex aJsonString=aJsonString.replace("\n","").replace(" ",""); // a map to store the umpleObjectID present in jsonString Map<String, Object> umpleObjectIDMap=new HashMap<>(); // instantiate a new object CourseSection anObject = new CourseSection(aJsonString, umpleObjectIDMap); return anObject; } /* * A new constructor specifically implemented if -s genJson is specified * * @param String aJsonString is the string in json format that is to be processed and turned into an object * * @param umpleObjectIDMap<String, Integer> mapping parsed objectID (from Json string) with newly instantiated object's objectID */ @SuppressWarnings("unchecked") public CourseSection(String aJsonString, Map<String, Object> umpleObjectIDMap){ // Initialize a HashMap to store the parsed result // key is the attribute name present in the jsonString // value is the attribute value present in the jsonString boolean visitedSuperClass=false; HashMap<String,String> parsedResult = new HashMap<String,String>(); parsedResult = fromJsonParser(aJsonString); if(!parsedResult.isEmpty()){ boolean classExist; boolean classChildExist; String parsedClassName=parsedResult.get("className"); String childName=this.getClass().getSimpleName(); classExist="CourseSection".equals(parsedClassName); classChildExist=childName.equals(parsedClassName); // if top-level class does not exist, throw exception if(!classExist&&!classChildExist){ throw new IllegalArgumentException("Top-level class \""+parsedClassName+"\" does not exist, please check the input json string"); } String umpleObjectId=parsedResult.get("umpleObjectID"); // Check if the object has already been visited and created //if((umpleObjectIDMap.get(umpleObjectId)==null)||visitedSuperClass){ try{ visitedSuperClass=false; // map the old objectID (in jsonString) with the newly created object's hashCode in umpleObjectIDMap umpleObjectIDMap.put(umpleObjectId,this); String jsonKey=""; jsonKey="code"; //more types should be considered here this.code=parsedResult.get(jsonKey); // below for-loop check the association class of the top level class jsonKey="course"; String newJsonString_0=parsedResult.get(jsonKey); String newIDRegex_0="\\\"umpleObjectID\\\"\\:\\\"[0-9]*\\\""; String newUmpleID_0=fromJsonParserHelper(newJsonString_0,newIDRegex_0); //Multiple associations if(!umpleObjectIDMap.containsKey(newUmpleID_0)){ String newClassNameOne_0=fromJsonParserClassName(newJsonString_0); Class clazzOne_0=Class.forName(newClassNameOne_0); Constructor constructorOne_0=clazzOne_0.getConstructor(String.class, Map.class); Object objectNewOne_0=constructorOne_0.newInstance(newJsonString_0,umpleObjectIDMap); Course oneAssoObj_0=(Course)objectNewOne_0; course=oneAssoObj_0; } else{ course=(Course)umpleObjectIDMap.get(newUmpleID_0); } jsonKey="employees"; String newJsonString_1=parsedResult.get(jsonKey); String newIDRegex_1="\\\"umpleObjectID\\\"\\:\\\"[0-9]*\\\""; String newUmpleID_1=fromJsonParserHelper(newJsonString_1,newIDRegex_1); //Multiple associations List<String> multiAssoObjList_1 = new ArrayList<String>(); multiAssoObjList_1=fromJsonParserList(newJsonString_1); employees=new ArrayList<Employee>(); for(String obj: multiAssoObjList_1){ newUmpleID_1=fromJsonParserHelper(obj,newIDRegex_1); String newClassName_1=fromJsonParserClassName(obj); if(!umpleObjectIDMap.containsKey(newUmpleID_1)){ boolean subClassFound=false; Class clazz_1=Class.forName(newClassName_1); Constructor constructor_1=clazz_1.getConstructor(String.class, Map.class); Object objectNew_1=constructor_1.newInstance(obj,umpleObjectIDMap); employees.add((Employee)objectNew_1); } else{ employees.add((Employee)umpleObjectIDMap.get(newUmpleID_1)); } } jsonKey="registrations"; String newJsonString_2=parsedResult.get(jsonKey); String newIDRegex_2="\\\"umpleObjectID\\\"\\:\\\"[0-9]*\\\""; String newUmpleID_2=fromJsonParserHelper(newJsonString_2,newIDRegex_2); //Multiple associations List<String> multiAssoObjList_2 = new ArrayList<String>(); multiAssoObjList_2=fromJsonParserList(newJsonString_2); registrations=new ArrayList<Registration>(); for(String obj: multiAssoObjList_2){ newUmpleID_2=fromJsonParserHelper(obj,newIDRegex_2); String newClassName_2=fromJsonParserClassName(obj); if(!umpleObjectIDMap.containsKey(newUmpleID_2)){ boolean subClassFound=false; Class clazz_2=Class.forName(newClassName_2); Constructor constructor_2=clazz_2.getConstructor(String.class, Map.class); Object objectNew_2=constructor_2.newInstance(obj,umpleObjectIDMap); registrations.add((Registration)objectNew_2); } else{ registrations.add((Registration)umpleObjectIDMap.get(newUmpleID_2)); } } }catch(Exception e){ } //} } } /* * A json parser to parse the input jsonString, if -s genJson is specified * * @param String aJsonString is the string in json format that is to be processed and turned into an object * * @ return HashMap<String,String> that stores paresed result, key is the attribute(or associations) of an object, value is the attribute value or association string */ public static HashMap<String,String> fromJsonParser(String jsonString){ HashMap<String,String> parsedResultMap = new HashMap<String,String>(); try{ //Below (String, Pattern, Matcher) are the regex strings and their patterns and matcher used to process a jsonString // topLevelString is the regex representing the topLevel class name String topLevelString = "\\{\\\"[A-Z]\\w*\\\":"; Pattern topLevelPattern = Pattern.compile(topLevelString); Matcher topLevelMatcher = topLevelPattern.matcher(jsonString); String quotes="\\\""; String colon="\\:"; String colonSquareBracket="\\:\\["; if(topLevelMatcher.find()){ //actual string that represent the topLevel className String topLevelStringFound=topLevelMatcher.group(0); String className=topLevelStringFound.split(quotes)[1]; parsedResultMap.put("className", className); jsonString=jsonString.split(topLevelString,2)[1]; //objIDString is the regex representing umpleObjectID that could be found in jsonString String objIDString = "\"umpleObjectID\"\\:\"[0-9]*\","; Pattern objIDPattern = Pattern.compile(objIDString); Matcher objIDMatcher = objIDPattern.matcher(jsonString); if(objIDMatcher.find()){ String objIDFound=objIDMatcher.group(0); parsedResultMap.put("umpleObjectID", objIDFound.split(colon)[1].split(quotes)[1]); jsonString=jsonString.replaceFirst(objIDFound,""); } String timeString="\\\"\\w*\\\"\\:\\\"\\d{2}:\\d{2}\\:\\d{2}\\\""; Pattern timeStringPattern=Pattern.compile(timeString); Matcher timeStringPatternMatcher=timeStringPattern.matcher(jsonString); if(timeStringPatternMatcher.find()){ String timeStringFound=timeStringPatternMatcher.group(0); parsedResultMap.put(timeStringFound.split(colon,2)[0].split(quotes)[1], timeStringFound.split(colon,2)[1].split(quotes)[1]); } // pairString is the regex for an object's attribute and attribute value, the string parsed will be in key-value formate String pairString = "(\\\"(?!umpleObjectID)[^\\\"]+)\\\":\\\"((?:\\\\\\\"|[^\\\"])*)"; Pattern pairPattern=Pattern.compile(pairString); Matcher pairMatcher=pairPattern.matcher(jsonString); String associationString="(?=\\\"\\w*\\\"\\:\\[\\{)(?:(?=.*?\\[\\{(?!.*?\\1)(.*\\}\\](?!.*\\2).*))(?=.*?\\}\\](?!.*?\\2)(.*)).)+?.*?(?=\\1)[^\\[]*(?=\\2$)"; Pattern associationPattern=Pattern.compile(associationString); String newObjJsonString="(?=\\,\\\"\\w*\\\"\\:\\{)(?:(?=.*?\\{\\\"(?!.*?\\1)(.*\\}(?!.*\\2).*))(?=.*?\\}(?!.*?\\2)(.*)).)+?.*?(?=\\1)[^\\{]*(?=\\2$)"; Pattern newObjJsonPattern=Pattern.compile(newObjJsonString); String quoteColonQuote="\\\"\\:\\\""; //Keep on parsing the attribute's key-value pair, //until a List (multi-associations) pattern or a newObject parttern (single association) is found while(pairMatcher.find()){ String pairStringFound=pairMatcher.group(0); if(parsedResultMap.get(pairStringFound.split(colon)[0].split(quotes)[1])==null){ String keyPair=pairStringFound.split(colon)[0].split(quotes)[1]; String valuePair=pairStringFound.split(quoteColonQuote,2)[1]; keyPair=keyPair.replace("\\\\","\\").replace("\\\"","\""); valuePair=valuePair.replace("\\\\","\\").replace("\\\"","\""); parsedResultMap.put(keyPair,valuePair); jsonString=jsonString.replaceFirst(pairString, ""); } int lastIndex = 0; while (lastIndex<jsonString.length()){ String remainingJson=jsonString.substring(lastIndex); Matcher associationMatcher=associationPattern.matcher(jsonString); Matcher newObjJsonMatcher=newObjJsonPattern.matcher(jsonString); boolean assoFound=associationMatcher.find(); boolean newObjFound=newObjJsonMatcher.find(); if (assoFound&&(!newObjFound||associationMatcher.start()<newObjJsonMatcher.start())){ String assoStringFound=associationMatcher.group(0); String associationName=assoStringFound.split(colon,2)[0].split(quotes)[1];; String associationItems=assoStringFound.split(colonSquareBracket,2)[1]; parsedResultMap.put(associationName, associationItems); jsonString=jsonString.replaceFirst(associationString, ""); } else if (newObjFound){ String newObjJsonFound=newObjJsonMatcher.group(0); String newObjName=newObjJsonFound.split(colon,2)[0].split(quotes)[1]; String newObjItems=newObjJsonFound.split(colon,2)[1]; parsedResultMap.put(newObjName, newObjItems); jsonString=jsonString.replaceFirst(newObjJsonString, ""); }else{ break; } } } } return parsedResultMap; }catch(NullPointerException e){ return parsedResultMap; } } public static String fromJsonParserHelper(String jsonString, String regexString){ String umpleID = ""; String quo="\\\""; try{ Pattern umpleIDPattern=Pattern.compile(regexString); Matcher umpleIDMatcher=umpleIDPattern.matcher(jsonString); if(umpleIDMatcher.find()){ String umpleIDStringFound=umpleIDMatcher.group(0); String idString="\\\"\\d*\\\""; Pattern idPattern=Pattern.compile(idString); Matcher idMatcher=idPattern.matcher(umpleIDStringFound); if(idMatcher.find()){ umpleID=idMatcher.group(0).split(quo)[1]; } } return umpleID; } catch(NullPointerException e){ return umpleID; } } public static List<String> fromJsonParserList(String objListString){ List<String> objList=new ArrayList<String>(); try{ String objString="(?:(?=.*?\\{(?!.*?\\1)(.*\\}(?!.*\\2).*))(?=.*?\\}(?!.*?\\2)(.*)).)+?.*?(?=\\1)[^\\{]*(?=\\2$)"; Pattern objStringPattern=Pattern.compile(objString); Matcher objStringMatcher=objStringPattern.matcher(objListString); while(objStringMatcher.find()){ objList.add(objStringMatcher.group(0)); } return objList; }catch(NullPointerException e){ return objList; } } public static String fromJsonParserClassName(String objNameString){ String nextName=""; String quotes="\\\""; try{ String nextNameString="\\{\\\"[A-Z]\\w*\\\":"; Pattern nextNamePattern=Pattern.compile(nextNameString); Matcher nextNameMatcher=nextNamePattern.matcher(objNameString); if(nextNameMatcher.find()){ nextName=nextNameMatcher.group(0).split(quotes)[1]; } return nextName; }catch(NullPointerException e){ return nextName; } } } /*PLEASE DO NOT EDIT THIS CODE*/ /*This code was generated using the UMPLE 1.35.0.7523.c616a4dce modeling language!*/ package example; import java.util.HashSet; import java.util.Map; import java.util.HashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.ArrayList; import java.util.List; import java.sql.*; import java.lang.reflect.Constructor; // line 46 "../ToJsonComplexTest.ump" public class Registration { //------------------------ // MEMBER VARIABLES //------------------------ //Registration Attributes private String grade; //Registration Associations private Student student; private CourseSection courseSection; //Helper Variables private int cachedHashCode; private boolean canSetStudent; private boolean canSetCourseSection; //------------------------ // CONSTRUCTOR //------------------------ public Registration(Student aStudent, CourseSection aCourseSection) { cachedHashCode = -1; canSetStudent = true; canSetCourseSection = true; grade = null; boolean didAddStudent = setStudent(aStudent); if (!didAddStudent) { throw new RuntimeException("Unable to create registration due to student. See https://manual.umple.org?RE002ViolationofAssociationMultiplicity.html"); } boolean didAddCourseSection = setCourseSection(aCourseSection); if (!didAddCourseSection) { throw new RuntimeException("Unable to create registration due to courseSection. See https://manual.umple.org?RE002ViolationofAssociationMultiplicity.html"); } } //------------------------ // INTERFACE //------------------------ public boolean setGrade(String aGrade) { boolean wasSet = false; grade = aGrade; wasSet = true; return wasSet; } public String getGrade() { return grade; } /* Code from template association_GetOne */ public Student getStudent() { return student; } /* Code from template association_GetOne */ public CourseSection getCourseSection() { return courseSection; } /* Code from template association_SetOneToManyAssociationClass */ public boolean setStudent(Student aStudent) { boolean wasSet = false; if (!canSetStudent) { return false; } if (aStudent == null) { return wasSet; } Student existingStudent = student; student = aStudent; if (existingStudent != null && !existingStudent.equals(aStudent)) { existingStudent.removeRegistration(this); } if (!student.addRegistration(this)) { student = existingStudent; wasSet = false; } else { wasSet = true; } return wasSet; } /* Code from template association_SetOneToManyAssociationClass */ public boolean setCourseSection(CourseSection aCourseSection) { boolean wasSet = false; if (!canSetCourseSection) { return false; } if (aCourseSection == null) { return wasSet; } CourseSection existingCourseSection = courseSection; courseSection = aCourseSection; if (existingCourseSection != null && !existingCourseSection.equals(aCourseSection)) { existingCourseSection.removeRegistration(this); } if (!courseSection.addRegistration(this)) { courseSection = existingCourseSection; wasSet = false; } else { wasSet = true; } return wasSet; } public boolean equals(Object obj) { if (obj == null) { return false; } if (!getClass().equals(obj.getClass())) { return false; } Registration compareTo = (Registration)obj; if (getStudent() == null && compareTo.getStudent() != null) { return false; } else if (getStudent() != null && !getStudent().equals(compareTo.getStudent())) { return false; } if (getCourseSection() == null && compareTo.getCourseSection() != null) { return false; } else if (getCourseSection() != null && !getCourseSection().equals(compareTo.getCourseSection())) { return false; } return true; } public int hashCode() { if (cachedHashCode != -1) { return cachedHashCode; } cachedHashCode = 17; if (getStudent() != null) { cachedHashCode = cachedHashCode * 23 + getStudent().hashCode(); } else { cachedHashCode = cachedHashCode * 23; } if (getCourseSection() != null) { cachedHashCode = cachedHashCode * 23 + getCourseSection().hashCode(); } else { cachedHashCode = cachedHashCode * 23; } canSetStudent = false; canSetCourseSection = false; return cachedHashCode; } public void delete() { Student placeholderStudent = student; this.student = null; if(placeholderStudent != null) { placeholderStudent.removeRegistration(this); } CourseSection placeholderCourseSection = courseSection; this.courseSection = null; if(placeholderCourseSection != null) { placeholderCourseSection.removeRegistration(this); } } public String toString() { return super.toString() + "["+ "grade" + ":" + getGrade()+ "]" + System.getProperties().getProperty("line.separator") + " " + "student = "+(getStudent()!=null?Integer.toHexString(System.identityHashCode(getStudent())):"null") + System.getProperties().getProperty("line.separator") + " " + "courseSection = "+(getCourseSection()!=null?Integer.toHexString(System.identityHashCode(getCourseSection())):"null"); } /* * Generate Json for this object and connected objects visited objects to enable avoidance of infinite loops * * @return a string in Json format of this object */ public String toJson() { HashSet<Object> visitedList = new HashSet<Object>(); StringBuilder toJsonOutput = new StringBuilder(); toJsonOutput.append("{\n"); this.toJsonHelper(toJsonOutput, visitedList,1,true); toJsonOutput.append("\n}"); return(toJsonOutput.toString()); } /* * Helper function to generate Json for this object and connected objects visited objects to enable avoidance of infinite loops * * @param toJsonOutput Output is aded to this as the network of objects is traversed * @param visitedList Every concrete object visited is added so we don't re-outpu * @param nestLevel As we output deeper objects, indent them more * @param atConcreteClass false when we are recursing to a superclass * so we get the superclass data * @return whether or not anything was output (so we can tell whether we need to output a comma) */ public boolean toJsonHelper(StringBuilder toJsonOutput, HashSet<Object> visitedList, int nestLevel, boolean atConcreteClass){ String indent = " ".repeat(nestLevel); boolean alreadyVisited = false; boolean haveOutputItem = false; if(atConcreteClass) { // This will not be true in a super call; output header toJsonOutput.append(indent+"\""+this.toString().split("@")[0]+ "\" : {\n"+indent+ " \"umpleObjectID\" : \""+System.identityHashCode(this)+"\""); // Check if we have already visited this object. If so we will not output details alreadyVisited = visitedList.contains(this); if(!alreadyVisited) { toJsonOutput.append(",\n"); visitedList.add(this); } } // There is no superclass of this class if(alreadyVisited) { toJsonOutput.append("\n"); } else { // Check if this class has a superclass. If it does, we make a call to output superclass content // This will keep calling super so the topmost attributes and associations appear first // When an object has not already been visited, output its details if(haveOutputItem){ //toJsonOutput.append(",\n"); } if(haveOutputItem){ toJsonOutput.append(",\n"); } toJsonOutput.append(indent); toJsonOutput.append(" \""); toJsonOutput.append("grade"); toJsonOutput.append("\" : \""); String primValue_0=""+getGrade()+""; toJsonOutput.append(primValue_0.replace("\\","\\\\").replace("\"","\\\"")); toJsonOutput.append("\""); haveOutputItem=true; //haveOutputItem = false; //haveOutputItem = false; if(haveOutputItem) { toJsonOutput.append(",\n"); } toJsonOutput.append(indent); toJsonOutput.append("\n"+indent); toJsonOutput.append(" \""); toJsonOutput.append("student"); toJsonOutput.append("\""); toJsonOutput.append(" : "); toJsonOutput.append("\n"); toJsonOutput.append(indent+" {"); toJsonOutput.append("\n");Student anotherItem_0 = getStudent(); anotherItem_0.toJsonHelper(toJsonOutput, visitedList, nestLevel+2, true); toJsonOutput.append("\n"); toJsonOutput.append(indent+" }"); haveOutputItem=true; if(haveOutputItem) { toJsonOutput.append(",\n"); } toJsonOutput.append(indent); toJsonOutput.append("\n"+indent); toJsonOutput.append(" \""); toJsonOutput.append("courseSection"); toJsonOutput.append("\""); toJsonOutput.append(" : "); toJsonOutput.append("\n"); toJsonOutput.append(indent+" {"); toJsonOutput.append("\n");CourseSection anotherItem_1 = getCourseSection(); anotherItem_1.toJsonHelper(toJsonOutput, visitedList, nestLevel+2, true); toJsonOutput.append("\n"); toJsonOutput.append(indent+" }"); haveOutputItem=true; toJsonOutput.append(indent+" \n"); } // Finalize the output of the concrete class if(atConcreteClass) { if(!alreadyVisited) { toJsonOutput.append("\n"); } toJsonOutput.append(indent+"}"); } haveOutputItem = true; return haveOutputItem; } /* * Deserialize Json string to instantiate Objects from top-level class * * @param umpleObjectIDMap<String, Object> mapping parsed objectID (from Json string) with newly instantiated object's objectID * * @param String aJsonString is the string in json format that is to be processed and turned into an object * * @return newly instantiated Object */ public static Registration fromJson(String aJsonString){ // process the input jsonString so that it can further processed using regex aJsonString=aJsonString.replace("\n","").replace(" ",""); // a map to store the umpleObjectID present in jsonString Map<String, Object> umpleObjectIDMap=new HashMap<>(); // instantiate a new object Registration anObject = new Registration(aJsonString, umpleObjectIDMap); return anObject; } /* * A new constructor specifically implemented if -s genJson is specified * * @param String aJsonString is the string in json format that is to be processed and turned into an object * * @param umpleObjectIDMap<String, Integer> mapping parsed objectID (from Json string) with newly instantiated object's objectID */ @SuppressWarnings("unchecked") public Registration(String aJsonString, Map<String, Object> umpleObjectIDMap){ // Initialize a HashMap to store the parsed result // key is the attribute name present in the jsonString // value is the attribute value present in the jsonString boolean visitedSuperClass=false; HashMap<String,String> parsedResult = new HashMap<String,String>(); parsedResult = fromJsonParser(aJsonString); if(!parsedResult.isEmpty()){ boolean classExist; boolean classChildExist; String parsedClassName=parsedResult.get("className"); String childName=this.getClass().getSimpleName(); classExist="Registration".equals(parsedClassName); classChildExist=childName.equals(parsedClassName); // if top-level class does not exist, throw exception if(!classExist&&!classChildExist){ throw new IllegalArgumentException("Top-level class \""+parsedClassName+"\" does not exist, please check the input json string"); } String umpleObjectId=parsedResult.get("umpleObjectID"); // Check if the object has already been visited and created //if((umpleObjectIDMap.get(umpleObjectId)==null)||visitedSuperClass){ try{ visitedSuperClass=false; // map the old objectID (in jsonString) with the newly created object's hashCode in umpleObjectIDMap umpleObjectIDMap.put(umpleObjectId,this); String jsonKey=""; jsonKey="grade"; //more types should be considered here this.grade=parsedResult.get(jsonKey); // below for-loop check the association class of the top level class jsonKey="student"; String newJsonString_0=parsedResult.get(jsonKey); String newIDRegex_0="\\\"umpleObjectID\\\"\\:\\\"[0-9]*\\\""; String newUmpleID_0=fromJsonParserHelper(newJsonString_0,newIDRegex_0); cachedHashCode=-1; //Multiple associations if(!umpleObjectIDMap.containsKey(newUmpleID_0)){ String newClassNameOne_0=fromJsonParserClassName(newJsonString_0); Class clazzOne_0=Class.forName(newClassNameOne_0); Constructor constructorOne_0=clazzOne_0.getConstructor(String.class, Map.class); Object objectNewOne_0=constructorOne_0.newInstance(newJsonString_0,umpleObjectIDMap); Student oneAssoObj_0=(Student)objectNewOne_0; student=oneAssoObj_0; } else{ student=(Student)umpleObjectIDMap.get(newUmpleID_0); } jsonKey="courseSection"; String newJsonString_1=parsedResult.get(jsonKey); String newIDRegex_1="\\\"umpleObjectID\\\"\\:\\\"[0-9]*\\\""; String newUmpleID_1=fromJsonParserHelper(newJsonString_1,newIDRegex_1); cachedHashCode=-1; //Multiple associations if(!umpleObjectIDMap.containsKey(newUmpleID_1)){ String newClassNameOne_1=fromJsonParserClassName(newJsonString_1); Class clazzOne_1=Class.forName(newClassNameOne_1); Constructor constructorOne_1=clazzOne_1.getConstructor(String.class, Map.class); Object objectNewOne_1=constructorOne_1.newInstance(newJsonString_1,umpleObjectIDMap); CourseSection oneAssoObj_1=(CourseSection)objectNewOne_1; courseSection=oneAssoObj_1; } else{ courseSection=(CourseSection)umpleObjectIDMap.get(newUmpleID_1); } }catch(Exception e){ } //} } } /* * A json parser to parse the input jsonString, if -s genJson is specified * * @param String aJsonString is the string in json format that is to be processed and turned into an object * * @ return HashMap<String,String> that stores paresed result, key is the attribute(or associations) of an object, value is the attribute value or association string */ public static HashMap<String,String> fromJsonParser(String jsonString){ HashMap<String,String> parsedResultMap = new HashMap<String,String>(); try{ //Below (String, Pattern, Matcher) are the regex strings and their patterns and matcher used to process a jsonString // topLevelString is the regex representing the topLevel class name String topLevelString = "\\{\\\"[A-Z]\\w*\\\":"; Pattern topLevelPattern = Pattern.compile(topLevelString); Matcher topLevelMatcher = topLevelPattern.matcher(jsonString); String quotes="\\\""; String colon="\\:"; String colonSquareBracket="\\:\\["; if(topLevelMatcher.find()){ //actual string that represent the topLevel className String topLevelStringFound=topLevelMatcher.group(0); String className=topLevelStringFound.split(quotes)[1]; parsedResultMap.put("className", className); jsonString=jsonString.split(topLevelString,2)[1]; //objIDString is the regex representing umpleObjectID that could be found in jsonString String objIDString = "\"umpleObjectID\"\\:\"[0-9]*\","; Pattern objIDPattern = Pattern.compile(objIDString); Matcher objIDMatcher = objIDPattern.matcher(jsonString); if(objIDMatcher.find()){ String objIDFound=objIDMatcher.group(0); parsedResultMap.put("umpleObjectID", objIDFound.split(colon)[1].split(quotes)[1]); jsonString=jsonString.replaceFirst(objIDFound,""); } String timeString="\\\"\\w*\\\"\\:\\\"\\d{2}:\\d{2}\\:\\d{2}\\\""; Pattern timeStringPattern=Pattern.compile(timeString); Matcher timeStringPatternMatcher=timeStringPattern.matcher(jsonString); if(timeStringPatternMatcher.find()){ String timeStringFound=timeStringPatternMatcher.group(0); parsedResultMap.put(timeStringFound.split(colon,2)[0].split(quotes)[1], timeStringFound.split(colon,2)[1].split(quotes)[1]); } // pairString is the regex for an object's attribute and attribute value, the string parsed will be in key-value formate String pairString = "(\\\"(?!umpleObjectID)[^\\\"]+)\\\":\\\"((?:\\\\\\\"|[^\\\"])*)"; Pattern pairPattern=Pattern.compile(pairString); Matcher pairMatcher=pairPattern.matcher(jsonString); String associationString="(?=\\\"\\w*\\\"\\:\\[\\{)(?:(?=.*?\\[\\{(?!.*?\\1)(.*\\}\\](?!.*\\2).*))(?=.*?\\}\\](?!.*?\\2)(.*)).)+?.*?(?=\\1)[^\\[]*(?=\\2$)"; Pattern associationPattern=Pattern.compile(associationString); String newObjJsonString="(?=\\,\\\"\\w*\\\"\\:\\{)(?:(?=.*?\\{\\\"(?!.*?\\1)(.*\\}(?!.*\\2).*))(?=.*?\\}(?!.*?\\2)(.*)).)+?.*?(?=\\1)[^\\{]*(?=\\2$)"; Pattern newObjJsonPattern=Pattern.compile(newObjJsonString); String quoteColonQuote="\\\"\\:\\\""; //Keep on parsing the attribute's key-value pair, //until a List (multi-associations) pattern or a newObject parttern (single association) is found while(pairMatcher.find()){ String pairStringFound=pairMatcher.group(0); if(parsedResultMap.get(pairStringFound.split(colon)[0].split(quotes)[1])==null){ String keyPair=pairStringFound.split(colon)[0].split(quotes)[1]; String valuePair=pairStringFound.split(quoteColonQuote,2)[1]; keyPair=keyPair.replace("\\\\","\\").replace("\\\"","\""); valuePair=valuePair.replace("\\\\","\\").replace("\\\"","\""); parsedResultMap.put(keyPair,valuePair); jsonString=jsonString.replaceFirst(pairString, ""); } int lastIndex = 0; while (lastIndex<jsonString.length()){ String remainingJson=jsonString.substring(lastIndex); Matcher associationMatcher=associationPattern.matcher(jsonString); Matcher newObjJsonMatcher=newObjJsonPattern.matcher(jsonString); boolean assoFound=associationMatcher.find(); boolean newObjFound=newObjJsonMatcher.find(); if (assoFound&&(!newObjFound||associationMatcher.start()<newObjJsonMatcher.start())){ String assoStringFound=associationMatcher.group(0); String associationName=assoStringFound.split(colon,2)[0].split(quotes)[1];; String associationItems=assoStringFound.split(colonSquareBracket,2)[1]; parsedResultMap.put(associationName, associationItems); jsonString=jsonString.replaceFirst(associationString, ""); } else if (newObjFound){ String newObjJsonFound=newObjJsonMatcher.group(0); String newObjName=newObjJsonFound.split(colon,2)[0].split(quotes)[1]; String newObjItems=newObjJsonFound.split(colon,2)[1]; parsedResultMap.put(newObjName, newObjItems); jsonString=jsonString.replaceFirst(newObjJsonString, ""); }else{ break; } } } } return parsedResultMap; }catch(NullPointerException e){ return parsedResultMap; } } public static String fromJsonParserHelper(String jsonString, String regexString){ String umpleID = ""; String quo="\\\""; try{ Pattern umpleIDPattern=Pattern.compile(regexString); Matcher umpleIDMatcher=umpleIDPattern.matcher(jsonString); if(umpleIDMatcher.find()){ String umpleIDStringFound=umpleIDMatcher.group(0); String idString="\\\"\\d*\\\""; Pattern idPattern=Pattern.compile(idString); Matcher idMatcher=idPattern.matcher(umpleIDStringFound); if(idMatcher.find()){ umpleID=idMatcher.group(0).split(quo)[1]; } } return umpleID; } catch(NullPointerException e){ return umpleID; } } public static List<String> fromJsonParserList(String objListString){ List<String> objList=new ArrayList<String>(); try{ String objString="(?:(?=.*?\\{(?!.*?\\1)(.*\\}(?!.*\\2).*))(?=.*?\\}(?!.*?\\2)(.*)).)+?.*?(?=\\1)[^\\{]*(?=\\2$)"; Pattern objStringPattern=Pattern.compile(objString); Matcher objStringMatcher=objStringPattern.matcher(objListString); while(objStringMatcher.find()){ objList.add(objStringMatcher.group(0)); } return objList; }catch(NullPointerException e){ return objList; } } public static String fromJsonParserClassName(String objNameString){ String nextName=""; String quotes="\\\""; try{ String nextNameString="\\{\\\"[A-Z]\\w*\\\":"; Pattern nextNamePattern=Pattern.compile(nextNameString); Matcher nextNameMatcher=nextNamePattern.matcher(objNameString); if(nextNameMatcher.find()){ nextName=nextNameMatcher.group(0).split(quotes)[1]; } return nextName; }catch(NullPointerException e){ return nextName; } } } /*PLEASE DO NOT EDIT THIS CODE*/ /*This code was generated using the UMPLE 1.35.0.7523.c616a4dce modeling language!*/ package example; import java.util.HashSet; import java.util.Map; import java.util.HashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.ArrayList; import java.util.List; import java.sql.*; import java.lang.reflect.Constructor; // line 11 "../ToJsonComplexTest.ump" public class Person { //------------------------ // MEMBER VARIABLES //------------------------ //Person Attributes private int id; private String name; //------------------------ // CONSTRUCTOR //------------------------ public Person(int aId, String aName) { id = aId; name = aName; } //------------------------ // INTERFACE //------------------------ public boolean setId(int aId) { boolean wasSet = false; id = aId; wasSet = true; return wasSet; } public boolean setName(String aName) { boolean wasSet = false; name = aName; wasSet = true; return wasSet; } public int getId() { return id; } public String getName() { return name; } public void delete() {} public String toString() { return super.toString() + "["+ "id" + ":" + getId()+ "," + "name" + ":" + getName()+ "]"; } /* * Generate Json for this object and connected objects visited objects to enable avoidance of infinite loops * * @return a string in Json format of this object */ public String toJson() { HashSet<Object> visitedList = new HashSet<Object>(); StringBuilder toJsonOutput = new StringBuilder(); toJsonOutput.append("{\n"); this.toJsonHelper(toJsonOutput, visitedList,1,true); toJsonOutput.append("\n}"); return(toJsonOutput.toString()); } /* * Helper function to generate Json for this object and connected objects visited objects to enable avoidance of infinite loops * * @param toJsonOutput Output is aded to this as the network of objects is traversed * @param visitedList Every concrete object visited is added so we don't re-outpu * @param nestLevel As we output deeper objects, indent them more * @param atConcreteClass false when we are recursing to a superclass * so we get the superclass data * @return whether or not anything was output (so we can tell whether we need to output a comma) */ public boolean toJsonHelper(StringBuilder toJsonOutput, HashSet<Object> visitedList, int nestLevel, boolean atConcreteClass){ String indent = " ".repeat(nestLevel); boolean alreadyVisited = false; boolean haveOutputItem = false; if(atConcreteClass) { // This will not be true in a super call; output header toJsonOutput.append(indent+"\""+this.toString().split("@")[0]+ "\" : {\n"+indent+ " \"umpleObjectID\" : \""+System.identityHashCode(this)+"\""); // Check if we have already visited this object. If so we will not output details alreadyVisited = visitedList.contains(this); if(!alreadyVisited) { toJsonOutput.append(",\n"); visitedList.add(this); } } // There is no superclass of this class if(alreadyVisited) { toJsonOutput.append("\n"); } else { // Check if this class has a superclass. If it does, we make a call to output superclass content // This will keep calling super so the topmost attributes and associations appear first // When an object has not already been visited, output its details if(haveOutputItem){ //toJsonOutput.append(",\n"); } if(haveOutputItem){ toJsonOutput.append(",\n"); } toJsonOutput.append(indent); toJsonOutput.append(" \""); toJsonOutput.append("id"); toJsonOutput.append("\" : \""); String primValue_0=""+getId()+""; toJsonOutput.append(primValue_0.replace("\\","\\\\").replace("\"","\\\"")); toJsonOutput.append("\""); haveOutputItem=true; if(haveOutputItem){ toJsonOutput.append(",\n"); } toJsonOutput.append(indent); toJsonOutput.append(" \""); toJsonOutput.append("name"); toJsonOutput.append("\" : \""); String primValue_1=""+getName()+""; toJsonOutput.append(primValue_1.replace("\\","\\\\").replace("\"","\\\"")); toJsonOutput.append("\""); haveOutputItem=true; //haveOutputItem = false; //haveOutputItem = false; toJsonOutput.append(indent+" \n"); } // Finalize the output of the concrete class if(atConcreteClass) { if(!alreadyVisited) { toJsonOutput.append("\n"); } toJsonOutput.append(indent+"}"); } haveOutputItem = true; return haveOutputItem; } /* * Deserialize Json string to instantiate Objects from top-level class * * @param umpleObjectIDMap<String, Object> mapping parsed objectID (from Json string) with newly instantiated object's objectID * * @param String aJsonString is the string in json format that is to be processed and turned into an object * * @return newly instantiated Object */ public static Person fromJson(String aJsonString){ // process the input jsonString so that it can further processed using regex aJsonString=aJsonString.replace("\n","").replace(" ",""); // a map to store the umpleObjectID present in jsonString Map<String, Object> umpleObjectIDMap=new HashMap<>(); // instantiate a new object Person anObject = new Person(aJsonString, umpleObjectIDMap); return anObject; } /* * A new constructor specifically implemented if -s genJson is specified * * @param String aJsonString is the string in json format that is to be processed and turned into an object * * @param umpleObjectIDMap<String, Integer> mapping parsed objectID (from Json string) with newly instantiated object's objectID */ @SuppressWarnings("unchecked") public Person(String aJsonString, Map<String, Object> umpleObjectIDMap){ // Initialize a HashMap to store the parsed result // key is the attribute name present in the jsonString // value is the attribute value present in the jsonString boolean visitedSuperClass=false; HashMap<String,String> parsedResult = new HashMap<String,String>(); parsedResult = fromJsonParser(aJsonString); if(!parsedResult.isEmpty()){ boolean classExist; boolean classChildExist; String parsedClassName=parsedResult.get("className"); String childName=this.getClass().getSimpleName(); classExist="Person".equals(parsedClassName); classChildExist=childName.equals(parsedClassName); // if top-level class does not exist, throw exception if(!classExist&&!classChildExist){ throw new IllegalArgumentException("Top-level class \""+parsedClassName+"\" does not exist, please check the input json string"); } String umpleObjectId=parsedResult.get("umpleObjectID"); // Check if the object has already been visited and created //if((umpleObjectIDMap.get(umpleObjectId)==null)||visitedSuperClass){ try{ visitedSuperClass=false; // map the old objectID (in jsonString) with the newly created object's hashCode in umpleObjectIDMap umpleObjectIDMap.put(umpleObjectId,this); String jsonKey=""; jsonKey="id"; //more types should be considered here int valueInt = Integer.valueOf(parsedResult.get(jsonKey)); this.id=valueInt; jsonKey="name"; //more types should be considered here this.name=parsedResult.get(jsonKey); // below for-loop check the association class of the top level class }catch(Exception e){ } //} } } /* * A json parser to parse the input jsonString, if -s genJson is specified * * @param String aJsonString is the string in json format that is to be processed and turned into an object * * @ return HashMap<String,String> that stores paresed result, key is the attribute(or associations) of an object, value is the attribute value or association string */ public static HashMap<String,String> fromJsonParser(String jsonString){ HashMap<String,String> parsedResultMap = new HashMap<String,String>(); try{ //Below (String, Pattern, Matcher) are the regex strings and their patterns and matcher used to process a jsonString // topLevelString is the regex representing the topLevel class name String topLevelString = "\\{\\\"[A-Z]\\w*\\\":"; Pattern topLevelPattern = Pattern.compile(topLevelString); Matcher topLevelMatcher = topLevelPattern.matcher(jsonString); String quotes="\\\""; String colon="\\:"; String colonSquareBracket="\\:\\["; if(topLevelMatcher.find()){ //actual string that represent the topLevel className String topLevelStringFound=topLevelMatcher.group(0); String className=topLevelStringFound.split(quotes)[1]; parsedResultMap.put("className", className); jsonString=jsonString.split(topLevelString,2)[1]; //objIDString is the regex representing umpleObjectID that could be found in jsonString String objIDString = "\"umpleObjectID\"\\:\"[0-9]*\","; Pattern objIDPattern = Pattern.compile(objIDString); Matcher objIDMatcher = objIDPattern.matcher(jsonString); if(objIDMatcher.find()){ String objIDFound=objIDMatcher.group(0); parsedResultMap.put("umpleObjectID", objIDFound.split(colon)[1].split(quotes)[1]); jsonString=jsonString.replaceFirst(objIDFound,""); } String timeString="\\\"\\w*\\\"\\:\\\"\\d{2}:\\d{2}\\:\\d{2}\\\""; Pattern timeStringPattern=Pattern.compile(timeString); Matcher timeStringPatternMatcher=timeStringPattern.matcher(jsonString); if(timeStringPatternMatcher.find()){ String timeStringFound=timeStringPatternMatcher.group(0); parsedResultMap.put(timeStringFound.split(colon,2)[0].split(quotes)[1], timeStringFound.split(colon,2)[1].split(quotes)[1]); } // pairString is the regex for an object's attribute and attribute value, the string parsed will be in key-value formate String pairString = "(\\\"(?!umpleObjectID)[^\\\"]+)\\\":\\\"((?:\\\\\\\"|[^\\\"])*)"; Pattern pairPattern=Pattern.compile(pairString); Matcher pairMatcher=pairPattern.matcher(jsonString); String associationString="(?=\\\"\\w*\\\"\\:\\[\\{)(?:(?=.*?\\[\\{(?!.*?\\1)(.*\\}\\](?!.*\\2).*))(?=.*?\\}\\](?!.*?\\2)(.*)).)+?.*?(?=\\1)[^\\[]*(?=\\2$)"; Pattern associationPattern=Pattern.compile(associationString); String newObjJsonString="(?=\\,\\\"\\w*\\\"\\:\\{)(?:(?=.*?\\{\\\"(?!.*?\\1)(.*\\}(?!.*\\2).*))(?=.*?\\}(?!.*?\\2)(.*)).)+?.*?(?=\\1)[^\\{]*(?=\\2$)"; Pattern newObjJsonPattern=Pattern.compile(newObjJsonString); String quoteColonQuote="\\\"\\:\\\""; //Keep on parsing the attribute's key-value pair, //until a List (multi-associations) pattern or a newObject parttern (single association) is found while(pairMatcher.find()){ String pairStringFound=pairMatcher.group(0); if(parsedResultMap.get(pairStringFound.split(colon)[0].split(quotes)[1])==null){ String keyPair=pairStringFound.split(colon)[0].split(quotes)[1]; String valuePair=pairStringFound.split(quoteColonQuote,2)[1]; keyPair=keyPair.replace("\\\\","\\").replace("\\\"","\""); valuePair=valuePair.replace("\\\\","\\").replace("\\\"","\""); parsedResultMap.put(keyPair,valuePair); jsonString=jsonString.replaceFirst(pairString, ""); } int lastIndex = 0; while (lastIndex<jsonString.length()){ String remainingJson=jsonString.substring(lastIndex); Matcher associationMatcher=associationPattern.matcher(jsonString); Matcher newObjJsonMatcher=newObjJsonPattern.matcher(jsonString); boolean assoFound=associationMatcher.find(); boolean newObjFound=newObjJsonMatcher.find(); if (assoFound&&(!newObjFound||associationMatcher.start()<newObjJsonMatcher.start())){ String assoStringFound=associationMatcher.group(0); String associationName=assoStringFound.split(colon,2)[0].split(quotes)[1];; String associationItems=assoStringFound.split(colonSquareBracket,2)[1]; parsedResultMap.put(associationName, associationItems); jsonString=jsonString.replaceFirst(associationString, ""); } else if (newObjFound){ String newObjJsonFound=newObjJsonMatcher.group(0); String newObjName=newObjJsonFound.split(colon,2)[0].split(quotes)[1]; String newObjItems=newObjJsonFound.split(colon,2)[1]; parsedResultMap.put(newObjName, newObjItems); jsonString=jsonString.replaceFirst(newObjJsonString, ""); }else{ break; } } } } return parsedResultMap; }catch(NullPointerException e){ return parsedResultMap; } } public static String fromJsonParserHelper(String jsonString, String regexString){ String umpleID = ""; String quo="\\\""; try{ Pattern umpleIDPattern=Pattern.compile(regexString); Matcher umpleIDMatcher=umpleIDPattern.matcher(jsonString); if(umpleIDMatcher.find()){ String umpleIDStringFound=umpleIDMatcher.group(0); String idString="\\\"\\d*\\\""; Pattern idPattern=Pattern.compile(idString); Matcher idMatcher=idPattern.matcher(umpleIDStringFound); if(idMatcher.find()){ umpleID=idMatcher.group(0).split(quo)[1]; } } return umpleID; } catch(NullPointerException e){ return umpleID; } } public static List<String> fromJsonParserList(String objListString){ List<String> objList=new ArrayList<String>(); try{ String objString="(?:(?=.*?\\{(?!.*?\\1)(.*\\}(?!.*\\2).*))(?=.*?\\}(?!.*?\\2)(.*)).)+?.*?(?=\\1)[^\\{]*(?=\\2$)"; Pattern objStringPattern=Pattern.compile(objString); Matcher objStringMatcher=objStringPattern.matcher(objListString); while(objStringMatcher.find()){ objList.add(objStringMatcher.group(0)); } return objList; }catch(NullPointerException e){ return objList; } } public static String fromJsonParserClassName(String objNameString){ String nextName=""; String quotes="\\\""; try{ String nextNameString="\\{\\\"[A-Z]\\w*\\\":"; Pattern nextNamePattern=Pattern.compile(nextNameString); Matcher nextNameMatcher=nextNamePattern.matcher(objNameString); if(nextNameMatcher.find()){ nextName=nextNameMatcher.group(0).split(quotes)[1]; } return nextName; }catch(NullPointerException e){ return nextName; } } } /*PLEASE DO NOT EDIT THIS CODE*/ /*This code was generated using the UMPLE 1.35.0.7523.c616a4dce modeling language!*/ package example; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.sql.*; import java.lang.reflect.Constructor; // line 21 "../ToJsonComplexTest.ump" public class PartTimeStudent extends Student { //------------------------ // MEMBER VARIABLES //------------------------ //PartTimeStudent Attributes private boolean isExemptFromFees; //------------------------ // CONSTRUCTOR //------------------------ public PartTimeStudent(int aId, String aName, float aTuitionPaid, University aUniversity, boolean aIsExemptFromFees) { super(aId, aName, aTuitionPaid, aUniversity); isExemptFromFees = aIsExemptFromFees; } //------------------------ // INTERFACE //------------------------ public boolean setIsExemptFromFees(boolean aIsExemptFromFees) { boolean wasSet = false; isExemptFromFees = aIsExemptFromFees; wasSet = true; return wasSet; } public boolean getIsExemptFromFees() { return isExemptFromFees; } /* Code from template attribute_IsBoolean */ public boolean isIsExemptFromFees() { return isExemptFromFees; } public void delete() { super.delete(); } public String toString() { return super.toString() + "["+ "isExemptFromFees" + ":" + getIsExemptFromFees()+ "]"; } /* * Generate Json for this object and connected objects visited objects to enable avoidance of infinite loops * * @return a string in Json format of this object */ public String toJson() { HashSet<Object> visitedList = new HashSet<Object>(); StringBuilder toJsonOutput = new StringBuilder(); toJsonOutput.append("{\n"); this.toJsonHelper(toJsonOutput, visitedList,1,true); toJsonOutput.append("\n}"); return(toJsonOutput.toString()); } /* * Helper function to generate Json for this object and connected objects visited objects to enable avoidance of infinite loops * * @param toJsonOutput Output is aded to this as the network of objects is traversed * @param visitedList Every concrete object visited is added so we don't re-outpu * @param nestLevel As we output deeper objects, indent them more * @param atConcreteClass false when we are recursing to a superclass * so we get the superclass data * @return whether or not anything was output (so we can tell whether we need to output a comma) */ public boolean toJsonHelper(StringBuilder toJsonOutput, HashSet<Object> visitedList, int nestLevel, boolean atConcreteClass){ String indent = " ".repeat(nestLevel); boolean alreadyVisited = false; boolean haveOutputItem = false; if(atConcreteClass) { // This will not be true in a super call; output header toJsonOutput.append(indent+"\""+this.toString().split("@")[0]+ "\" : {\n"+indent+ " \"umpleObjectID\" : \""+System.identityHashCode(this)+"\""); // Check if we have already visited this object. If so we will not output details alreadyVisited = visitedList.contains(this); if(!alreadyVisited) { toJsonOutput.append(",\n"); visitedList.add(this); } } // There is no superclass of this class if(alreadyVisited) { toJsonOutput.append("\n"); } else { // Check if this class has a superclass. If it does, we make a call to output superclass content // This will keep calling super so the topmost attributes and associations appear first haveOutputItem = super.toJsonHelper(toJsonOutput, visitedList, nestLevel, false); // When an object has not already been visited, output its details if(haveOutputItem){ //toJsonOutput.append(",\n"); } if(haveOutputItem){ toJsonOutput.append(",\n"); } toJsonOutput.append(indent); toJsonOutput.append(" \""); toJsonOutput.append("isExemptFromFees"); toJsonOutput.append("\" : \""); String primValue_0=""+getIsExemptFromFees()+""; toJsonOutput.append(primValue_0.replace("\\","\\\\").replace("\"","\\\"")); toJsonOutput.append("\""); haveOutputItem=true; //haveOutputItem = false; //haveOutputItem = false; toJsonOutput.append(indent+" \n"); } // Finalize the output of the concrete class if(atConcreteClass) { if(!alreadyVisited) { toJsonOutput.append("\n"); } toJsonOutput.append(indent+"}"); } haveOutputItem = true; return haveOutputItem; } /* * Deserialize Json string to instantiate Objects from top-level class * * @param umpleObjectIDMap<String, Object> mapping parsed objectID (from Json string) with newly instantiated object's objectID * * @param String aJsonString is the string in json format that is to be processed and turned into an object * * @return newly instantiated Object */ public static PartTimeStudent fromJson(String aJsonString){ // process the input jsonString so that it can further processed using regex aJsonString=aJsonString.replace("\n","").replace(" ",""); // a map to store the umpleObjectID present in jsonString Map<String, Object> umpleObjectIDMap=new HashMap<>(); // instantiate a new object PartTimeStudent anObject = new PartTimeStudent(aJsonString, umpleObjectIDMap); return anObject; } /* * A new constructor specifically implemented if -s genJson is specified * * @param String aJsonString is the string in json format that is to be processed and turned into an object * * @param umpleObjectIDMap<String, Integer> mapping parsed objectID (from Json string) with newly instantiated object's objectID */ @SuppressWarnings("unchecked") public PartTimeStudent(String aJsonString, Map<String, Object> umpleObjectIDMap){ // Initialize a HashMap to store the parsed result // key is the attribute name present in the jsonString // value is the attribute value present in the jsonString super(aJsonString,umpleObjectIDMap); boolean visitedSuperClass=true; HashMap<String,String> parsedResult = new HashMap<String,String>(); parsedResult = fromJsonParser(aJsonString); if(!parsedResult.isEmpty()){ boolean classExist; boolean classChildExist; String parsedClassName=parsedResult.get("className"); String childName=this.getClass().getSimpleName(); classExist="PartTimeStudent".equals(parsedClassName); classChildExist=childName.equals(parsedClassName); // if top-level class does not exist, throw exception if(!classExist&&!classChildExist){ throw new IllegalArgumentException("Top-level class \""+parsedClassName+"\" does not exist, please check the input json string"); } String umpleObjectId=parsedResult.get("umpleObjectID"); // Check if the object has already been visited and created //if((umpleObjectIDMap.get(umpleObjectId)==null)||visitedSuperClass){ try{ visitedSuperClass=false; // map the old objectID (in jsonString) with the newly created object's hashCode in umpleObjectIDMap umpleObjectIDMap.put(umpleObjectId,this); String jsonKey=""; jsonKey="isExemptFromFees"; //more types should be considered here boolean valueBool=Boolean.parseBoolean(parsedResult.get(jsonKey)); this.isExemptFromFees=valueBool; // below for-loop check the association class of the top level class }catch(Exception e){ } //} } } /* * A json parser to parse the input jsonString, if -s genJson is specified * * @param String aJsonString is the string in json format that is to be processed and turned into an object * * @ return HashMap<String,String> that stores paresed result, key is the attribute(or associations) of an object, value is the attribute value or association string */ public static HashMap<String,String> fromJsonParser(String jsonString){ HashMap<String,String> parsedResultMap = new HashMap<String,String>(); try{ //Below (String, Pattern, Matcher) are the regex strings and their patterns and matcher used to process a jsonString // topLevelString is the regex representing the topLevel class name String topLevelString = "\\{\\\"[A-Z]\\w*\\\":"; Pattern topLevelPattern = Pattern.compile(topLevelString); Matcher topLevelMatcher = topLevelPattern.matcher(jsonString); String quotes="\\\""; String colon="\\:"; String colonSquareBracket="\\:\\["; if(topLevelMatcher.find()){ //actual string that represent the topLevel className String topLevelStringFound=topLevelMatcher.group(0); String className=topLevelStringFound.split(quotes)[1]; parsedResultMap.put("className", className); jsonString=jsonString.split(topLevelString,2)[1]; //objIDString is the regex representing umpleObjectID that could be found in jsonString String objIDString = "\"umpleObjectID\"\\:\"[0-9]*\","; Pattern objIDPattern = Pattern.compile(objIDString); Matcher objIDMatcher = objIDPattern.matcher(jsonString); if(objIDMatcher.find()){ String objIDFound=objIDMatcher.group(0); parsedResultMap.put("umpleObjectID", objIDFound.split(colon)[1].split(quotes)[1]); jsonString=jsonString.replaceFirst(objIDFound,""); } String timeString="\\\"\\w*\\\"\\:\\\"\\d{2}:\\d{2}\\:\\d{2}\\\""; Pattern timeStringPattern=Pattern.compile(timeString); Matcher timeStringPatternMatcher=timeStringPattern.matcher(jsonString); if(timeStringPatternMatcher.find()){ String timeStringFound=timeStringPatternMatcher.group(0); parsedResultMap.put(timeStringFound.split(colon,2)[0].split(quotes)[1], timeStringFound.split(colon,2)[1].split(quotes)[1]); } // pairString is the regex for an object's attribute and attribute value, the string parsed will be in key-value formate String pairString = "(\\\"(?!umpleObjectID)[^\\\"]+)\\\":\\\"((?:\\\\\\\"|[^\\\"])*)"; Pattern pairPattern=Pattern.compile(pairString); Matcher pairMatcher=pairPattern.matcher(jsonString); String associationString="(?=\\\"\\w*\\\"\\:\\[\\{)(?:(?=.*?\\[\\{(?!.*?\\1)(.*\\}\\](?!.*\\2).*))(?=.*?\\}\\](?!.*?\\2)(.*)).)+?.*?(?=\\1)[^\\[]*(?=\\2$)"; Pattern associationPattern=Pattern.compile(associationString); String newObjJsonString="(?=\\,\\\"\\w*\\\"\\:\\{)(?:(?=.*?\\{\\\"(?!.*?\\1)(.*\\}(?!.*\\2).*))(?=.*?\\}(?!.*?\\2)(.*)).)+?.*?(?=\\1)[^\\{]*(?=\\2$)"; Pattern newObjJsonPattern=Pattern.compile(newObjJsonString); String quoteColonQuote="\\\"\\:\\\""; //Keep on parsing the attribute's key-value pair, //until a List (multi-associations) pattern or a newObject parttern (single association) is found while(pairMatcher.find()){ String pairStringFound=pairMatcher.group(0); if(parsedResultMap.get(pairStringFound.split(colon)[0].split(quotes)[1])==null){ String keyPair=pairStringFound.split(colon)[0].split(quotes)[1]; String valuePair=pairStringFound.split(quoteColonQuote,2)[1]; keyPair=keyPair.replace("\\\\","\\").replace("\\\"","\""); valuePair=valuePair.replace("\\\\","\\").replace("\\\"","\""); parsedResultMap.put(keyPair,valuePair); jsonString=jsonString.replaceFirst(pairString, ""); } int lastIndex = 0; while (lastIndex<jsonString.length()){ String remainingJson=jsonString.substring(lastIndex); Matcher associationMatcher=associationPattern.matcher(jsonString); Matcher newObjJsonMatcher=newObjJsonPattern.matcher(jsonString); boolean assoFound=associationMatcher.find(); boolean newObjFound=newObjJsonMatcher.find(); if (assoFound&&(!newObjFound||associationMatcher.start()<newObjJsonMatcher.start())){ String assoStringFound=associationMatcher.group(0); String associationName=assoStringFound.split(colon,2)[0].split(quotes)[1];; String associationItems=assoStringFound.split(colonSquareBracket,2)[1]; parsedResultMap.put(associationName, associationItems); jsonString=jsonString.replaceFirst(associationString, ""); } else if (newObjFound){ String newObjJsonFound=newObjJsonMatcher.group(0); String newObjName=newObjJsonFound.split(colon,2)[0].split(quotes)[1]; String newObjItems=newObjJsonFound.split(colon,2)[1]; parsedResultMap.put(newObjName, newObjItems); jsonString=jsonString.replaceFirst(newObjJsonString, ""); }else{ break; } } } } return parsedResultMap; }catch(NullPointerException e){ return parsedResultMap; } } public static String fromJsonParserHelper(String jsonString, String regexString){ String umpleID = ""; String quo="\\\""; try{ Pattern umpleIDPattern=Pattern.compile(regexString); Matcher umpleIDMatcher=umpleIDPattern.matcher(jsonString); if(umpleIDMatcher.find()){ String umpleIDStringFound=umpleIDMatcher.group(0); String idString="\\\"\\d*\\\""; Pattern idPattern=Pattern.compile(idString); Matcher idMatcher=idPattern.matcher(umpleIDStringFound); if(idMatcher.find()){ umpleID=idMatcher.group(0).split(quo)[1]; } } return umpleID; } catch(NullPointerException e){ return umpleID; } } public static List<String> fromJsonParserList(String objListString){ List<String> objList=new ArrayList<String>(); try{ String objString="(?:(?=.*?\\{(?!.*?\\1)(.*\\}(?!.*\\2).*))(?=.*?\\}(?!.*?\\2)(.*)).)+?.*?(?=\\1)[^\\{]*(?=\\2$)"; Pattern objStringPattern=Pattern.compile(objString); Matcher objStringMatcher=objStringPattern.matcher(objListString); while(objStringMatcher.find()){ objList.add(objStringMatcher.group(0)); } return objList; }catch(NullPointerException e){ return objList; } } public static String fromJsonParserClassName(String objNameString){ String nextName=""; String quotes="\\\""; try{ String nextNameString="\\{\\\"[A-Z]\\w*\\\":"; Pattern nextNamePattern=Pattern.compile(nextNameString); Matcher nextNameMatcher=nextNamePattern.matcher(objNameString); if(nextNameMatcher.find()){ nextName=nextNameMatcher.group(0).split(quotes)[1]; } return nextName; }catch(NullPointerException e){ return nextName; } } }