package simulator;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import models.algebra.Constant;
import models.algebra.Expression;
import models.algebra.Term;
import models.algebra.Type;
import models.algebra.Variable;
import models.dataConstraintModel.DataConstraintModel;
import models.dataConstraintModel.JsonTerm;
import models.dataConstraintModel.ListTerm;
import models.dataConstraintModel.MapTerm;
import models.dataConstraintModel.ResourceHierarchy;
import models.dataFlowModel.DataTransferChannel;
import simulator.states.CompositeResourceState;
import simulator.states.JsonResourceState;
import simulator.states.ListResourceState;
import simulator.states.MapResourceState;
import simulator.states.PrimitiveResourceState;
import simulator.states.ResourceState;
/**
* The whole state of a running model
* @author Nitta
*
*/
public class SystemState {
private Set<Resource> rootResources = new HashSet<>();
private Map<DataTransferChannel, ChannelState> channelStates = new HashMap<>();
private List<Event> events = new ArrayList<>();
public SystemState() {
}
public SystemState(SystemState prevState) {
for (Resource resource: prevState.getRootResources()) {
rootResources.add(new Resource(resource));
}
for (Map.Entry<DataTransferChannel, ChannelState> channelEnt: prevState.getChannelStates().entrySet()) {
if (channelEnt.getValue() != null) {
channelStates.put(channelEnt.getKey(), (ChannelState) channelEnt.getValue().clone());
} else {
channelStates.put(channelEnt.getKey(), null);
}
}
}
public Set<Resource> getRootResources() {
return rootResources;
}
public void addResource(Resource rootResource) {
rootResources.add(rootResource);
}
public Resource getResource(ResourceIdentifier resourceIdentifier) {
for (Resource root: rootResources) {
Resource descendant = root.getDescendant(resourceIdentifier);
if (descendant != null) return descendant;
}
return null;
}
public Resource getResource(String resourceIdentifier) {
for (Resource root: rootResources) {
Resource descendant = root.getDescendant(resourceIdentifier);
if (descendant != null) return descendant;
}
return null;
}
/**
* update the state of a specified resource
*
* @param resourceIdentifier a resource identifier to identify the resource
* @param curResVar a variable to represent the current state of the resource (may be replaced with resCurStateVal)
* @param resCurStateVal the value of the current state of the resource
* @param resNextStateVal the value of the new state of the resource (may contain curResVar)
* @return the identifier of the deepest resource created by this update.
*/
public List<ResourceIdentifier> updateResourceState(ResourceIdentifier resourceIdentifier, Variable curResVar, Expression resCurStateVal, Expression resNextStateVal) {
Type resType = resourceIdentifier.getResourceStateType();
if (resNextStateVal instanceof Term) {
Term termValue = (Term) resNextStateVal;
if (termValue.getSymbol().equals(DataConstraintModel.cond)) {
// If resNextStateVal is a conditional term, then calculates it here.
Expression condExp = termValue.getChild(0);
if (condExp instanceof Term) {
condExp = ((Term) condExp).substitute(curResVar, resCurStateVal);
condExp = ((Term) condExp).reduce();
}
List<Expression> condArgs = new ArrayList<>();
condArgs.add(condExp);
condArgs.add(termValue.getChild(1));
condArgs.add(termValue.getChild(2));
resNextStateVal = DataConstraintModel.cond.calculate(condArgs);
if (resNextStateVal != null) {
return updateResourceState(resourceIdentifier, curResVar, resCurStateVal, resNextStateVal);
}
return null;
}
}
if (resType != null && DataConstraintModel.typeList.isAncestorOf(resType)) {
if (resNextStateVal instanceof Constant) {
} else if (resNextStateVal instanceof ListTerm) {
ListTerm listValue = (ListTerm) resNextStateVal;
Resource res = getResource(resourceIdentifier);
ResourceState state = res.getState();
if (state instanceof ListResourceState) {
List<ResourceIdentifier> createdResources = new ArrayList<>();
((ListResourceState) state).clearChildStates();
for (int i = 0; i < listValue.size(); i++) {
Expression childExp = new Constant(Integer.toString(i), DataConstraintModel.typeInt);
ResourceHierarchy childResourceHierarchy = null;
if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) {
childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next();
} else {
Type childResType = null;
if (listValue.get(i) instanceof Variable) {
childResType = ((Variable) listValue.get(i)).getType();
} else if (listValue.get(i) instanceof Term) {
childResType = ((Term) listValue.get(i)).getType();
}
childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType);
}
ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy);
Map.Entry<ResourceState, List<ResourceIdentifier>> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, listValue.get(i));
((ListResourceState) state).addChildState(childInfo.getKey());
createdResources.addAll(childInfo.getValue());
}
return createdResources;
}
return null;
} else if (resNextStateVal instanceof Term) {
Term listValue = (Term) resNextStateVal;
if (listValue.getSymbol().equals(DataConstraintModel.append)) {
List<ResourceIdentifier> createdResources = new ArrayList<>();
Resource res = getResource(resourceIdentifier);
ResourceState state = res.getState();
if (listValue.getChild(0) instanceof Term) {
if (listValue.getChild(0) instanceof Constant && ((Constant) listValue.getChild(0)).getSymbol().equals(DataConstraintModel.nil)) {
// If the child list is nil.
ResourceState parentState = res.getParent().getState();
ResourceState newState = new ListResourceState();
if (parentState instanceof CompositeResourceState) {
((CompositeResourceState) parentState).replaceChildState(state, newState);
}
state = newState;
res.changeState(state);
} else {
Expression childList = ((Term) listValue.getChild(0)).reduce();
if (childList instanceof ListTerm) {
// If the child list is a list literal.
List<ResourceIdentifier> childInfo = updateResourceState(resourceIdentifier, curResVar, resCurStateVal, childList); // one more recursion.
if (childInfo != null) createdResources.addAll(childInfo);
} else if (childList instanceof Term) {
// There may or may not be the current state of the resource (curResVar) under the child.
List<ResourceIdentifier> childInfo = updateResourceState(resourceIdentifier, curResVar, resCurStateVal, listValue.getChild(0));
if (childInfo != null) createdResources.addAll(childInfo);
}
}
}
Expression childExp = null;
if (state instanceof ListResourceState) {
childExp = new Constant(Integer.toString(((ListResourceState) state).getChildStates().size()), DataConstraintModel.typeInt);
} else if (state instanceof PrimitiveResourceState && ((PrimitiveResourceState) state).getValue().getSymbol().equals(DataConstraintModel.nil)) {
// If the value of state is nil.
childExp = new Constant("0", DataConstraintModel.typeInt);
ResourceState parentState = res.getParent().getState();
ResourceState newState = new ListResourceState();
if (parentState instanceof CompositeResourceState) {
((CompositeResourceState) parentState).replaceChildState(state, newState);
}
state = newState;
res.changeState(state);
}
ResourceHierarchy childResourceHierarchy = null;
if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) {
childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next();
} else {
Type childResType = null;
if (listValue.getChild(1) instanceof Variable) {
childResType = ((Variable) listValue.getChild(1)).getType();
} else if (listValue.getChild(1) instanceof Term) {
childResType = ((Term) listValue.getChild(1)).getType();
}
childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType);
}
ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy);
Map.Entry<ResourceState, List<ResourceIdentifier>> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, listValue.getChild(1));
((ListResourceState) state).addChildState(childInfo.getKey());
createdResources.addAll(childInfo.getValue());
return createdResources;
} else if (listValue.getSymbol().equals(DataConstraintModel.set)) {
Expression childIdxExp = listValue.getChild(1);
if (childIdxExp instanceof Term) {
childIdxExp = ((Term) childIdxExp).substitute(curResVar, resCurStateVal);
childIdxExp = ((Term) childIdxExp).reduce();
}
if (childIdxExp instanceof Constant) {
List<ResourceIdentifier> createdResources = new ArrayList<>();
Resource res = getResource(resourceIdentifier);
ResourceState state = res.getState();
if (listValue.getChild(0) instanceof Term) {
if (listValue.getChild(0) instanceof Constant && ((Constant) listValue.getChild(0)).getSymbol().equals(DataConstraintModel.nil)) {
// If the child list is nil.
ResourceState parentState = res.getParent().getState();
ResourceState newState = new ListResourceState();
if (parentState instanceof CompositeResourceState) {
((CompositeResourceState) parentState).replaceChildState(state, newState);
}
state = newState;
res.changeState(state);
} else {
Expression childList = ((Term) listValue.getChild(0)).reduce();
if (childList instanceof ListTerm) {
// If the child list is a list literal.
List<ResourceIdentifier> childInfo = updateResourceState(resourceIdentifier, curResVar, resCurStateVal, childList); // one more recursion.
if (childInfo != null) createdResources.addAll(childInfo);
} else if (childList instanceof Term) {
// There may or may not be the current state of the resource (curResVar) under the child.
List<ResourceIdentifier> childInfo = updateResourceState(resourceIdentifier, curResVar, resCurStateVal, listValue.getChild(0));
if (childInfo != null) createdResources.addAll(childInfo);
}
}
}
ResourceHierarchy childResourceHierarchy = null;
if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) {
childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next();
} else {
Type childResType = null;
if (listValue.getChild(2) instanceof Variable) {
childResType = ((Variable) listValue.getChild(2)).getType();
} else if (listValue.getChild(2) instanceof Term) {
childResType = ((Term) listValue.getChild(2)).getType();
}
childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType);
}
ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childIdxExp, childResourceHierarchy);
Map.Entry<ResourceState, List<ResourceIdentifier>> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, listValue.getChild(2));
((ListResourceState) state).replaceChildState(Integer.parseInt(childIdxExp.toString()), childInfo.getKey());
createdResources.addAll(childInfo.getValue());
return createdResources;
}
} else if (listValue.getSymbol().equals(DataConstraintModel.remove)) {
Expression childIdxExp = listValue.getChild(1);
if (childIdxExp instanceof Term) {
childIdxExp = ((Term) childIdxExp).substitute(curResVar, resCurStateVal);
childIdxExp = ((Term) childIdxExp).reduce();
}
if (childIdxExp instanceof Constant) {
List<ResourceIdentifier> createdResources = new ArrayList<>();
Resource res = getResource(resourceIdentifier);
ResourceState state = res.getState();
if (listValue.getChild(0) instanceof Term) {
if (listValue.getChild(0) instanceof Constant && ((Constant) listValue.getChild(0)).getSymbol().equals(DataConstraintModel.nil)) {
// If the child list is nil.
ResourceState parentState = res.getParent().getState();
ResourceState newState = new ListResourceState();
if (parentState instanceof CompositeResourceState) {
((CompositeResourceState) parentState).replaceChildState(state, newState);
}
state = newState;
res.changeState(state);
} else {
Expression childList = ((Term) listValue.getChild(0)).reduce();
if (childList instanceof ListTerm) {
// If the child list is a list literal.
List<ResourceIdentifier> childInfo = updateResourceState(resourceIdentifier, curResVar, resCurStateVal, childList); // one more recursion.
if (childInfo != null) createdResources.addAll(childInfo);
} else if (childList instanceof Term) {
// There may or may not be the current state of the resource (curResVar) under the child.
List<ResourceIdentifier> childInfo = updateResourceState(resourceIdentifier, curResVar, resCurStateVal, listValue.getChild(0));
if (childInfo != null) createdResources.addAll(childInfo);
}
}
}
((ListResourceState) state).removeChildState(Integer.parseInt(childIdxExp.toString()));
createdResources.add(resourceIdentifier);
return createdResources;
}
}
}
} else if (resType != null && DataConstraintModel.typeMap.isAncestorOf(resType)) {
if (resNextStateVal instanceof Constant) {
} else if (resNextStateVal instanceof JsonTerm) {
JsonTerm mapValue = (JsonTerm) resNextStateVal;
Resource res = getResource(resourceIdentifier);
ResourceState state = res.getState();
if (state instanceof MapResourceState) {
List<ResourceIdentifier> createdResources = new ArrayList<>();
((MapResourceState) state).clearChildStates();
for (String key: mapValue.keySet()) {
Expression childExp = new Constant(key, DataConstraintModel.typeString);
ResourceHierarchy childResourceHierarchy = null;
if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) {
childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next();
} else {
Type childResType = null;
if (mapValue.get(key) instanceof Variable) {
childResType = ((Variable) mapValue.get(key)).getType();
} else if (mapValue.get(key) instanceof Term) {
childResType = ((Term) mapValue.get(key)).getType();
}
childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType);
}
ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy);
Map.Entry<ResourceState, List<ResourceIdentifier>> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, mapValue.get(key));
((MapResourceState) state).addChildState(key, childInfo.getKey());
createdResources.addAll(childInfo.getValue());
}
return createdResources;
}
return null;
} else if (resNextStateVal instanceof MapTerm) {
MapTerm mapValue = (MapTerm) resNextStateVal;
Resource res = getResource(resourceIdentifier);
ResourceState state = res.getState();
if (state instanceof MapResourceState) {
((MapResourceState) state).clearChildStates();
List<ResourceIdentifier> createdResources = new ArrayList<>();
for (String key: mapValue.keySet()) {
Expression childExp = new Constant(key, DataConstraintModel.typeString);
ResourceHierarchy childResourceHierarchy = null;
if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) {
childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next();
} else {
Type childResType = null;
if (mapValue.get(key) instanceof Variable) {
childResType = ((Variable) mapValue.get(key)).getType();
} else if (mapValue.get(key) instanceof Term) {
childResType = ((Term) mapValue.get(key)).getType();
}
childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType);
}
ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy);
Map.Entry<ResourceState, List<ResourceIdentifier>> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, mapValue.get(key));
((MapResourceState) state).addChildState(key, childInfo.getKey());
createdResources.addAll(childInfo.getValue());
}
return createdResources;
}
return null;
} else if (resNextStateVal instanceof Term) {
Term mapValue = (Term) resNextStateVal;
if (mapValue.getSymbol().equals(DataConstraintModel.insert)) {
List<ResourceIdentifier> createdResources = new ArrayList<>();
Expression childKeyExp = mapValue.getChild(1);
if (childKeyExp instanceof Term) {
childKeyExp = ((Term) childKeyExp).substitute(curResVar, resCurStateVal);
childKeyExp = ((Term) childKeyExp).reduce();
}
if (childKeyExp instanceof Constant) {
Resource res = getResource(resourceIdentifier);
ResourceState state = res.getState();
if (mapValue.getChild(0) instanceof Term) {
if (mapValue.getChild(0) instanceof Constant && ((Constant) mapValue.getChild(0)).getSymbol().equals(DataConstraintModel.nil)) {
// If the child map is nil.
ResourceState parentState = res.getParent().getState();
ResourceState newState = new MapResourceState();
if (parentState instanceof CompositeResourceState) {
((CompositeResourceState) parentState).replaceChildState(state, newState);
}
state = newState;
res.changeState(state);
} else {
Expression childMap = ((Term) mapValue.getChild(0)).reduce();
if (childMap instanceof MapTerm) {
// If the child map is a map literal.
List<ResourceIdentifier> childInfo = updateResourceState(resourceIdentifier, curResVar, resCurStateVal, childMap); // one more recursion
if (childInfo != null) createdResources.addAll(childInfo);
} else if (childMap instanceof Term) {
// There may or may not be the current state of the resource (curResVar) under the child.
List<ResourceIdentifier> childInfo = updateResourceState(resourceIdentifier, curResVar, resCurStateVal, mapValue.getChild(0));
if (childInfo != null) createdResources.addAll(childInfo);
}
}
}
if (state instanceof PrimitiveResourceState && ((PrimitiveResourceState) state).getValue().getSymbol().equals(DataConstraintModel.nil)) {
// If the value of state is nil.
ResourceState parentState = res.getParent().getState();
ResourceState newState = new MapResourceState();
if (parentState instanceof CompositeResourceState) {
((CompositeResourceState) parentState).replaceChildState(state, newState);
}
state = newState;
res.changeState(state);
}
ResourceHierarchy childResourceHierarchy = null;
if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) {
childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next();
} else {
Type childResType = null;
if (mapValue.getChild(2) instanceof Variable) {
childResType = ((Variable) mapValue.getChild(2)).getType();
} else if (mapValue.getChild(2) instanceof Term) {
childResType = ((Term) mapValue.getChild(2)).getType();
}
childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType);
}
ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childKeyExp, childResourceHierarchy);
String childId = (String) ((Constant) childKeyExp).getValue();
Map.Entry<ResourceState, List<ResourceIdentifier>> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, mapValue.getChild(2));
((MapResourceState) state).addChildState(childId, childInfo.getKey());
createdResources.addAll(childInfo.getValue());
return createdResources;
}
} else if (mapValue.getSymbol().equals(DataConstraintModel.delete)) {
Expression childKeyExp = mapValue.getChild(1);
if (childKeyExp instanceof Term) {
childKeyExp = ((Term) childKeyExp).substitute(curResVar, resCurStateVal);
childKeyExp = ((Term) childKeyExp).reduce();
}
if (childKeyExp instanceof Constant) {
List<ResourceIdentifier> createdResources = new ArrayList<>();
Resource res = getResource(resourceIdentifier);
ResourceState state = res.getState();
if (mapValue.getChild(0) instanceof Term) {
if (mapValue.getChild(0) instanceof Constant && ((Constant) mapValue.getChild(0)).getSymbol().equals(DataConstraintModel.nil)) {
// If the child map is nil.
ResourceState parentState = res.getParent().getState();
ResourceState newState = new MapResourceState();
if (parentState instanceof CompositeResourceState) {
((CompositeResourceState) parentState).replaceChildState(state, newState);
}
state = newState;
res.changeState(state);
} else {
Expression childMap = ((Term) mapValue.getChild(0)).reduce();
if (childMap instanceof MapTerm) {
// If the child map is a map literal.
List<ResourceIdentifier> childInfo = updateResourceState(resourceIdentifier, curResVar, resCurStateVal, childMap); // one more recursion
if (childInfo != null) createdResources.addAll(childInfo);
} else if (childMap instanceof Term) {
// There may or may not be the current state of the resource (curResVar) under the child.
List<ResourceIdentifier> childInfo = updateResourceState(resourceIdentifier, curResVar, resCurStateVal, mapValue.getChild(0));
if (childInfo != null) createdResources.addAll(childInfo);
}
}
}
String childId = (String) ((Constant) childKeyExp).getValue();
((MapResourceState) state).removeChildState(childId);
createdResources.add(resourceIdentifier);
return createdResources;
}
}
}
} else if (resType != null && DataConstraintModel.typeJson.isAncestorOf(resType)) {
if (resNextStateVal instanceof Constant) {
} else if (resNextStateVal instanceof JsonTerm) {
JsonTerm jsonValue = (JsonTerm) resNextStateVal;
Resource res = getResource(resourceIdentifier);
ResourceState state = res.getState();
if (state instanceof JsonResourceState) {
List<ResourceIdentifier> createdResources = new ArrayList<>();
for (String key: jsonValue.keySet()) {
ResourceHierarchy childResourceHierarchy = null;
for (ResourceHierarchy childRes: resourceIdentifier.getResourceHierarchy().getChildren()) {
if (childRes.getResourceName().equals(key)) {
childResourceHierarchy = childRes;
break;
}
}
if (childResourceHierarchy == null) {
Type childResType = null;
if (jsonValue.get(key) instanceof Variable) {
childResType = ((Variable) jsonValue.get(key)).getType();
} else if (jsonValue.get(key) instanceof Term) {
childResType = ((Term) jsonValue.get(key)).getType();
}
childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), key, childResType);
}
ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, key, childResourceHierarchy);
Map.Entry<ResourceState, List<ResourceIdentifier>> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, jsonValue.get(key));
ResourceState childState = childInfo.getKey();
if (res.getChildrenMap() != null && res.getChildrenMap().get(key) != null) {
res.getChildrenMap().get(key).changeState(childState);
}
((JsonResourceState) state).addChildState(key, childState);
createdResources.addAll(childInfo.getValue());
}
return createdResources;
}
return null;
} else if (resNextStateVal instanceof Term) {
Term jsonValue = (Term) resNextStateVal;
Resource res = getResource(resourceIdentifier);
ResourceState state = res.getState();
List<ResourceIdentifier> createdResources = new ArrayList<>();
while (jsonValue.getSymbol().equals(DataConstraintModel.addMember)) {
Expression childKeyExp = jsonValue.getChild(1);
if (childKeyExp instanceof Constant) {
String memberName = (String) ((Constant) childKeyExp).getValue();
ResourceHierarchy childResourceHierarchy = null;
for (ResourceHierarchy childRes: resourceIdentifier.getResourceHierarchy().getChildren()) {
if (childRes.getResourceName().equals(memberName)) {
childResourceHierarchy = childRes;
break;
}
}
if (childResourceHierarchy == null) {
Type childResType = null;
if (jsonValue.getChild(2) instanceof Variable) {
childResType = ((Variable) jsonValue.getChild(2)).getType();
} else if (jsonValue.getChild(2) instanceof Term) {
childResType = ((Term) jsonValue.getChild(2)).getType();
}
childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), memberName, childResType);
}
ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, memberName, childResourceHierarchy);
Map.Entry<ResourceState, List<ResourceIdentifier>> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, jsonValue.getChild(2));
((JsonResourceState) state).addChildState(memberName, childInfo.getKey());
createdResources.addAll(childInfo.getValue());
}
if (!(jsonValue.getChild(0) instanceof Term)) break;
jsonValue = (Term) jsonValue.getChild(0);
}
return createdResources;
}
} else {
if (curResVar != null && resCurStateVal != null) {
if (resNextStateVal instanceof Term) {
resNextStateVal = ((Term) resNextStateVal).substitute(curResVar, resCurStateVal);
resNextStateVal = ((Term) resNextStateVal).reduce();
}
}
if (resNextStateVal instanceof Constant) {
Resource res = getResource(resourceIdentifier);
ResourceState state = null;
if (res != null) {
state = res.getState();
((PrimitiveResourceState) state).setValue((Constant) resNextStateVal);
} else {
ResourceIdentifier parentResId = (ResourceIdentifier) resourceIdentifier.getParent();
Type parentResType = parentResId.getResourceStateType();
if (parentResType != null && DataConstraintModel.typeList.isAncestorOf(parentResType)) {
} else if (parentResType != null && DataConstraintModel.typeMap.isAncestorOf(parentResType)) {
JsonResourceState parentState = (JsonResourceState) getResource(parentResId).getState();
parentState.addChildState((String) ((Constant) resourceIdentifier.getLastParam()).getValue(), new PrimitiveResourceState((Constant) resNextStateVal));
} else if (parentResType != null && DataConstraintModel.typeJson.isAncestorOf(parentResType)) {
JsonResourceState parentState = (JsonResourceState) getResource(parentResId).getState();
parentState.addChildState(resourceIdentifier.getLeafResourceName(), new PrimitiveResourceState((Constant) resNextStateVal));
}
}
List<ResourceIdentifier> updatedResources = new ArrayList<>();
updatedResources.add(resourceIdentifier);
return updatedResources;
}
}
return null;
}
public Map.Entry<ResourceState, List<ResourceIdentifier>> createResourceState(ResourceIdentifier resourceIdentifier, Variable curResVar, Expression resCurStateVal, Expression resStateValue) {
Type resType = resourceIdentifier.getResourceStateType();
if (resType == null && resStateValue instanceof Term) {
resType = ((Term) resStateValue).getType();
resStateValue = ((Term) resStateValue).reduce();
}
if (resType != null) {
if (DataConstraintModel.typeList.isAncestorOf(resType)) {
if (resStateValue instanceof Constant) {
} else if (resStateValue instanceof ListTerm) {
ListTerm listValue = (ListTerm) resStateValue;
ListResourceState state = new ListResourceState();
Map.Entry<ResourceState, List<ResourceIdentifier>> createInfo = new AbstractMap.SimpleEntry<>(state, new ArrayList<>());
for (int i = 0; i < listValue.size(); i++) {
Expression childExp = new Constant(Integer.toString(i), DataConstraintModel.typeInt);
ResourceHierarchy childResourceHierarchy = null;
if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) {
childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next();
} else {
Type childResType = null;
if (listValue.get(i) instanceof Variable) {
childResType = ((Variable) listValue.get(i)).getType();
} else if (listValue.get(i) instanceof Term) {
childResType = ((Term) listValue.get(i)).getType();
}
childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType);
}
ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy);
Map.Entry<ResourceState, List<ResourceIdentifier>> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, listValue.get(i));
state.addChildState(childInfo.getKey());
createInfo.getValue().addAll(childInfo.getValue());
createInfo = new AbstractMap.SimpleEntry<>(state, createInfo.getValue());
}
return createInfo;
} else if (resStateValue instanceof Term) {
Term listValue = (Term) resStateValue;
if (listValue.getSymbol().equals(DataConstraintModel.append)) {
List<ResourceIdentifier> createdResources = new ArrayList<>();
ListResourceState state = new ListResourceState();
if (listValue.getChild(0) instanceof Term) {
if (listValue.getChild(0) instanceof Constant && ((Constant) listValue.getChild(0)).getSymbol().equals(DataConstraintModel.nil)) {
// If the child list is nil.
} else {
Expression childList = ((Term) listValue.getChild(0));
childList = ((Term) childList).substitute(curResVar, resStateValue);
childList = ((Term) childList).reduce();
if (childList instanceof ListTerm) {
// If the child list is a list literal.
Map.Entry<ResourceState, List<ResourceIdentifier>> childInfo = createResourceState(resourceIdentifier, curResVar, resCurStateVal, childList); // one more recursion.
state = (ListResourceState) childInfo.getKey();
if (childInfo != null) createdResources.addAll(childInfo.getValue());
} else if (childList instanceof Term) {
// If the child list is a list term.
Map.Entry<ResourceState, List<ResourceIdentifier>> childInfo = createResourceState(resourceIdentifier, curResVar, resCurStateVal, listValue.getChild(0));
state = (ListResourceState) childInfo.getKey();
if (childInfo != null) createdResources.addAll(childInfo.getValue());
}
}
}
Expression childExp = new Constant(Integer.toString(((ListResourceState) state).getChildStates().size()), DataConstraintModel.typeInt);
ResourceHierarchy childResourceHierarchy = null;
if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) {
childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next();
} else {
Type childResType = null;
if (listValue.getChild(1) instanceof Variable) {
childResType = ((Variable) listValue.getChild(1)).getType();
} else if (listValue.getChild(1) instanceof Term) {
childResType = ((Term) listValue.getChild(1)).getType();
}
childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType);
}
ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy);
Map.Entry<ResourceState, List<ResourceIdentifier>> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, listValue.getChild(1));
state.addChildState(childInfo.getKey());
createdResources.addAll(childInfo.getValue());
return new AbstractMap.SimpleEntry<>(state, createdResources);
} else if (listValue.getSymbol().equals(DataConstraintModel.set)) {
Expression childIdxExp = listValue.getChild(1);
if (childIdxExp instanceof Term) {
childIdxExp = ((Term) childIdxExp).substitute(curResVar, resCurStateVal);
childIdxExp = ((Term) childIdxExp).reduce();
}
if (childIdxExp instanceof Constant) {
List<ResourceIdentifier> createdResources = new ArrayList<>();
ListResourceState state = new ListResourceState();
if (listValue.getChild(0) instanceof Term) {
if (listValue.getChild(0) instanceof Constant && ((Constant) listValue.getChild(0)).getSymbol().equals(DataConstraintModel.nil)) {
// If the child list is nil.
} else {
Expression childList = ((Term) listValue.getChild(0));
childList = ((Term) childList).substitute(curResVar, resStateValue);
childList = ((Term) childList).reduce();
if (childList instanceof ListTerm) {
// If the child list is a list literal.
Map.Entry<ResourceState, List<ResourceIdentifier>> childInfo = createResourceState(resourceIdentifier, curResVar, resCurStateVal, childList); // one more recursion.
state = (ListResourceState) childInfo.getKey();
if (childInfo != null) createdResources.addAll(childInfo.getValue());
} else if (childList instanceof Term) {
// If the child list is a list term.
Map.Entry<ResourceState, List<ResourceIdentifier>> childInfo = createResourceState(resourceIdentifier, curResVar, resCurStateVal, listValue.getChild(0));
state = (ListResourceState) childInfo.getKey();
if (childInfo != null) createdResources.addAll(childInfo.getValue());
}
}
}
ResourceHierarchy childResourceHierarchy = null;
if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) {
childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next();
} else {
Type childResType = null;
if (listValue.getChild(2) instanceof Variable) {
childResType = ((Variable) listValue.getChild(2)).getType();
} else if (listValue.getChild(2) instanceof Term) {
childResType = ((Term) listValue.getChild(2)).getType();
}
childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType);
}
ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childIdxExp, childResourceHierarchy);
Map.Entry<ResourceState, List<ResourceIdentifier>> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, listValue.getChild(2));
state.replaceChildState(Integer.parseInt(childIdxExp.toString()), childInfo.getKey());
createdResources.addAll(childInfo.getValue());
return new AbstractMap.SimpleEntry<>(state, createdResources);
}
} else if (listValue.getSymbol().equals(DataConstraintModel.remove)) {
Expression childIdxExp = listValue.getChild(1);
if (childIdxExp instanceof Term) {
childIdxExp = ((Term) childIdxExp).substitute(curResVar, resCurStateVal);
childIdxExp = ((Term) childIdxExp).reduce();
}
if (childIdxExp instanceof Constant) {
List<ResourceIdentifier> createdResources = new ArrayList<>();
ListResourceState state = new ListResourceState();
if (listValue.getChild(0) instanceof Term) {
if (listValue.getChild(0) instanceof Constant && ((Constant) listValue.getChild(0)).getSymbol().equals(DataConstraintModel.nil)) {
// If the child list is nil.
} else {
Expression childList = ((Term) listValue.getChild(0));
childList = ((Term) childList).substitute(curResVar, resStateValue);
childList = ((Term) childList).reduce();
if (childList instanceof ListTerm) {
// If the child list is a list literal.
Map.Entry<ResourceState, List<ResourceIdentifier>> childInfo = createResourceState(resourceIdentifier, curResVar, resCurStateVal, childList); // one more recursion.
state = (ListResourceState) childInfo.getKey();
if (childInfo != null) createdResources.addAll(childInfo.getValue());
} else if (childList instanceof Term) {
// If the child list is a list term.
Map.Entry<ResourceState, List<ResourceIdentifier>> childInfo = createResourceState(resourceIdentifier, curResVar, resCurStateVal, listValue.getChild(0));
state = (ListResourceState) childInfo.getKey();
if (childInfo != null) createdResources.addAll(childInfo.getValue());
}
}
}
((ListResourceState) state).removeChildState(Integer.parseInt(childIdxExp.toString()));
return new AbstractMap.SimpleEntry<>(state, createdResources);
}
} else {
listValue = listValue.substitute(curResVar, resCurStateVal);
Expression listExp = listValue.reduce();
if (listExp instanceof ListTerm) {
ListTerm listVal = (ListTerm) listExp;
ListResourceState state = new ListResourceState();
Map.Entry<ResourceState, List<ResourceIdentifier>> createInfo = new AbstractMap.SimpleEntry<>(state, new ArrayList<>());
for (int i = 0; i < listVal.size(); i++) {
Expression childExp = new Constant(Integer.toString(i), DataConstraintModel.typeInt);
ResourceHierarchy childResourceHierarchy = null;
if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) {
childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next();
} else {
Type childResType = null;
if (listVal.get(i) instanceof Variable) {
childResType = ((Variable) listVal.get(i)).getType();
} else if (listVal.get(i) instanceof Term) {
childResType = ((Term) listVal.get(i)).getType();
}
childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType);
}
ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy);
Map.Entry<ResourceState, List<ResourceIdentifier>> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, listVal.get(i));
state.addChildState(childInfo.getKey());
createInfo.getValue().addAll(childInfo.getValue());
createInfo = new AbstractMap.SimpleEntry<>(state, createInfo.getValue());
}
return createInfo;
}
}
}
} else if (DataConstraintModel.typeMap.isAncestorOf(resType)) {
if (resStateValue instanceof Constant) {
} else if (resStateValue instanceof JsonTerm) {
JsonTerm mapValue = (JsonTerm) resStateValue;
MapResourceState state = new MapResourceState();
Map.Entry<ResourceState, List<ResourceIdentifier>> createInfo = new AbstractMap.SimpleEntry<>(state, new ArrayList<>());
for (String key: mapValue.keySet()) {
Expression childExp = new Constant(key, DataConstraintModel.typeString);
ResourceHierarchy childResourceHierarchy = null;
if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) {
childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next();
} else {
Type childResType = null;
if (mapValue.get(key) instanceof Variable) {
childResType = ((Variable) mapValue.get(key)).getType();
} else if (mapValue.get(key) instanceof Term) {
childResType = ((Term) mapValue.get(key)).getType();
}
childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType);
}
ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy);
Map.Entry<ResourceState, List<ResourceIdentifier>> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, mapValue.get(key));
state.addChildState(key, childInfo.getKey());
createInfo.getValue().addAll(childInfo.getValue());
createInfo = new AbstractMap.SimpleEntry<>(state, createInfo.getValue());
}
return createInfo;
} else if (resStateValue instanceof MapTerm) {
MapTerm mapValue = (MapTerm) resStateValue;
MapResourceState state = new MapResourceState();
Map.Entry<ResourceState, List<ResourceIdentifier>> createInfo = new AbstractMap.SimpleEntry<>(state, new ArrayList<>());
for (String key: mapValue.keySet()) {
Expression childExp = new Constant(key, DataConstraintModel.typeString);
ResourceHierarchy childResourceHierarchy = null;
if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) {
childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next();
} else {
Type childResType = null;
if (mapValue.get(key) instanceof Variable) {
childResType = ((Variable) mapValue.get(key)).getType();
} else if (mapValue.get(key) instanceof Term) {
childResType = ((Term) mapValue.get(key)).getType();
}
childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType);
}
ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy);
Map.Entry<ResourceState, List<ResourceIdentifier>> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, mapValue.get(key));
state.addChildState(key, childInfo.getKey());
createInfo.getValue().addAll(childInfo.getValue());
createInfo = new AbstractMap.SimpleEntry<>(state, createInfo.getValue());
}
return createInfo;
} else if (resStateValue instanceof Term) {
Term mapValue = (Term) resStateValue;
if (mapValue.getSymbol().equals(DataConstraintModel.insert)) {
Expression childKeyExp = mapValue.getChild(1);
if (childKeyExp instanceof Term) {
childKeyExp = ((Term) childKeyExp).substitute(curResVar, resCurStateVal);
childKeyExp = ((Term) childKeyExp).reduce();
}
if (childKeyExp instanceof Constant) {
List<ResourceIdentifier> createdResources = new ArrayList<>();
MapResourceState state = new MapResourceState();
if (mapValue.getChild(0) instanceof Term) {
if (mapValue.getChild(0) instanceof Constant && ((Constant) mapValue.getChild(0)).getSymbol().equals(DataConstraintModel.nil)) {
// If the child map is nil.
} else {
Expression childMap = ((Term) mapValue.getChild(0));
childMap = ((Term) childMap).substitute(curResVar, resStateValue);
childMap = ((Term) childMap).reduce();
if (childMap instanceof MapTerm) {
// If the child map is a map literal.
Map.Entry<ResourceState, List<ResourceIdentifier>> childInfo = createResourceState(resourceIdentifier, curResVar, resCurStateVal, childMap); // one more recursion.
state = (MapResourceState) childInfo.getKey();
if (childInfo != null) createdResources.addAll(childInfo.getValue());
} else if (childMap instanceof Term) {
// If the child map is a map term.
Map.Entry<ResourceState, List<ResourceIdentifier>> childInfo = createResourceState(resourceIdentifier, curResVar, resCurStateVal, mapValue.getChild(0));
state = (MapResourceState) childInfo.getKey();
if (childInfo != null) createdResources.addAll(childInfo.getValue());
}
}
}
ResourceHierarchy childResourceHierarchy = null;
if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) {
childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next();
} else {
Type childResType = null;
if (mapValue.getChild(2) instanceof Variable) {
childResType = ((Variable) mapValue.getChild(2)).getType();
} else if (mapValue.getChild(2) instanceof Term) {
childResType = ((Term) mapValue.getChild(2)).getType();
}
childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType);
}
ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childKeyExp, childResourceHierarchy);
String childId = (String) ((Constant) childKeyExp).getValue();
Map.Entry<ResourceState, List<ResourceIdentifier>> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, mapValue.getChild(2));
state.addChildState(childId, childInfo.getKey());
createdResources.addAll(childInfo.getValue());
return new AbstractMap.SimpleEntry<>(state, createdResources);
}
} else if (mapValue.getSymbol().equals(DataConstraintModel.delete)) {
Expression childKeyExp = mapValue.getChild(1);
if (childKeyExp instanceof Term) {
childKeyExp = ((Term) childKeyExp).substitute(curResVar, resCurStateVal);
childKeyExp = ((Term) childKeyExp).reduce();
}
if (childKeyExp instanceof Constant) {
List<ResourceIdentifier> createdResources = new ArrayList<>();
MapResourceState state = new MapResourceState();
if (mapValue.getChild(0) instanceof Term) {
if (mapValue.getChild(0) instanceof Constant && ((Constant) mapValue.getChild(0)).getSymbol().equals(DataConstraintModel.nil)) {
// If the child map is nil.
} else {
Expression childMap = ((Term) mapValue.getChild(0));
childMap = ((Term) childMap).substitute(curResVar, resStateValue);
childMap = ((Term) childMap).reduce();
if (childMap instanceof MapTerm) {
// If the child map is a map literal.
Map.Entry<ResourceState, List<ResourceIdentifier>> childInfo = createResourceState(resourceIdentifier, curResVar, resCurStateVal, childMap); // one more recursion.
state = (MapResourceState) childInfo.getKey();
if (childInfo != null) createdResources.addAll(childInfo.getValue());
} else if (childMap instanceof Term) {
// If the child map is a map term.
Map.Entry<ResourceState, List<ResourceIdentifier>> childInfo = createResourceState(resourceIdentifier, curResVar, resCurStateVal, mapValue.getChild(0));
state = (MapResourceState) childInfo.getKey();
if (childInfo != null) createdResources.addAll(childInfo.getValue());
}
}
}
String childId = (String) ((Constant) childKeyExp).getValue();
((MapResourceState) state).removeChildState(childId);
return new AbstractMap.SimpleEntry<>(state, createdResources);
}
} else {
mapValue = mapValue.substitute(curResVar, resCurStateVal);
Expression mapExp = mapValue.reduce();
if (mapExp instanceof MapTerm) {
MapTerm mapVal = (MapTerm) mapExp;
MapResourceState state = new MapResourceState();
Map.Entry<ResourceState, List<ResourceIdentifier>> createInfo = new AbstractMap.SimpleEntry<>(null, new ArrayList<>());
for (String key: mapVal.keySet()) {
Expression childExp = new Constant(key, DataConstraintModel.typeString);
ResourceHierarchy childResourceHierarchy = null;
if (resourceIdentifier.getResourceHierarchy().getChildren() != null && resourceIdentifier.getResourceHierarchy().getChildren().size() > 0) {
childResourceHierarchy = resourceIdentifier.getResourceHierarchy().getChildren().iterator().next();
} else {
Type childResType = null;
if (mapVal.get(key) instanceof Variable) {
childResType = ((Variable) mapVal.get(key)).getType();
} else if (mapVal.get(key) instanceof Term) {
childResType = ((Term) mapVal.get(key)).getType();
}
childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), 1, childResType);
}
ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, childResourceHierarchy);
Map.Entry<ResourceState, List<ResourceIdentifier>> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, mapVal.get(key));
state.addChildState(key, childInfo.getKey());
createInfo.getValue().addAll(childInfo.getValue());
createInfo = new AbstractMap.SimpleEntry<>(state, createInfo.getValue());
}
return createInfo;
}
}
}
} else if (DataConstraintModel.typeJson.isAncestorOf(resType)) {
if (resStateValue instanceof Constant) {
} else if (resStateValue instanceof JsonTerm) {
JsonTerm jsonValue = (JsonTerm) resStateValue;
JsonResourceState state = new JsonResourceState();
Map.Entry<ResourceState, List<ResourceIdentifier>> createInfo = new AbstractMap.SimpleEntry<>(null, new ArrayList<>());
for (String key: jsonValue.keySet()) {
ResourceHierarchy childResourceHierarchy = null;
for (ResourceHierarchy childRes: resourceIdentifier.getResourceHierarchy().getChildren()) {
if (childRes.getResourceName().equals(key)) {
childResourceHierarchy = childRes;
break;
}
}
if (childResourceHierarchy == null) {
Type childResType = null;
if (jsonValue.get(key) instanceof Variable) {
childResType = ((Variable) jsonValue.get(key)).getType();
} else if (jsonValue.get(key) instanceof Term) {
childResType = ((Term) jsonValue.get(key)).getType();
}
childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), key, childResType);
}
ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, key, childResourceHierarchy);
Map.Entry<ResourceState, List<ResourceIdentifier>> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, jsonValue.get(key));
ResourceState childState = childInfo.getKey();
Resource res = getResource(resourceIdentifier);
if (res != null && res.getChildrenMap() != null && res.getChildrenMap().get(key) != null) {
res.getChildrenMap().get(key).changeState(childState);
}
state.addChildState(key, childState);
createInfo.getValue().addAll(childInfo.getValue());
createInfo = new AbstractMap.SimpleEntry<>(state, createInfo.getValue());
}
return createInfo;
} else if (resStateValue instanceof Term) {
Term jsonValue = (Term) resStateValue;
JsonResourceState state = new JsonResourceState();
Map.Entry<ResourceState, List<ResourceIdentifier>> createInfo = new AbstractMap.SimpleEntry<>(null, new ArrayList<>());
if (jsonValue.getSymbol().equals(DataConstraintModel.addMember)) {
while (jsonValue.getSymbol().equals(DataConstraintModel.addMember)) {
Expression childExp = jsonValue.getChild(1);
if (childExp instanceof Constant) {
String memberName = (String) ((Constant) childExp).getValue();
ResourceHierarchy childResourceHierarchy = null;
for (ResourceHierarchy childRes: resourceIdentifier.getResourceHierarchy().getChildren()) {
if (childRes.getResourceName().equals(memberName)) {
childResourceHierarchy = childRes;
break;
}
}
if (childResourceHierarchy == null) {
Type childResType = null;
if (jsonValue.getChild(2) instanceof Variable) {
childResType = ((Variable) jsonValue.getChild(2)).getType();
} else if (jsonValue.getChild(2) instanceof Term) {
childResType = ((Term) jsonValue.getChild(2)).getType();
}
childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), memberName, childResType);
}
ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, memberName, childResourceHierarchy);
Map.Entry<ResourceState, List<ResourceIdentifier>> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, jsonValue.getChild(2));
state.addChildState(memberName, childInfo.getKey());
createInfo.getValue().addAll(childInfo.getValue());
createInfo = new AbstractMap.SimpleEntry<>(state, createInfo.getValue());
}
if (!(jsonValue.getChild(0) instanceof Term)) break;
jsonValue = (Term) jsonValue.getChild(0);
}
} else {
jsonValue = jsonValue.substitute(curResVar, resCurStateVal);
Expression jsonExp = jsonValue.reduce();
if (jsonExp instanceof JsonTerm) {
JsonTerm jsonVal = (JsonTerm) jsonExp;
for (String key: jsonVal.keySet()) {
ResourceHierarchy childResourceHierarchy = null;
for (ResourceHierarchy childRes: resourceIdentifier.getResourceHierarchy().getChildren()) {
if (childRes.getResourceName().equals(key)) {
childResourceHierarchy = childRes;
break;
}
}
if (childResourceHierarchy == null) {
Type childResType = null;
if (jsonVal.get(key) instanceof Variable) {
childResType = ((Variable) jsonVal.get(key)).getType();
} else if (jsonVal.get(key) instanceof Term) {
childResType = ((Term) jsonVal.get(key)).getType();
}
childResourceHierarchy = new ResourceHierarchy(resourceIdentifier.getResourceHierarchy(), key, childResType);
}
ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, key, childResourceHierarchy);
Map.Entry<ResourceState, List<ResourceIdentifier>> childInfo = createResourceState(childResourceIdentifier, curResVar, resCurStateVal, jsonVal.get(key));
ResourceState childState = childInfo.getKey();
Resource res = getResource(resourceIdentifier);
if (res != null && res.getChildrenMap() != null && res.getChildrenMap().get(key) != null) {
res.getChildrenMap().get(key).changeState(childState);
}
state.addChildState(key, childState);
createInfo.getValue().addAll(childInfo.getValue());
createInfo = new AbstractMap.SimpleEntry<>(state, createInfo.getValue());
}
}
}
return createInfo;
}
}
}
if (curResVar != null && resCurStateVal != null) {
if (resStateValue instanceof Term) {
resStateValue = ((Term) resStateValue).substitute(curResVar, resCurStateVal);
resStateValue = ((Term) resStateValue).reduce();
}
}
if (resStateValue instanceof Constant) {
Resource res = getResource(resourceIdentifier);
ResourceState state = null;
if (res != null) {
state = res.getState();
((PrimitiveResourceState) state).setValue((Constant) resStateValue);
} else {
state = new PrimitiveResourceState((Constant) resStateValue);
}
List<ResourceIdentifier> updatedResources = new ArrayList<>();
updatedResources.add(resourceIdentifier);
return new AbstractMap.SimpleEntry<>(state, updatedResources);
}
return null;
}
public Map<DataTransferChannel, ChannelState> getChannelStates() {
return channelStates;
}
public ChannelState getChannelState(DataTransferChannel channel) {
return channelStates.get(channel);
}
public void addChannel(DataTransferChannel channel) {
channelStates.put(channel, null);
}
public void updateChannelState(DataTransferChannel channel, ChannelState channelState) {
channelStates.put(channel, channelState);
}
public List<Event> getEvents() {
return events;
}
public void addEvent(Event event) {
events.add(event);
}
}