package models.terms;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;
import exceptions.SyntaxException;
import lombok.Getter;
import models.algebra.Symbol;
@Getter
public class Dependency extends RDLTerm{
private RDLTerm dependingTerm;
private TreeSet<EvaluatableTerm> dependedTerms;
public Dependency(RDLTerm dependingTerm, Set<EvaluatableTerm> dependedTerms) {
super(new Symbol(":", dependedTerms.size() + 1), dependedTerms.iterator().next().getOrder(), dependingTerm.getSize() + dependedTerms.stream().mapToInt(v -> v.size).sum());
this.dependingTerm = dependingTerm;
this.dependedTerms = new TreeSet<>(dependedTerms);
this.addChild(dependingTerm);
if (dependingTerm.getTermOrder() > getOrder()) {
throw new SyntaxException("dependingTerm's order must be less than " + (getOrder() + 1) + ", but " + dependingTerm + "'s order is " + dependingTerm.getOrder());
}
for (EvaluatableTerm dependedTerm: dependedTerms) {
this.addChild(dependedTerm);
if (dependedTerm.getTermOrder() != getOrder()) {
throw new SyntaxException(dependedTerm + " order is not " + getOrder());
}
}
}
public Dependency(RDLTerm dependingTerm, EvaluatableTerm ...dependedTerms) {
this(dependingTerm, new TreeSet<>(Arrays.asList(dependedTerms)));
}
public Dependency(RDLTerm dependingTerm, List<EvaluatableTerm>dependedTerms) {
this(dependingTerm, new TreeSet<>(dependedTerms));
}
@Override
public int getTermOrder() {
return getOrder() - 1;
}
public boolean isDependeingTermEvaluatable() {
return dependingTerm instanceof EvaluatableTerm;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(dependingTerm.toTermString());
sb.append(" : ");
sb.append(dependedTerms.stream().map(RDLTerm::toString).collect(Collectors.joining(", ")));
return sb.toString();
}
@Override
public String toStringWithOrder() {
StringBuilder sb = new StringBuilder();
sb.append(dependingTerm.toStringWithOrder());
sb.append(" : ");
sb.append(dependedTerms.stream().map(RDLTerm::toStringWithOrder).collect(Collectors.joining(", ")));
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;
return anotherDep.getDependingTerm().equals(dependingTerm)
&& anotherDep.getDependedTerms().equals(dependedTerms);
}
@Override
public int hashCode() {
return ("Dep" + toString()).hashCode();
}
@Override
public Object clone() {
return new Dependency((RDLTerm) dependingTerm.clone(), new TreeSet<>(dependedTerms));
}
}