package models.dataFlowModel;
import java.util.AbstractMap;
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import models.Node;
import models.algebra.Expression;
import models.algebra.Type;
import models.dataConstraintModel.ResourceHierarchy;
import models.dataConstraintModel.ResourcePath;
import models.dataConstraintModel.Selector;
public class ResourceNode extends Node {
protected ResourceNode parent = null;
protected Set<ResourceNode> children = null;
protected ResourceHierarchy resourceHierarchy = null;
protected ResourcePath primaryResourcePath = null; // for temporal use at the modeling stage
protected Map<DataTransferChannel, ResourcePath> inSide = null;
protected Map<DataTransferChannel, ResourcePath> outSide = null;
protected List<Selector> selectors = null;
public ResourceNode(ResourceNode parent, ResourcePath primaryResourcePath) {
this.parent = parent;
this.children = new HashSet<>();
this.inSide = new HashMap<>();
this.outSide = new HashMap<>();
this.resourceHierarchy = primaryResourcePath.getResourceHierarchy();
this.primaryResourcePath = primaryResourcePath;
this.selectors = new ArrayList<>();
if (resourceHierarchy.getNumParameters() > 0) {
List<Expression> pathParams = primaryResourcePath.getPathParams();
selectors.add(new Selector(pathParams.get(pathParams.size() - 1)));
}
}
public ResourceNode(ResourceNode parent, ResourcePath outSideResource, DataTransferChannel outSideChannel) {
this.parent = parent;
this.children = new HashSet<>();
this.inSide = new HashMap<>();
this.outSide = new HashMap<>();
this.outSide.put(outSideChannel, outSideResource);
this.resourceHierarchy = outSideResource.getResourceHierarchy();
this.selectors = new ArrayList<>();
if (resourceHierarchy.getNumParameters() > 0) {
if (outSideChannel != null) {
selectors.addAll(outSideChannel.getSelectors());
} else {
List<Expression> pathParams = outSideResource.getPathParams();
selectors.add(new Selector(pathParams.get(pathParams.size() - 1)));
}
}
}
public ResourceNode(ResourceNode parent, ResourcePath resource, DataTransferChannel channel, boolean isInside) {
this.parent = parent;
this.children = new HashSet<>();
this.inSide = new HashMap<>();
this.outSide = new HashMap<>();
if (isInside) {
this.inSide.put(channel, resource);
} else {
this.outSide.put(channel, resource);
}
this.resourceHierarchy = resource.getResourceHierarchy();
this.selectors = new ArrayList<>();
if (resourceHierarchy.getNumParameters() > 0) {
if (channel != null) {
selectors.addAll(channel.getSelectors());
} else {
List<Expression> pathParams = resource.getPathParams();
selectors.add(new Selector(pathParams.get(pathParams.size() - 1)));
}
}
}
public ResourceNode(ResourceNode parent, Map<DataTransferChannel, ResourcePath> outSide, Map<DataTransferChannel, ResourcePath> inSide) {
this.parent = parent;
this.children = new HashSet<>();
this.inSide = inSide;
this.outSide = outSide;
this.selectors = new ArrayList<>();
for (Map.Entry<DataTransferChannel, ResourcePath> outsideEnt: outSide.entrySet()) {
DataTransferChannel outSideChannel = outsideEnt.getKey();
ResourcePath outSideResource = outsideEnt.getValue();
if (this.resourceHierarchy == null) {
this.resourceHierarchy = outSideResource.getResourceHierarchy();
}
if (resourceHierarchy.getNumParameters() > 0) {
if (outSideChannel != null) {
selectors.addAll(outSideChannel.getSelectors());
} else {
List<Expression> pathParams = outSideResource.getPathParams();
selectors.add(new Selector(pathParams.get(pathParams.size() - 1)));
}
}
}
}
public ResourceHierarchy getResourceHierarchy() {
return resourceHierarchy;
}
public String getResourceName() {
return resourceHierarchy.getResourceName();
}
public Type getResourceStateType() {
return resourceHierarchy.getResourceStateType();
}
public int getNumberOfParameters() {
return resourceHierarchy.getTotalNumParameters();
}
public ResourceNode getParent() {
return parent;
}
public Set<ResourceNode> getChildren() {
return children;
}
public void addChild(ResourceNode child) {
children.add(child);
child.parent = this;
}
public ResourcePath getPrimaryResourcePath() {
if (primaryResourcePath != null) return primaryResourcePath;
if (outSide.size() > 0) return outSide.values().iterator().next();
return inSide.values().iterator().next();
}
public Collection<ResourcePath> getInSideResources() {
return inSide.values();
}
public ResourcePath getInSideResource(DataTransferChannel channel) {
return inSide.get(channel);
}
public Set<DataTransferChannel> getInSideChannels() {
return inSide.keySet();
}
public Collection<ResourcePath> getOutSideResources() {
return outSide.values();
}
public ResourcePath getOutSideResource(DataTransferChannel channel) {
return outSide.get(channel);
}
public Set<DataTransferChannel> getOutSideChannels() {
return outSide.keySet();
}
public void addInSideResource(DataTransferChannel channel, ResourcePath inResource) {
primaryResourcePath = null;
inSide.put(channel, inResource);
}
public void addOutSideResource(DataTransferChannel channel, ResourcePath outResource) {
primaryResourcePath = null;
outSide.put(channel, outResource);
}
public List<Selector> getSelectors() {
return selectors;
}
public Selector getLastSelector() {
return selectors.get(resourceHierarchy.getTotalNumParameters() - 1);
}
public List<Selector> getAllSelectors() {
List<Selector> selectors = new ArrayList<>();
if (parent != null) {
selectors.addAll(parent.getAllSelectors());
}
selectors.addAll(this.selectors);
return selectors;
}
// public boolean equals(Object another) {
// if (this == another) return true;
// if (!(another instanceof ResourceNode)) return false;
// return resourcePath.equals(((ResourceNode)another).resourcePath);
// }
//
// public int hashCode() {
// return resourcePath.hashCode();
// }
//
// public String toString() {
// return resourcePath.toString();
// }
}