package nl.uva.softwcons.qls.validation.questionidentifier;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import nl.uva.softwcons.ql.ast.LineInfo;
import nl.uva.softwcons.ql.ast.expression.identifier.Identifier;
import nl.uva.softwcons.ql.ast.form.Form;
import nl.uva.softwcons.ql.validation.Checker;
import nl.uva.softwcons.ql.validation.Error;
import nl.uva.softwcons.ql.validation.identifier.error.DuplicateQuestionIdentifier;
import nl.uva.softwcons.qls.ast.segment.Page;
import nl.uva.softwcons.qls.ast.segment.Question;
import nl.uva.softwcons.qls.ast.segment.Section;
import nl.uva.softwcons.qls.ast.segment.SegmentVisitor;
import nl.uva.softwcons.qls.ast.stylesheet.Stylesheet;
import nl.uva.softwcons.qls.ast.stylesheet.StylesheetVisitor;
import nl.uva.softwcons.qls.validation.questionidentifier.error.MissingQuestionIdentifier;
import nl.uva.softwcons.qls.validation.questionidentifier.error.UnknownQuestionIdentifier;
public final class QuestionIdentifierChecker extends Checker implements StylesheetVisitor<List<Error>>,
SegmentVisitor<Void> {
private final Set<Identifier> formQuestionsIdentifiers;
private final Set<Identifier> stylesheetQuestionsIdentifiers;
public static List<Error> check(final Stylesheet stylesheet, final Form form) {
return stylesheet.accept(new QuestionIdentifierChecker(form));
}
private QuestionIdentifierChecker(final Form form) {
this.formQuestionsIdentifiers = FormQuestionCollector.collectFrom(form);
this.stylesheetQuestionsIdentifiers = new HashSet<Identifier>();
}
@Override
public List<Error> visit(final Stylesheet stylesheet) {
stylesheet.getPages().forEach(p -> p.accept(this));
final Set<Identifier> missingIdentifiers = getMissingIdentifiers();
if (!missingIdentifiers.isEmpty()) {
this.addError(new MissingQuestionIdentifier(missingIdentifiers));
}
return this.getErrors();
}
@Override
public Void visit(final Page page) {
page.getSegments().forEach(s -> s.accept(this));
return null;
}
@Override
public Void visit(final Question question) {
final Identifier currentIdentifier = question.getId();
final LineInfo currentLineInfo = question.getLineInfo();
if (!formQuestionsIdentifiers.contains(currentIdentifier)) {
this.addError(new UnknownQuestionIdentifier(currentLineInfo));
}
if (stylesheetQuestionsIdentifiers.contains(currentIdentifier)) {
this.addError(new DuplicateQuestionIdentifier(currentLineInfo));
}
stylesheetQuestionsIdentifiers.add(currentIdentifier);
return null;
}
@Override
public Void visit(final Section section) {
section.getContent().forEach(c -> c.accept(this));
return null;
}
private Set<Identifier> getMissingIdentifiers() {
final Set<Identifier> missingIdentifiers = new HashSet<Identifier>(formQuestionsIdentifiers);
missingIdentifiers.removeAll(stylesheetQuestionsIdentifiers);
return missingIdentifiers;
}
}