/* * QuestionSet.java * * Created on 04 September 2006, 17:17 */ package uk.co.bytemark.vm.enigma.inquisition.questions; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.List; import uk.co.bytemark.vm.enigma.inquisition.misc.Utils; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; /** * * A set of {@link Question}s bundle together with information about the set. */ public class QuestionSet implements Iterable<Question>, Serializable { private final String name; private final String description; private final int recommendedTimePerQuestion; // in seconds private final String category; private final List<Question> questions; /** * Creates a new instance of <tt>QuestionSet</tt> * * @param name * the name or title of this set of questions. * @param description * description and other information, in HTML text. * @param recommendedTimePerQuestion * suggested time, in seconds, needed to answer one question. * @param category * a colon (:) delimited string showing where in the category hierarchy the question set lies. * @param questions * list of <tt>Question</tt>s. */ public QuestionSet(String name, String description, int recommendedTimePerQuestion, String category, List<Question> questions) { Utils.checkArgumentNotNull(name, "name"); Utils.checkArgumentNotNull(description, "description"); Utils.checkPositive(recommendedTimePerQuestion, "recommendedTimePerQuestion"); Utils.checkArgumentNotNull(category, "category"); Utils.checkArgumentNotNull(questions, "questions"); Preconditions.checkContentsNotNull(questions, "No question can be null"); this.name = name; this.description = description; this.recommendedTimePerQuestion = recommendedTimePerQuestion; this.category = category; this.questions = ImmutableList.copyOf(questions); } public String getName() { return name; } public String getDescription() { return description; } public List<Question> getQuestions() { return Collections.unmodifiableList(questions); } public int getRecommendedTimePerQuestion() { return recommendedTimePerQuestion; } public int getRecommendedTimeForAllQuestions() { return recommendedTimePerQuestion * numberOfQuestions(); } public int numberOfQuestions() { return questions.size(); } public int size() { return numberOfQuestions(); } public List<String> getCategoryList() { if (category == null || category.equals("")) return Collections.emptyList(); else return Arrays.asList(category.split(":")); } public String getCategorySequence() { return category; } @Override public String toString() { return QuestionSet.class.getSimpleName() + "(\"" + getName() + "\")"; } /** * Returns the number of instances of a class type in the question set * * @param c * The class type in question */ public int numberOfType(Class<? extends Question> c) { int count = 0; for (Question question : questions) if (c.isInstance(question)) count++; return count; } public Iterator<Question> iterator() { return Collections.unmodifiableList(questions).iterator(); } public static class QuestionSetBuilder { private String name = null; private String description = ""; private int recommendedTimePerQuestion = 30; private String category = ""; private final List<Question> questions = new ArrayList<Question>(); public QuestionSet build() { if (name == null) throw new IllegalStateException("Name required"); return new QuestionSet(name, description, recommendedTimePerQuestion, category, questions); } public QuestionSetBuilder name(String name_) { this.name = name_; return this; } public QuestionSetBuilder description(String description_) { this.description = description_; return this; } public QuestionSetBuilder recommendedTime(int recommendedTime_) { this.recommendedTimePerQuestion = recommendedTime_; return this; } public QuestionSetBuilder category(String category_) { this.category = category_; return this; } public QuestionSetBuilder addQuestions(Question... questions_) { for (Question question : questions_) this.questions.add(question); return this; } public QuestionSetBuilder addQuestion(Question question) { this.questions.add(question); return this; } } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((category == null) ? 0 : category.hashCode()); result = prime * result + ((description == null) ? 0 : description.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + ((questions == null) ? 0 : questions.hashCode()); result = prime * result + recommendedTimePerQuestion; return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; final QuestionSet other = (QuestionSet) obj; if (category == null) { if (other.category != null) return false; } else if (!category.equals(other.category)) return false; if (description == null) { if (other.description != null) return false; } else if (!description.equals(other.description)) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; if (questions == null) { if (other.questions != null) return false; } else if (!questions.equals(other.questions)) return false; if (recommendedTimePerQuestion != other.recommendedTimePerQuestion) return false; return true; } }