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.dataConstraintModel.DataConstraintModel; import models.dataFlowModel.DataTransferChannel; import simulator.states.JsonResourceState; import simulator.states.ListResourceState; import simulator.states.MapResourceState; import simulator.states.PrimitiveResourceState; import simulator.states.ResourceState; 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) { rootResources = new HashSet<>(prevState.getRootResources()); channelStates = new HashMap<>(prevState.getChannelStates()); } 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 ResourceIdentifier updateResourceState(ResourceIdentifier resourceIdentifier, Expression resStateValue) { Type resType = resourceIdentifier.getResourceStateType(); if (DataConstraintModel.typeList.isAncestorOf(resType)) { if (resStateValue instanceof Constant) { } else if (resStateValue instanceof Term) { Term listValue = (Term) resStateValue; if (listValue.getSymbol().equals(DataConstraintModel.append)) { Resource res = getResource(resourceIdentifier); ResourceState state = res.getState(); Expression childExp = new Constant(Integer.toString(((ListResourceState) state).getChildStates().size())); ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, resourceIdentifier.getResourceHierarchy().getChildren().iterator().next()); Map.Entry<ResourceState, ResourceIdentifier> childInfo = createResourceState(childResourceIdentifier, listValue.getChild(1)); ((ListResourceState) state).addChildState(childInfo.getKey()); return childInfo.getValue(); } } } else if (DataConstraintModel.typeMap.isAncestorOf(resType)) { if (resStateValue instanceof Constant) { } else if (resStateValue instanceof Term) { Term mapValue = (Term) resStateValue; if (mapValue.getSymbol().equals(DataConstraintModel.insert)) { Expression childExp = mapValue.getChild(1); if (childExp instanceof Constant) { Resource res = getResource(resourceIdentifier); ResourceState state = res.getState(); ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, resourceIdentifier.getResourceHierarchy().getChildren().iterator().next()); String childId = ((Constant) childExp).toString(); Map.Entry<ResourceState, ResourceIdentifier> childInfo = createResourceState(childResourceIdentifier, mapValue.getChild(2)); ((MapResourceState) state).addChildState(childId, childInfo.getKey()); return childInfo.getValue(); } } } } else if (DataConstraintModel.typeJson.isAncestorOf(resType)) { if (resStateValue instanceof Constant) { } else if (resStateValue instanceof Term) { Term jsonValue = (Term) resStateValue; if (jsonValue.getSymbol().equals(DataConstraintModel.addMember)) { Expression childExp = jsonValue.getChild(1); if (childExp instanceof Constant) { Resource res = getResource(resourceIdentifier); ResourceState state = res.getState(); ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, resourceIdentifier.getResourceHierarchy().getChildren().iterator().next()); String childId = ((Constant) childExp).toString(); Map.Entry<ResourceState, ResourceIdentifier> childInfo = createResourceState(childResourceIdentifier, jsonValue.getChild(2)); ((JsonResourceState) state).addChildState(childId, childInfo.getKey()); return childInfo.getValue(); } } } } else { 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); } return resourceIdentifier; } } return resourceIdentifier; } public Map.Entry<ResourceState, ResourceIdentifier> createResourceState(ResourceIdentifier resourceIdentifier, Expression resStateValue) { Type resType = null; if (resStateValue instanceof Term) { resType = ((Term) resStateValue).getType(); } if (resType != null) { if (DataConstraintModel.typeList.isAncestorOf(resType)) { if (resStateValue instanceof Constant) { } else if (resStateValue instanceof Term) { Term listValue = (Term) resStateValue; if (listValue.getSymbol().equals(DataConstraintModel.append)) { ListResourceState state = new ListResourceState(); Expression childExp = new Constant(Integer.toString(((ListResourceState) state).getChildStates().size())); ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, resourceIdentifier.getResourceHierarchy().getChildren().iterator().next()); Map.Entry<ResourceState, ResourceIdentifier> childInfo = createResourceState(childResourceIdentifier, listValue.getChild(1)); state.addChildState(childInfo.getKey()); return new AbstractMap.SimpleEntry<>(state, childInfo.getValue()); } } } else if (DataConstraintModel.typeMap.isAncestorOf(resType)) { if (resStateValue instanceof Constant) { } else if (resStateValue instanceof Term) { Term mapValue = (Term) resStateValue; if (mapValue.getSymbol().equals(DataConstraintModel.insert)) { Expression childExp = mapValue.getChild(1); if (childExp instanceof Constant) { MapResourceState state = new MapResourceState(); ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, childExp, resourceIdentifier.getResourceHierarchy().getChildren().iterator().next()); String childId = ((Constant) childExp).toString(); Map.Entry<ResourceState, ResourceIdentifier> childInfo = createResourceState(childResourceIdentifier, mapValue.getChild(2)); state.addChildState(childId, childInfo.getKey()); return new AbstractMap.SimpleEntry<>(state, childInfo.getValue()); } } } } else if (DataConstraintModel.typeJson.isAncestorOf(resType)) { if (resStateValue instanceof Constant) { } else if (resStateValue instanceof Term) { Term jsonValue = (Term) resStateValue; if (jsonValue.getSymbol().equals(DataConstraintModel.addMember)) { Expression childExp = jsonValue.getChild(1); if (childExp instanceof Constant) { JsonResourceState state = new JsonResourceState(); ResourceIdentifier childResourceIdentifier = new ResourceIdentifier(resourceIdentifier, ((Constant) childExp).getSymbol().getName(), resourceIdentifier.getResourceHierarchy().getChildren().iterator().next()); String childId = ((Constant) childExp).toString(); Map.Entry<ResourceState, ResourceIdentifier> childInfo = createResourceState(childResourceIdentifier, jsonValue.getChild(2)); state.addChildState(childId, childInfo.getKey()); return new AbstractMap.SimpleEntry<>(state, childInfo.getValue()); } } } } else { 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); } return new AbstractMap.SimpleEntry<>(state, resourceIdentifier); } } } 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); } }