net.sf.gazpachoquest.questionnaire.resolver.SectionBySectionRelevanceAwareResolver.java Source code

Java tutorial

Introduction

Here is the source code for net.sf.gazpachoquest.questionnaire.resolver.SectionBySectionRelevanceAwareResolver.java

Source

/*******************************************************************************
 * 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.Arrays;
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.domain.core.SectionBreadcrumb;
import net.sf.gazpachoquest.questionnaire.support.PageStructure;
import net.sf.gazpachoquest.services.BreadcrumbService;
import net.sf.gazpachoquest.services.SectionService;
import net.sf.gazpachoquest.types.RandomizationStrategy;
import net.sf.gazpachoquest.types.RenderingMode;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

@Component("SectionBySectionRelevanceAwareResolver")
public class SectionBySectionRelevanceAwareResolver extends AbstractResolver<SectionBreadcrumb>
        implements PageResolver {

    private static final Integer INITIAL_POSITION = 0;

    private static final Logger logger = LoggerFactory.getLogger(SectionBySectionRelevanceAwareResolver.class);

    @Autowired
    private BreadcrumbService breadcrumbService;

    @Autowired
    private SectionService sectionService;

    protected SectionBySectionRelevanceAwareResolver() {
        super(RenderingMode.SECTION_BY_SECTION);
    }

    @Override
    protected List<SectionBreadcrumb> makeBreadcrumbs(QuestionnaireDefinition questionnaireDefinition,
            Questionnaire questionnaire) {
        List<SectionBreadcrumb> breadcrumbs = new ArrayList<>();
        SectionBreadcrumb breadcrumb = null;
        Integer questionnairDefinitionId = questionnaireDefinition.getId();

        Section section = findFirstSection(questionnairDefinitionId);
        breadcrumb = SectionBreadcrumb.with().questionnaire(questionnaire).section(section)
                .renderingMode(RenderingMode.SECTION_BY_SECTION).build();
        breadcrumbs.add(breadcrumb);
        populateQuestionsBreadcrumbs(breadcrumbs, QUESTION_NUMBER_START_COUNTER);
        // Store questions displayed number in order to generate the question
        // numbers.
        breadcrumb.setQuestionsDisplayedCount(breadcrumb.getQuestionsBreadcrumbCount());
        breadcrumbs.get(0).setLast(Boolean.TRUE);
        return breadcrumbs;
    }

    @Override
    protected SectionBreadcrumb findNextBreadcrumb(final QuestionnaireDefinition questionnaireDefinition,
            final Questionnaire questionnaire, Map<String, Object> answers, final SectionBreadcrumb lastBreadcrumb,
            final Integer lastBreadcrumbPosition) {

        SectionBreadcrumb nextBreadcrumb = null;

        Integer position = sectionService.positionInQuestionnaireDefinition(lastBreadcrumb.getSection().getId());
        boolean found = false;
        Section next = null;

        do {
            position++;
            next = sectionService.findOneByPositionInQuestionnaireDefinition(questionnaireDefinition.getId(),
                    position);
            if (next == null) {
                break;
            }
            found = isRevealed(next.getRelevance(), answers);
        } while (!found);

        if (logger.isDebugEnabled()) {
            logger.debug("Displaying sectionId {} because condition ({}) is satisfied ", next.getId(),
                    next.getRelevance());
        }

        // The respondent has reached the last question group
        if (next == null) {
            return null;
        }
        nextBreadcrumb = SectionBreadcrumb.with().questionnaire(questionnaire).section(next)
                .renderingMode(RenderingMode.SECTION_BY_SECTION).build();
        Integer questionsDisplayedCount = lastBreadcrumb.getQuestionsDisplayedCount();
        populateQuestionsBreadcrumbs(Arrays.asList(nextBreadcrumb), questionsDisplayedCount + 1);
        nextBreadcrumb
                .setQuestionsDisplayedCount(questionsDisplayedCount + nextBreadcrumb.getQuestionsBreadcrumbCount());
        return nextBreadcrumb;
    }

    @Override
    protected SectionBreadcrumb findPreviousBreadcrumb(final QuestionnaireDefinition questionnaireDefinition,
            final Questionnaire questionnaire, final SectionBreadcrumb lastBreadcrumb,
            final Integer lastBreadcrumbPosition) {
        if (lastBreadcrumbPosition == INITIAL_POSITION) {
            return null;
        }
        Breadcrumb previous = breadcrumbService.findByQuestionnaireIdAndPosition(questionnaire.getId(),
                lastBreadcrumbPosition - 1);
        Assert.isInstanceOf(SectionBreadcrumb.class, lastBreadcrumb);
        return (SectionBreadcrumb) previous;
    }

    private Section findFirstSection(int questionnaireDefinitionId) {
        // It assumes that the first section is always displayed
        return sectionService.findOneByPositionInQuestionnaireDefinition(questionnaireDefinitionId,
                INITIAL_POSITION);
    }

    @Override
    protected boolean breadcrumbCacheEnable() {
        return false;
    }

    @Override
    protected PageStructure createPageStructure(RandomizationStrategy randomizationStrategy,
            List<SectionBreadcrumb> breadcrumbs, Map<String, Object> answers) {
        PageStructure nextPage = super.createPageStructure(randomizationStrategy, breadcrumbs, answers);
        Breadcrumb active = breadcrumbs.get(0);

        SectionBreadcrumb sectionBreadcrumb = (SectionBreadcrumb) active;
        Builder builder = Section.with();
        if (!randomizationStrategy.equals(RandomizationStrategy.QUESTIONS_RANDOMIZATION)) {
            builder.id(sectionBreadcrumb.getSection().getId());
        }
        Section section = builder.build();
        for (QuestionBreadcrumb questionBreadcrumb : sectionBreadcrumb.getBreadcrumbs()) {
            section.addQuestion(Question.with().id(questionBreadcrumb.getQuestion().getId())
                    .number(questionBreadcrumb.getQuestionNumber()).build());
        }
        nextPage.addSection(section);
        return nextPage;
    }
}