Java tutorial
/******************************************************************************* * Copyright (c) 2014 antoniomariasanchez at gmail.com. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html * * Contributors: * antoniomaria - initial API and implementation ******************************************************************************/ package net.sf.gazpachoquest.questionnaire.resolver; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import net.sf.gazpachoquest.domain.core.Breadcrumb; import net.sf.gazpachoquest.domain.core.Question; import net.sf.gazpachoquest.domain.core.QuestionBreadcrumb; import net.sf.gazpachoquest.domain.core.Questionnaire; import net.sf.gazpachoquest.domain.core.QuestionnaireDefinition; import net.sf.gazpachoquest.domain.core.Section; import net.sf.gazpachoquest.domain.core.Section.Builder; import net.sf.gazpachoquest.qbe.SearchParameters; import net.sf.gazpachoquest.questionnaire.support.PageMetadataCreator; import net.sf.gazpachoquest.questionnaire.support.PageStructure; import net.sf.gazpachoquest.services.BreadcrumbService; import net.sf.gazpachoquest.services.QuestionService; import net.sf.gazpachoquest.services.QuestionnaireService; import net.sf.gazpachoquest.services.SectionService; import net.sf.gazpachoquest.types.RandomizationStrategy; import net.sf.gazpachoquest.types.RenderingMode; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.Assert; @Component("QuestionByQuestionResolver") public class QuestionByQuestionResolver extends AbstractResolver<QuestionBreadcrumb> implements PageResolver { private static final Integer INITIAL_POSITION = 0; @Autowired private BreadcrumbService breadcrumbService; @Autowired private SectionService sectionService; @Autowired private QuestionService questionService; @Autowired private QuestionnaireService questionnaireService; @Autowired private PageMetadataCreator metadataCreator; public QuestionByQuestionResolver() { super(RenderingMode.QUESTION_BY_QUESTION); } @Override protected List<QuestionBreadcrumb> makeBreadcrumbs(QuestionnaireDefinition questionnaireDefinition, Questionnaire questionnaire) { List<QuestionBreadcrumb> breadcrumbs = new ArrayList<>(); QuestionBreadcrumb breadcrumb = null; Integer questionnairDefinitionId = questionnaireDefinition.getId(); RandomizationStrategy randomizationStrategy = questionnaireDefinition.getRandomizationStrategy(); Integer questionNumberCounter = QUESTION_NUMBER_START_COUNTER; if (RandomizationStrategy.SECTIONS_RANDOMIZATION.equals(randomizationStrategy)) { List<Section> sections = sectionService.findByExample( Section.with() .questionnaireDefinition( QuestionnaireDefinition.with().id(questionnairDefinitionId).build()) .build(), new SearchParameters()); Collections.shuffle(sections); for (Section section : sections) { List<Question> questions = findQuestions(section); for (Question question : questions) { breadcrumb = QuestionBreadcrumb.with().questionnaire(questionnaire).last(Boolean.FALSE) .question(question).renderingMode(RenderingMode.QUESTION_BY_QUESTION) .questionNumber(questionNumberCounter++).build(); breadcrumbs.add(breadcrumb); } } } else if (RandomizationStrategy.QUESTIONS_RANDOMIZATION.equals(randomizationStrategy)) { List<Question> questions = questionnaireDefinitionService.getQuestions(questionnairDefinitionId); Collections.shuffle(questions); for (Question question : questions) { breadcrumb = QuestionBreadcrumb.with().questionnaire(questionnaire).last(Boolean.FALSE) .question(question).renderingMode(RenderingMode.QUESTION_BY_QUESTION) .questionNumber(questionNumberCounter++).build(); breadcrumbs.add(breadcrumb); } } else { Question question = findFirstQuestion(questionnairDefinitionId); breadcrumb = QuestionBreadcrumb.with().questionnaire(questionnaire).last(Boolean.FALSE) .renderingMode(RenderingMode.QUESTION_BY_QUESTION).question(question) .questionNumber(questionNumberCounter).build(); breadcrumbs.add(breadcrumb); } breadcrumbs.get(0).setLast(Boolean.TRUE); return breadcrumbs; } @Override protected QuestionBreadcrumb findNextBreadcrumb(QuestionnaireDefinition questionnaireDefinition, Questionnaire questionnaire, Map<String, Object> answers, QuestionBreadcrumb lastBreadcrumb, Integer lastBreadcrumbPosition) { Assert.notNull(lastBreadcrumbPosition, "Questionnaire not started for the given questionnaireId = " + lastBreadcrumbPosition); Breadcrumb breadcrumb = breadcrumbService.findByQuestionnaireIdAndPosition(questionnaire.getId(), lastBreadcrumbPosition + 1); QuestionBreadcrumb nextBreadcrumb = null; if (breadcrumb == null) { Assert.isInstanceOf(QuestionBreadcrumb.class, lastBreadcrumb); Section lastSection = lastBreadcrumb.getQuestion().getSection(); Integer position = questionService.findPositionInSection(lastBreadcrumb.getQuestion().getId()); long questionsCount = sectionService.questionsCount(lastSection.getId()); Question next = null; if (position < questionsCount - 1) { // Not last in group next = questionService.findOneByPositionInSection(lastSection.getId(), position + 1); } else { Integer sectionPosition = sectionService.positionInQuestionnaireDefinition(lastSection.getId()); Section nextSection = sectionService.findOneByPositionInQuestionnaireDefinition( questionnaireDefinition.getId(), sectionPosition + 1); if (nextSection == null) { return null; } next = questionService.findOneByPositionInSection(nextSection.getId(), INITIAL_POSITION); } // Mark next element as last browsed. nextBreadcrumb = QuestionBreadcrumb.with().questionnaire(questionnaire).question(next) .questionNumber(lastBreadcrumb.getQuestionNumber() + 1) .renderingMode(RenderingMode.QUESTION_BY_QUESTION).build(); } else { Assert.isInstanceOf(QuestionBreadcrumb.class, breadcrumb); nextBreadcrumb = (QuestionBreadcrumb) breadcrumb; } return nextBreadcrumb; } @Override protected QuestionBreadcrumb findPreviousBreadcrumb(QuestionnaireDefinition questionnaireDefinition, Questionnaire questionnaire, QuestionBreadcrumb lastBreadcrumb, Integer lastBreadcrumbPosition) { Assert.notNull(lastBreadcrumbPosition, "Questionnaire not started for the given questionnaireId = " + lastBreadcrumbPosition); if (lastBreadcrumbPosition == INITIAL_POSITION) { return null; } Breadcrumb breadcrumb = breadcrumbService.findByQuestionnaireIdAndPosition(questionnaire.getId(), lastBreadcrumbPosition - 1); Assert.isInstanceOf(QuestionBreadcrumb.class, breadcrumb); return (QuestionBreadcrumb) breadcrumb; } @Override protected List<Question> findQuestions(Section section) { List<Question> questions; if (section.isRandomizationEnabled()) { questions = questionService.findByExample( Question.with().section(Section.with().id(section.getId()).build()).build(), new SearchParameters()); shuffle(questions); } else { questions = questionService.findBySectionId(section.getId()); } return questions; } private Question findFirstQuestion(int questionnairDefinitionId) { Section initialGroup = sectionService.findOneByPositionInQuestionnaireDefinition(questionnairDefinitionId, INITIAL_POSITION); return questionService.findOneByPositionInSection(initialGroup.getId(), INITIAL_POSITION); } @Override protected PageStructure createPageStructure(RandomizationStrategy randomizationStrategy, List<QuestionBreadcrumb> breadcrumbs, Map<String, Object> answers) { PageStructure nextPage = super.createPageStructure(randomizationStrategy, breadcrumbs, answers); Breadcrumb active = breadcrumbs.get(0); QuestionBreadcrumb questionBreadcrumb = (QuestionBreadcrumb) active; Builder builder = Section.with(); if (!randomizationStrategy.equals(RandomizationStrategy.QUESTIONS_RANDOMIZATION)) { builder.id(questionBreadcrumb.getQuestion().getSectionId()); } Section section = builder.build(); section.addQuestion(Question.with().id(questionBreadcrumb.getQuestion().getId()) .number(questionBreadcrumb.getQuestionNumber()).build()); nextPage.addSection(section); return nextPage; } }