package net.sourceforge.fenixedu.domain.tests; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.Stack; import net.sourceforge.fenixedu.commons.Permutations; import net.sourceforge.fenixedu.domain.tests.predicates.PredicateType; import org.apache.commons.collections.CollectionUtils; public class NewQuestionGroup extends NewQuestionGroup_Base { public NewQuestionGroup() { super(); } public NewQuestionGroup(NewQuestionGroup parentQuestionGroup, String name) { this(); this.init(parentQuestionGroup); this.setName(name); } public List getChildQuestions() { List questions = new ArrayList(); for (NewGroupElement groupElement : getChildElements()) { questions.add(groupElement.getChild()); } return questions; } public Integer getChildQuestionsCount() { return this.getChildQuestions().size(); } public List getOrderedChildQuestionGroups() { List questionGroups = this.getChildQuestionGroups(); Collections.sort(questionGroups, QUESTION_GROUP_COMPARATOR); return questionGroups; } public List getOrderedChildAtomicQuestions() { List questions = this.getChildAtomicQuestions(); Collections.sort(questions, new AtomicQuestionComparator(this)); return questions; } @Override public boolean isComposite() { return true; } public int getChildQuestionGroupsCount() { return getChildQuestionGroups().size(); } public List getChildQuestionGroups() { List questionGroups = (List) CollectionUtils.select(getChildQuestions(), COMPOSITE_QUESTION_PREDICATE); return questionGroups; } public int getChildAtomicQuestionsCount() { return getChildAtomicQuestions().size(); } public List getChildAtomicQuestions() { List questions = (List) CollectionUtils.selectRejected(getChildQuestions(), COMPOSITE_QUESTION_PREDICATE); return questions; } /** * Cleans sorting of child questions. Should be called after deleting a * child. Non composite questions are attributed a number. Composite * questions are left with zero. */ public void resortChildQuestions() { int i = 1; List groupElements = new ArrayList(this.getChildElements()); Collections.sort(groupElements, NewGroupElement.POSITION_COMPARATOR); for (NewGroupElement groupElement : groupElements) { if (COMPOSITE_QUESTION_PREDICATE.evaluate(groupElement.getChild())) { groupElement.setPosition(0); } else { groupElement.setPosition(i++); } } } @Override public void delete() { for (NewGroupElement childElement : this.getChildElements()) { NewQuestion child = childElement.getChild(); this.removeChildElements(childElement); childElement.deleteDown(); if (child.getParentElementsCount() == 0) { child.delete(); } } super.delete(); } public List getAllChildQuestionGroups() { Set results = new HashSet(); List childQuestionGroups = this.getOrderedChildQuestionGroups(); results.addAll(childQuestionGroups); for (NewQuestionGroup childQuestionGroup : childQuestionGroups) { results.addAll(childQuestionGroup.getAllChildQuestionGroups()); } return new ArrayList(results); } public List getAllChildAtomicQuestions() { Stack stack = new Stack(); Set results = new HashSet(); stack.add(this); while (stack.size() > 0) { NewQuestion question = stack.pop(); if (question.isComposite()) { stack.addAll(((NewQuestionGroup) question).getChildQuestions()); } else { results.add(question); } } return new ArrayList(results); } public int getAllChildAtomicQuestionsCount() { return getAllChildAtomicQuestions().size(); } @Override public Integer getNewPosition(NewQuestionGroup parentQuestionGroup) { return 0; } public void disassociate(NewQuestion child) { for (NewGroupElement childElement : this.getChildElements()) { if (childElement.getChild().equals(child)) { childElement.deleteBothWays(); } } } @Override public NewQuestionType getQuestionType() { return null; } @Override public List getPredicates() { return null; } @Override public NewTestElement copy(HashMap transformationMap) { throw new IllegalArgumentException("class.not.clonable"); } transient Permutations permutations; @Override public List provide(int count) { List questions = this.getAllChildAtomicQuestions(); if (questions.isEmpty()) { return null; } if (count > this.getAllChildAtomicQuestionsCount()) { count = this.getAllChildAtomicQuestionsCount(); } if (permutations == null) { permutations = new Permutations(questions, count); } List permutation = permutations.nextElement(); if (!permutations.hasMoreElements()) { permutations = null; } for (NewQuestion question : permutation) { question.setTimesUsed(question.getTimesUsed() + 1); } return permutation; } public boolean isGradeComplete() { int grades = 0; for (NewQuestion question : this.getChildAtomicQuestions()) { if (question.getGrade() != null) { grades++; } } return (grades == 0 || grades == this.getChildAtomicQuestionsCount()); } }