package nl.uva.polyql.ast;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import nl.uva.polyql.ast.expressions.Expression;
public abstract class RuleContainer {
private final List<Rule> mRules = new LinkedList<>();
private final List<RuleContainer> mRuleContainers = new LinkedList<>();
private final Map<String, Question> mQuestions = new HashMap<>();
public Question addQuestion(final String id, final String content, final String type) {
final Question question = new Question(id, content, type);
addQuestion(question);
return question;
}
public CalculatedQuestion addCalculatedQuestion(final String id, final String content, final String type,
final Expression expression) {
final CalculatedQuestion calculatedQuestion = new CalculatedQuestion(id, content, type, expression);
addQuestion(calculatedQuestion);
return calculatedQuestion;
}
private void addQuestion(final Question question) {
mQuestions.put(question.getId(), question);
mRules.add(question);
}
public IfStatement addIfStatement(final Expression expression) {
final IfStatement child = new IfStatement(this, expression);
mRuleContainers.add(child);
mRules.add(child);
return child;
}
public ElseStatement addElseStatement(final Expression expression) {
final ElseStatement child = new ElseStatement(this, expression);
mRuleContainers.add(child);
mRules.add(child);
return child;
}
/**
* Retrieves the list of rules within this container. Does not include the parent's rules.
*
* @return This container's rules
*/
public List<Rule> getRules() {
return mRules;
}
/**
* Retrieves all rules within this container and its children containers.
*
* @return All questions in the hierarchy
*/
public List<Question> getQuestionsRecursively() {
final List<Question> questions = new LinkedList<>();
questions.addAll(mQuestions.values());
for (final RuleContainer container : mRuleContainers) {
questions.addAll(container.getQuestionsRecursively());
}
return questions;
}
/**
* Finds a question based on the ID through a recursive upward search. Doesn't find questions
* defined in scopes that sibling this container's hierarchy.
*
* @param id
* The question ID to find
*
* @return The question matching the given ID or null if it wasn't found
*/
public Question getQuestion(final String id) {
if (mQuestions.containsKey(id)) {
return mQuestions.get(id);
}
final RuleContainer parent = getParent();
if (parent != null) {
return parent.getQuestion(id);
}
return null;
}
/**
* Can be override to supply a parent.
*
* @return null by default, or a parent when overridden
*/
public RuleContainer getParent() {
return null;
}
}