/*PLEASE DO NOT EDIT THIS CODE*/
/*This code was generated using the UMPLE 1.38.0.8942.247e17422 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 "../ToJsonTest_1.ump"
public class Person
{
//------------------------
// MEMBER VARIABLES
//------------------------
//Person Attributes
private String name;
//Person Associations
private List<Address> addresses;
//------------------------
// CONSTRUCTOR
//------------------------
public Person(String aName)
{
name = aName;
addresses = new ArrayList<Address>();
}
//------------------------
// INTERFACE
//------------------------
public boolean setName(String aName)
{
boolean wasSet = false;
name = aName;
wasSet = true;
return wasSet;
}
public String getName()
{
return name;
}
/* Code from template association_GetMany */
public Address getAddress(int index)
{
Address aAddress = addresses.get(index);
return aAddress;
}
public List<Address> getAddresses()
{
List<Address> newAddresses = Collections.unmodifiableList(addresses);
return newAddresses;
}
public int numberOfAddresses()
{
int number = addresses.size();
return number;
}
public boolean hasAddresses()
{
boolean has = addresses.size() > 0;
return has;
}
public int indexOfAddress(Address aAddress)
{
int index = addresses.indexOf(aAddress);
return index;
}
/* Code from template association_MinimumNumberOfMethod */
public static int minimumNumberOfAddresses()
{
return 0;
}
/* Code from template association_AddManyToOne */
public Address addAddress(String aStreet)
{
return new Address(aStreet, this);
}
public boolean addAddress(Address aAddress)
{
boolean wasAdded = false;
if (addresses.contains(aAddress)) { return false; }
Person existingPerson = aAddress.getPerson();
boolean isNewPerson = existingPerson != null && !this.equals(existingPerson);
if (isNewPerson)
{
aAddress.setPerson(this);
}
else
{
addresses.add(aAddress);
}
wasAdded = true;
return wasAdded;
}
public boolean removeAddress(Address aAddress)
{
boolean wasRemoved = false;
//Unable to remove aAddress, as it must always have a person
if (!this.equals(aAddress.getPerson()))
{
addresses.remove(aAddress);
wasRemoved = true;
}
return wasRemoved;
}
/* Code from template association_AddIndexControlFunctions */
public boolean addAddressAt(Address aAddress, int index)
{
boolean wasAdded = false;
if(addAddress(aAddress))
{
if(index < 0 ) { index = 0; }
if(index > numberOfAddresses()) { index = numberOfAddresses() - 1; }
addresses.remove(aAddress);
addresses.add(index, aAddress);
wasAdded = true;
}
return wasAdded;
}
public boolean addOrMoveAddressAt(Address aAddress, int index)
{
boolean wasAdded = false;
if(addresses.contains(aAddress))
{
if(index < 0 ) { index = 0; }
if(index > numberOfAddresses()) { index = numberOfAddresses() - 1; }
addresses.remove(aAddress);
addresses.add(index, aAddress);
wasAdded = true;
}
else
{
wasAdded = addAddressAt(aAddress, index);
}
return wasAdded;
}
public void delete()
{
for(int i=addresses.size(); i > 0; i--)
{
Address aAddress = addresses.get(i - 1);
aAddress.delete();
}
}
public String toString()
{
return super.toString() + "["+
"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("name");
toJsonOutput.append("\" : \"");
String primValue_0=""+getName()+"";
toJsonOutput.append(primValue_0.replace("\\","\\\\").replace("\"","\\\""));
toJsonOutput.append("\"");
haveOutputItem=true;
//haveOutputItem = false;
//haveOutputItem = false;
if(haveOutputItem) {
toJsonOutput.append(",\n");
}
toJsonOutput.append(indent);
toJsonOutput.append(" \"");
toJsonOutput.append("addresses");
toJsonOutput.append("\"");
toJsonOutput.append(" : [");
toJsonOutput.append("\n");
haveOutputItem = false;
try{
for (Address anItem_0 :getAddresses()){
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 Person fromJson(String aJsonString){
// the parser below reads json with nothing between its tokens, so remove every whitespace character json allows there
aJsonString=aJsonString.replace("\n","").replace("\r","").replace("\t","").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="name";
//more types should be considered here
this.name=parsedResult.get(jsonKey);
// below for-loop check the association class of the top level class
jsonKey="addresses";
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);
addresses=new ArrayList<Address>();
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);
addresses.add((Address)objectNew_0);
}
else{
addresses.add((Address)umpleObjectIDMap.get(newUmpleID_0));
}
}
}catch(java.lang.reflect.InvocationTargetException e){
// an associated object with an unknown state must fail the load, as the top-level object does
if(e.getCause() instanceof IllegalArgumentException){
throw (IllegalArgumentException)e.getCause();
}
}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="\\\"";
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);
// The object's own "key":value pairs follow, a value being a "string", a [list] or an {object}.
// Each value is skipped whole, so the pairs of an associated object are left for that object to read
int pairStart=topLevelMatcher.end()+1;
while(pairStart<jsonString.length()&&jsonString.charAt(pairStart)=='"'){
int keyEnd=fromJsonParserValueEnd(jsonString,pairStart);
// without the colon there is no telling which value is the key's, so read no further
if(keyEnd<0||!jsonString.startsWith(":",keyEnd)){
break;
}
int valueEnd=fromJsonParserValueEnd(jsonString,keyEnd+1);
if(valueEnd<0){
break;
}
String key=jsonString.substring(pairStart+1,keyEnd-1);
String value=jsonString.substring(keyEnd+1,valueEnd);
// The class name and object id come first and win over an attribute named like them.
// toJson quotes every attribute and state, so a bare null, boolean or number is left unread, as it always was
if(value.startsWith("\"")){
parsedResultMap.putIfAbsent(key,value.substring(1,value.length()-1).replace("\\\\","\\").replace("\\\"","\""));
}
else if(value.startsWith("[")||value.startsWith("{")){
parsedResultMap.putIfAbsent(key,value);
}
// skip the comma, and the extra one left by a superclass with nothing to output
pairStart=valueEnd;
while(pairStart<jsonString.length()&&jsonString.charAt(pairStart)==','){
pairStart++;
}
}
}
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{
// objListString is a [list]; each {object} in it is taken whole with the objects nested in it,
// and any other element, which toJson does not write, is skipped
int itemStart=1;
while(itemStart<objListString.length()&&objListString.charAt(itemStart)!=']'){
int itemEnd=fromJsonParserValueEnd(objListString,itemStart);
if(itemEnd<0){
break;
}
if(objListString.charAt(itemStart)=='{'){
objList.add(objListString.substring(itemStart,itemEnd));
}
itemStart=itemEnd+1;
}
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;
}
}
/*
* Returns the index just after the json value that starts at index start,
* or -1 if there is none there or it is cut short.
* A "string", [list] or {object} ends where it closes; brackets and escaped quotes inside a string are text.
* A bare null, boolean or number ends at the next comma or closing bracket
*/
private static int fromJsonParserValueEnd(String jsonString, int start){
if(start>=jsonString.length()){
return -1;
}
if("\"[{".indexOf(jsonString.charAt(start))<0){
int end=start;
while(end<jsonString.length()&&",}]".indexOf(jsonString.charAt(end))<0){
end++;
}
return end>start&&end<jsonString.length()?end:-1;
}
int depth=0;
boolean inString=false;
for(int i=start;i<jsonString.length();i++){
char c=jsonString.charAt(i);
if(inString){
if(c=='\\'){
i++;
}
else if(c=='"'){
inString=false;
}
}
else if(c=='"'){
inString=true;
}
else if(c=='{'||c=='['){
depth++;
}
else if(c=='}'||c==']'){
depth--;
}
if(!inString&&depth==0){
return i+1;
}
}
return -1;
}
}
/*PLEASE DO NOT EDIT THIS CODE*/
/*This code was generated using the UMPLE 1.38.0.8942.247e17422 modeling language!*/
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 3 "ToJsonTest_3.ump"
public class Player
{
//------------------------
// MEMBER VARIABLES
//------------------------
//Player Attributes
private String name;
//Player State Machines
public enum Status { Off, On }
public enum StatusOn { Null, Idle, Playing, H }
private Status status;
private StatusOn statusOn;
private StatusOn statusOnH;
public enum Mode { Active, Stopped }
public enum ModeActive { Null, Waiting, Busy, HStar }
private Mode mode;
private ModeActive modeActive;
private ModeActive modeActiveHStar;
public enum Unused { }
private Unused unused;
//------------------------
// CONSTRUCTOR
//------------------------
public Player(String aName)
{
name = aName;
setStatusOn(StatusOn.Null);
statusOnH = StatusOn.Idle;
setStatus(Status.Off);
setModeActive(ModeActive.Null);
modeActiveHStar = ModeActive.Waiting;
setMode(Mode.Active);
}
//------------------------
// INTERFACE
//------------------------
public boolean setName(String aName)
{
boolean wasSet = false;
name = aName;
wasSet = true;
return wasSet;
}
public String getName()
{
return name;
}
public String getStatusFullName()
{
String answer = status.toString();
if (statusOn != StatusOn.Null) { answer += "." + statusOn.toString(); }
return answer;
}
public String getModeFullName()
{
String answer = mode.toString();
if (modeActive != ModeActive.Null) { answer += "." + modeActive.toString(); }
return answer;
}
public String getUnusedFullName()
{
String answer = unused.toString();
return answer;
}
public Status getStatus()
{
return status;
}
public Mode getMode()
{
return mode;
}
public Unused getUnused()
{
return unused;
}
public StatusOn getStatusOn()
{
return statusOn;
}
public ModeActive getModeActive()
{
return modeActive;
}
public boolean turnOn()
{
boolean wasEventProcessed = false;
Status aStatus = status;
switch (aStatus)
{
case Off:
setStatus(Status.On);
wasEventProcessed = true;
break;
default:
// Other states do respond to this event
}
return wasEventProcessed;
}
public boolean resume()
{
boolean wasEventProcessed = false;
Status aStatus = status;
switch (aStatus)
{
case Off:
setStatusOn(statusOnH);
wasEventProcessed = true;
break;
default:
// Other states do respond to this event
}
return wasEventProcessed;
}
public boolean turnOff()
{
boolean wasEventProcessed = false;
Status aStatus = status;
switch (aStatus)
{
case On:
exitStatus();
setStatus(Status.Off);
wasEventProcessed = true;
break;
default:
// Other states do respond to this event
}
return wasEventProcessed;
}
public boolean stop()
{
boolean wasEventProcessed = false;
Mode aMode = mode;
switch (aMode)
{
case Active:
exitMode();
setMode(Mode.Stopped);
wasEventProcessed = true;
break;
default:
// Other states do respond to this event
}
return wasEventProcessed;
}
public boolean restart()
{
boolean wasEventProcessed = false;
Mode aMode = mode;
switch (aMode)
{
case Stopped:
setModeActive(ModeActive.HStar);
wasEventProcessed = true;
break;
default:
// Other states do respond to this event
}
return wasEventProcessed;
}
public boolean play()
{
boolean wasEventProcessed = false;
StatusOn aStatusOn = statusOn;
if (statusOn != StatusOn.Null){statusOnH = statusOn;}
switch (aStatusOn)
{
case Idle:
exitStatusOn();
setStatusOn(StatusOn.Playing);
wasEventProcessed = true;
break;
default:
// Other states do respond to this event
}
return wasEventProcessed;
}
public boolean work()
{
boolean wasEventProcessed = false;
ModeActive aModeActive = modeActive;
if (modeActive != ModeActive.Null){modeActiveHStar = modeActive;}
switch (aModeActive)
{
case Waiting:
exitModeActive();
setModeActive(ModeActive.Busy);
wasEventProcessed = true;
break;
default:
// Other states do respond to this event
}
return wasEventProcessed;
}
private void exitStatus()
{
switch(status)
{
case On:
exitStatusOn();
break;
}
}
private void setStatus(Status aStatus)
{
status = aStatus;
// entry actions and do activities
switch(status)
{
case On:
if (statusOn == StatusOn.Null) { setStatusOn(StatusOn.Idle); }
break;
}
}
private void exitMode()
{
switch(mode)
{
case Active:
exitModeActive();
break;
}
}
private void setMode(Mode aMode)
{
mode = aMode;
// entry actions and do activities
switch(mode)
{
case Active:
if (modeActive == ModeActive.Null) { setModeActive(ModeActive.Waiting); }
break;
}
}
private void exitStatusOn()
{
switch(statusOn)
{
case Idle:
setStatusOn(StatusOn.Null);
break;
case Playing:
setStatusOn(StatusOn.Null);
break;
case H:
setStatusOn(StatusOn.Null);
break;
}
}
private void setStatusOn(StatusOn aStatusOn)
{
statusOn = aStatusOn;
if (status != Status.On && aStatusOn != StatusOn.Null) { setStatus(Status.On); }
}
private void exitModeActive()
{
switch(modeActive)
{
case Waiting:
setModeActive(ModeActive.Null);
break;
case Busy:
setModeActive(ModeActive.Null);
break;
case HStar:
setModeActive(ModeActive.Null);
break;
}
}
private void setModeActive(ModeActive aModeActive)
{
modeActive = aModeActive;
if (mode != Mode.Active && aModeActive != ModeActive.Null) { setMode(Mode.Active); }
if (aModeActive == ModeActive.HStar) { modeActive = modeActiveHStar;}
}
public void delete()
{}
public String toString()
{
return super.toString() + "["+
"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("name");
toJsonOutput.append("\" : \"");
String primValue_0=""+getName()+"";
toJsonOutput.append(primValue_0.replace("\\","\\\\").replace("\"","\\\""));
toJsonOutput.append("\"");
haveOutputItem=true;
//haveOutputItem = false;
//haveOutputItem = false;
if(haveOutputItem){
toJsonOutput.append(",\n");
}
toJsonOutput.append(indent+" \"status\" : \""+this.status+"\"");
haveOutputItem=true;
if(haveOutputItem){
toJsonOutput.append(",\n");
}
toJsonOutput.append(indent+" \"statusOn\" : \""+this.statusOn+"\"");
haveOutputItem=true;
if(haveOutputItem){
toJsonOutput.append(",\n");
}
toJsonOutput.append(indent+" \"mode\" : \""+this.mode+"\"");
haveOutputItem=true;
if(haveOutputItem){
toJsonOutput.append(",\n");
}
toJsonOutput.append(indent+" \"modeActive\" : \""+this.modeActive+"\"");
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 Player fromJson(String aJsonString){
// the parser below reads json with nothing between its tokens, so remove every whitespace character json allows there
aJsonString=aJsonString.replace("\n","").replace("\r","").replace("\t","").replace(" ","");
// a map to store the umpleObjectID present in jsonString
Map<String, Object> umpleObjectIDMap=new HashMap<>();
// instantiate a new object
Player anObject = new Player(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 Player(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="Player".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");
// Restore the current state of each state machine; a missing one gets its start state
this.status=parsedResult.containsKey("status")?Status.valueOf(parsedResult.get("status")):Status.Off;
this.statusOn=parsedResult.containsKey("statusOn")?StatusOn.valueOf(parsedResult.get("statusOn")):StatusOn.Null;
this.statusOnH=StatusOn.Idle;
this.mode=parsedResult.containsKey("mode")?Mode.valueOf(parsedResult.get("mode")):Mode.Active;
this.modeActive=parsedResult.containsKey("modeActive")?ModeActive.valueOf(parsedResult.get("modeActive")):ModeActive.Waiting;
this.modeActiveHStar=ModeActive.Waiting;
// 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);
// 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="\\\"";
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);
// The object's own "key":value pairs follow, a value being a "string", a [list] or an {object}.
// Each value is skipped whole, so the pairs of an associated object are left for that object to read
int pairStart=topLevelMatcher.end()+1;
while(pairStart<jsonString.length()&&jsonString.charAt(pairStart)=='"'){
int keyEnd=fromJsonParserValueEnd(jsonString,pairStart);
// without the colon there is no telling which value is the key's, so read no further
if(keyEnd<0||!jsonString.startsWith(":",keyEnd)){
break;
}
int valueEnd=fromJsonParserValueEnd(jsonString,keyEnd+1);
if(valueEnd<0){
break;
}
String key=jsonString.substring(pairStart+1,keyEnd-1);
String value=jsonString.substring(keyEnd+1,valueEnd);
// The class name and object id come first and win over an attribute named like them.
// toJson quotes every attribute and state, so a bare null, boolean or number is left unread, as it always was
if(value.startsWith("\"")){
parsedResultMap.putIfAbsent(key,value.substring(1,value.length()-1).replace("\\\\","\\").replace("\\\"","\""));
}
else if(value.startsWith("[")||value.startsWith("{")){
parsedResultMap.putIfAbsent(key,value);
}
// skip the comma, and the extra one left by a superclass with nothing to output
pairStart=valueEnd;
while(pairStart<jsonString.length()&&jsonString.charAt(pairStart)==','){
pairStart++;
}
}
}
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{
// objListString is a [list]; each {object} in it is taken whole with the objects nested in it,
// and any other element, which toJson does not write, is skipped
int itemStart=1;
while(itemStart<objListString.length()&&objListString.charAt(itemStart)!=']'){
int itemEnd=fromJsonParserValueEnd(objListString,itemStart);
if(itemEnd<0){
break;
}
if(objListString.charAt(itemStart)=='{'){
objList.add(objListString.substring(itemStart,itemEnd));
}
itemStart=itemEnd+1;
}
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;
}
}
/*
* Returns the index just after the json value that starts at index start,
* or -1 if there is none there or it is cut short.
* A "string", [list] or {object} ends where it closes; brackets and escaped quotes inside a string are text.
* A bare null, boolean or number ends at the next comma or closing bracket
*/
private static int fromJsonParserValueEnd(String jsonString, int start){
if(start>=jsonString.length()){
return -1;
}
if("\"[{".indexOf(jsonString.charAt(start))<0){
int end=start;
while(end<jsonString.length()&&",}]".indexOf(jsonString.charAt(end))<0){
end++;
}
return end>start&&end<jsonString.length()?end:-1;
}
int depth=0;
boolean inString=false;
for(int i=start;i<jsonString.length();i++){
char c=jsonString.charAt(i);
if(inString){
if(c=='\\'){
i++;
}
else if(c=='"'){
inString=false;
}
}
else if(c=='"'){
inString=true;
}
else if(c=='{'||c=='['){
depth++;
}
else if(c=='}'||c==']'){
depth--;
}
if(!inString&&depth==0){
return i+1;
}
}
return -1;
}
}
/*PLEASE DO NOT EDIT THIS CODE*/
/*This code was generated using the UMPLE 1.38.0.8942.247e17422 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 8 "../ToJsonTest_1.ump"
public class Address
{
//------------------------
// MEMBER VARIABLES
//------------------------
//Address Attributes
private String street;
//Address Associations
private Person person;
//------------------------
// CONSTRUCTOR
//------------------------
public Address(String aStreet, Person aPerson)
{
street = aStreet;
boolean didAddPerson = setPerson(aPerson);
if (!didAddPerson)
{
throw new RuntimeException("Unable to create address due to person. See https://manual.umple.org?RE002ViolationofAssociationMultiplicity.html");
}
}
//------------------------
// INTERFACE
//------------------------
public boolean setStreet(String aStreet)
{
boolean wasSet = false;
street = aStreet;
wasSet = true;
return wasSet;
}
public String getStreet()
{
return street;
}
/* Code from template association_GetOne */
public Person getPerson()
{
return person;
}
/* Code from template association_SetOneToMany */
public boolean setPerson(Person aPerson)
{
boolean wasSet = false;
if (aPerson == null)
{
return wasSet;
}
Person existingPerson = person;
person = aPerson;
if (existingPerson != null && !existingPerson.equals(aPerson))
{
existingPerson.removeAddress(this);
}
person.addAddress(this);
wasSet = true;
return wasSet;
}
public void delete()
{
Person placeholderPerson = person;
this.person = null;
if(placeholderPerson != null)
{
placeholderPerson.removeAddress(this);
}
}
public String toString()
{
return super.toString() + "["+
"street" + ":" + getStreet()+ "]" + System.getProperties().getProperty("line.separator") +
" " + "person = "+(getPerson()!=null?Integer.toHexString(System.identityHashCode(getPerson())):"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("street");
toJsonOutput.append("\" : \"");
String primValue_0=""+getStreet()+"";
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("person");
toJsonOutput.append("\"");
toJsonOutput.append(" : ");
toJsonOutput.append("\n");
toJsonOutput.append(indent+" {");
toJsonOutput.append("\n");Person anotherItem_0 = getPerson();
anotherItem_0.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 Address fromJson(String aJsonString){
// the parser below reads json with nothing between its tokens, so remove every whitespace character json allows there
aJsonString=aJsonString.replace("\n","").replace("\r","").replace("\t","").replace(" ","");
// a map to store the umpleObjectID present in jsonString
Map<String, Object> umpleObjectIDMap=new HashMap<>();
// instantiate a new object
Address anObject = new Address(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 Address(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="Address".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="street";
//more types should be considered here
this.street=parsedResult.get(jsonKey);
// below for-loop check the association class of the top level class
jsonKey="person";
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);
Person oneAssoObj_0=(Person)objectNewOne_0;
person=oneAssoObj_0;
}
else{
person=(Person)umpleObjectIDMap.get(newUmpleID_0);
}
}catch(java.lang.reflect.InvocationTargetException e){
// an associated object with an unknown state must fail the load, as the top-level object does
if(e.getCause() instanceof IllegalArgumentException){
throw (IllegalArgumentException)e.getCause();
}
}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="\\\"";
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);
// The object's own "key":value pairs follow, a value being a "string", a [list] or an {object}.
// Each value is skipped whole, so the pairs of an associated object are left for that object to read
int pairStart=topLevelMatcher.end()+1;
while(pairStart<jsonString.length()&&jsonString.charAt(pairStart)=='"'){
int keyEnd=fromJsonParserValueEnd(jsonString,pairStart);
// without the colon there is no telling which value is the key's, so read no further
if(keyEnd<0||!jsonString.startsWith(":",keyEnd)){
break;
}
int valueEnd=fromJsonParserValueEnd(jsonString,keyEnd+1);
if(valueEnd<0){
break;
}
String key=jsonString.substring(pairStart+1,keyEnd-1);
String value=jsonString.substring(keyEnd+1,valueEnd);
// The class name and object id come first and win over an attribute named like them.
// toJson quotes every attribute and state, so a bare null, boolean or number is left unread, as it always was
if(value.startsWith("\"")){
parsedResultMap.putIfAbsent(key,value.substring(1,value.length()-1).replace("\\\\","\\").replace("\\\"","\""));
}
else if(value.startsWith("[")||value.startsWith("{")){
parsedResultMap.putIfAbsent(key,value);
}
// skip the comma, and the extra one left by a superclass with nothing to output
pairStart=valueEnd;
while(pairStart<jsonString.length()&&jsonString.charAt(pairStart)==','){
pairStart++;
}
}
}
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{
// objListString is a [list]; each {object} in it is taken whole with the objects nested in it,
// and any other element, which toJson does not write, is skipped
int itemStart=1;
while(itemStart<objListString.length()&&objListString.charAt(itemStart)!=']'){
int itemEnd=fromJsonParserValueEnd(objListString,itemStart);
if(itemEnd<0){
break;
}
if(objListString.charAt(itemStart)=='{'){
objList.add(objListString.substring(itemStart,itemEnd));
}
itemStart=itemEnd+1;
}
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;
}
}
/*
* Returns the index just after the json value that starts at index start,
* or -1 if there is none there or it is cut short.
* A "string", [list] or {object} ends where it closes; brackets and escaped quotes inside a string are text.
* A bare null, boolean or number ends at the next comma or closing bracket
*/
private static int fromJsonParserValueEnd(String jsonString, int start){
if(start>=jsonString.length()){
return -1;
}
if("\"[{".indexOf(jsonString.charAt(start))<0){
int end=start;
while(end<jsonString.length()&&",}]".indexOf(jsonString.charAt(end))<0){
end++;
}
return end>start&&end<jsonString.length()?end:-1;
}
int depth=0;
boolean inString=false;
for(int i=start;i<jsonString.length();i++){
char c=jsonString.charAt(i);
if(inString){
if(c=='\\'){
i++;
}
else if(c=='"'){
inString=false;
}
}
else if(c=='"'){
inString=true;
}
else if(c=='{'||c=='['){
depth++;
}
else if(c=='}'||c==']'){
depth--;
}
if(!inString&&depth==0){
return i+1;
}
}
return -1;
}
}