Newer
Older
AlgebraicDataflowArchitectureModel / AlgebraicDataflowArchitectureModel / src / simulator / SystemState.java
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);
	}
}