package models.terms;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import lombok.Getter;
import models.algebra.Symbol;
@Getter
public class Dependency extends RDLTerm{
private RDLTerm dependingTerm;
private List<Resource> dependedResources;
private Dependency dependency;
private boolean isListType;
// public Dependency(RDLTerm dependingTerm, Resource dependedVariable) {
// super(new Symbol(":", 2), dependedVariable.getOrder(), dependingTerm.getSize() + dependedVariable.getSize());
// this.dependingTerm = dependingTerm;
// this.dependedVariable = dependedVariable;
// this.dependency = null;
// this.addChild(dependingTerm);
// this.addChild(dependedVariable);
// this.isListType = false;
// }
public Dependency(RDLTerm dependingTerm, List<Resource> dependedResources) {
super(new Symbol(":", dependedResources.size() + 1), dependedResources.get(0).getOrder(), dependingTerm.getSize() + dependedResources.stream().mapToInt(v -> v.size).sum());
this.dependingTerm = dependingTerm;
this.dependedResources = dependedResources;
this.dependency = null;
this.addChild(dependingTerm);
for (Resource dependedResource: dependedResources) {
this.addChild(dependedResource);
}
this.isListType = false;
}
public Dependency(RDLTerm dependingTerm, Resource ...dependedResources) {
this(dependingTerm, Arrays.asList(dependedResources));
}
public Dependency(Dependency dependency) {
super(new Symbol(":", 1), dependency.getOrder() - 1, dependency.getSize());
this.dependency = dependency;
this.dependingTerm = null;
this.dependedResources = null;
this.addChild(dependency);
this.isListType = true;
}
// public Dependency(RDLTerm dependingTerm, Resource dependedVariable, int order) {
// super(new Symbol(":", order == dependedVariable.order ? 2 : 1), order, dependingTerm.getSize() + dependedVariable.getSize());
// if(order == dependedVariable.order) {
// this.dependingTerm = dependingTerm;
// this.dependedResources = dependedVariable;
// this.addChild(dependingTerm);
// this.addChild(dependedVariable);
// this.dependency = null;
// this.isListType = false;
// } else {
// this.dependency = new Dependency(dependingTerm, dependedVariable, order+1);
// this.dependingTerm = null;
// this.dependedResources = null;
// this.addChild(dependency);
// this.isListType = true;
// }
// }
public Dependency getDependency() {
return this.dependency;
}
@Override
public int getTermOrder() {
return getOrder() - 1;
}
public boolean isDependeingTermEvaluatable() {
return dependingTerm instanceof EvaluatableTerm;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
if(dependency == null) {
sb.append(dependingTerm.toTermString());
sb.append(" : ");
sb.append(dependedResources.toString());
} else {
sb.append('[');
sb.append(dependency.toString());
sb.append(']');
}
return sb.toString();
}
@Override
public String toStringWithOrder() {
StringBuilder sb = new StringBuilder();
if(dependency == null) {
sb.append(dependingTerm.toStringWithOrder());
sb.append(" : ");
sb.append(dependedResources.stream().map(RDLTerm::toStringWithOrder).collect(Collectors.joining(", ")));
} else {
sb.append('[');
sb.append(dependency.toStringWithOrder());
sb.append(']');
}
return sb.toString() + "(" + order + ")";
}
@Override
public String toTermString() {
return "[" + toString() + "]";
}
@Override
public boolean equals(Object another) {
if(! (another instanceof Dependency)) {
return false;
}
Dependency anotherDep = (Dependency) another;
if(anotherDep.isListType() != isListType()) {
return false;
}
if(isListType()) {
return anotherDep.getDependency().equals(dependency);
}
return anotherDep.getDependingTerm().equals(dependingTerm)
&& anotherDep.getDependedResources().equals(dependedResources);
}
@Override
public int hashCode() {
return ("Dep" + toString()).hashCode();
}
@Override
public Object clone() {
return new Dependency((RDLTerm) dependingTerm.clone(), new ArrayList<>(dependedResources));
}
}