package models.dataConstraintModel;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import models.algebra.Expression;
import models.algebra.Term;
import models.algebra.Type;
import models.algebra.Variable;
public class ResourceHierarchy {
private ResourceHierarchy parent = null;
private Set<ResourceHierarchy> children = null;
private String resourceName = null;
private Type resourceStateType = null;
private int numParameters = 0;
protected Expression initialValue;
protected String initText;
protected boolean isNative = false;
public ResourceHierarchy(String resourceName) {
this.parent = null;
this.children = new HashSet<>();
this.resourceName = resourceName;
this.numParameters = 0;
}
public ResourceHierarchy(String resourceName, Type resourceStateType) {
this.parent = null;
this.children = new HashSet<>();
this.resourceName = resourceName;
this.numParameters = 0;
this.resourceStateType = resourceStateType;
}
public ResourceHierarchy(ResourceHierarchy parent, String resourceName) {
this.parent = parent;
this.children = new HashSet<>();
this.resourceName = resourceName;
this.numParameters = 0;
if (parent != null) {
parent.addChild(this);
if (parent.getResourceStateType() == null) {
parent.setResourceStateType(DataConstraintModel.typeJson);
}
}
}
public ResourceHierarchy(ResourceHierarchy parent, String resourceName, Type resourceStateType) {
this.parent = parent;
this.children = new HashSet<>();
this.resourceName = resourceName;
this.numParameters = 0;
this.resourceStateType = resourceStateType;
if (parent != null) {
parent.addChild(this);
if (parent.getResourceStateType() == null) {
parent.setResourceStateType(DataConstraintModel.typeJson);
}
}
}
public ResourceHierarchy(ResourceHierarchy parent, int numParameters) {
this.parent = parent;
this.children = new HashSet<>();
this.resourceName = null;
this.numParameters = numParameters;
if (parent != null) {
parent.addChild(this);
}
}
public ResourceHierarchy(ResourceHierarchy parent, Expression parameterExp) {
this.parent = parent;
this.children = new HashSet<>();
this.resourceName = null;
this.numParameters = 1;
if (parent != null) {
parent.addChild(this);
if (parent.getResourceStateType() == null) {
Type paramType = null;
if (parameterExp instanceof Variable) {
paramType = ((Variable) parameterExp).getType();
} else if (parameterExp instanceof Term) {
paramType = ((Term) parameterExp).getType();
}
if (paramType != null) {
if (paramType.equals(DataConstraintModel.typeInt)) {
parent.setResourceStateType(DataConstraintModel.typeList);
} else if (paramType.equals(DataConstraintModel.typeString)) {
parent.setResourceStateType(DataConstraintModel.typeMap);
}
}
}
}
}
public ResourceHierarchy(ResourceHierarchy parent, Expression parameterExp, Type resourceStateType) {
this.parent = parent;
if (this.children == null) this.children = new HashSet<>();
this.resourceName = null;
this.numParameters = 1;
this.resourceStateType = resourceStateType;
if (parent != null) {
parent.addChild(this);
if (parent.getResourceStateType() == null) {
Type paramType = null;
if (parameterExp instanceof Variable) {
paramType = ((Variable) parameterExp).getType();
} else if (parameterExp instanceof Term) {
paramType = ((Term) parameterExp).getType();
}
if (paramType.equals(DataConstraintModel.typeInt)) {
parent.setResourceStateType(DataConstraintModel.typeList);
} else if (paramType.equals(DataConstraintModel.typeString)) {
parent.setResourceStateType(DataConstraintModel.typeMap);
}
}
}
}
public ResourceHierarchy(ResourceHierarchy parent, int numParameters, Type resourceStateType) {
this.parent = parent;
if (this.children == null) this.children = new HashSet<>();
this.resourceName = null;
this.numParameters = numParameters;
this.resourceStateType = resourceStateType;
if (parent != null) {
parent.addChild(this);
}
}
public ResourceHierarchy getParent() {
return parent;
}
public void setParent(ResourceHierarchy parent) {
this.parent = parent;
if (parent != null) {
parent.addChild(this);
}
}
public Set<ResourceHierarchy> getChildren() {
return children;
}
protected void addChild(ResourceHierarchy child) {
children.add(child);
}
public ResourceHierarchy getRoot() {
if (parent == null) return this;
return parent.getRoot();
}
public boolean isAncestorOf(ResourceHierarchy another) {
if (another == null) return false;
if (this == another) return true;
return isAncestorOf(another.getParent());
}
public String getResourceName() {
if (resourceName == null) return parent.getResourceName();
return resourceName;
}
public void setResourceName(String resourceName) {
this.resourceName = resourceName;
}
public Type getResourceStateType() {
return resourceStateType;
}
public void setResourceStateType(Type resourceStateType) {
this.resourceStateType = resourceStateType;
if (initialValue != null) {
if (initialValue instanceof Term) {
((Term) initialValue).setType(resourceStateType);
}
}
}
public int getNumParameters() {
return numParameters;
}
public int getTotalNumParameters() {
if (parent == null) return numParameters;
return numParameters + parent.getTotalNumParameters();
}
public void setNumParameters(int numParameters) {
this.numParameters = numParameters;
}
public Expression getInitialValue() {
return initialValue;
}
public void setInitialValue(Expression initialValue) {
this.initialValue = initialValue;
}
public String getInitText() {
return initText;
}
public void setInitText(String initText) {
this.initText = initText;
}
public boolean isNative() {
return isNative;
}
public void setNative(boolean isNative) {
this.isNative = isNative;
}
public String toString() {
if (parent == null) return resourceName;
if (resourceName != null) {
return parent.toString() + "." + resourceName;
} else {
return parent.toString() + ".{}";
}
}
public String toString(List<Map.Entry<Expression, Expression>> pathParams) {
if (parent == null) return resourceName;
if (resourceName != null) {
return parent.toString(pathParams) + "." + resourceName;
} else {
Map.Entry<Expression, Expression> lastParam = pathParams.get(pathParams.size() - 1);
pathParams = pathParams.subList(0, pathParams.size() - 1);
if (lastParam.getValue() == null) {
return parent.toString(pathParams) + ".{" + lastParam.getKey() +"}";
}
return parent.toString(pathParams) + ".{" + lastParam.getKey() + "=" + lastParam.getValue() +"}";
}
}
public String toResourcePath(List<String> pathParams) {
if (parent == null) return resourceName;
if (resourceName != null) {
return parent.toResourcePath(pathParams) + "/" + resourceName;
} else {
String lastParam = pathParams.get(pathParams.size() - 1);
pathParams = pathParams.subList(0, pathParams.size() - 1);
return parent.toResourcePath(pathParams) + "/" + lastParam;
}
}
}