/*******************************************************************************
* 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.facades.impl;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import net.sf.gazpachoquest.domain.core.Question;
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.dto.PageMetadataDTO;
import net.sf.gazpachoquest.dto.QuestionDTO;
import net.sf.gazpachoquest.dto.QuestionnaireDefinitionDTO;
import net.sf.gazpachoquest.dto.QuestionnairePageDTO;
import net.sf.gazpachoquest.dto.SectionDTO;
import net.sf.gazpachoquest.dto.answers.Answer;
import net.sf.gazpachoquest.dto.answers.BooleanAnswer;
import net.sf.gazpachoquest.dto.answers.SimpleAnswer;
import net.sf.gazpachoquest.facades.QuestionnaireFacade;
import net.sf.gazpachoquest.questionnaire.resolver.PageResolver;
import net.sf.gazpachoquest.questionnaire.resolver.ResolverSelector;
import net.sf.gazpachoquest.questionnaire.support.AnswersPopulator;
import net.sf.gazpachoquest.questionnaire.support.PageMetadataCreator;
import net.sf.gazpachoquest.questionnaire.support.PageMetadataStructure;
import net.sf.gazpachoquest.questionnaire.support.PageStructure;
import net.sf.gazpachoquest.services.QuestionService;
import net.sf.gazpachoquest.services.QuestionnaireAnswersService;
import net.sf.gazpachoquest.services.QuestionnaireDefinitionService;
import net.sf.gazpachoquest.services.QuestionnaireService;
import net.sf.gazpachoquest.services.SectionService;
import net.sf.gazpachoquest.types.Language;
import net.sf.gazpachoquest.types.NavigationAction;
import net.sf.gazpachoquest.types.RenderingMode;
import net.sf.gazpachoquest.types.Topology;
import org.dozer.Mapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@Component
public class QuestionnaireFacadeImpl implements QuestionnaireFacade {
private static Logger logger = LoggerFactory.getLogger(QuestionnaireFacadeImpl.class);
@Autowired
private ResolverSelector resolverSelector;
@Autowired
private QuestionnaireService questionnaireService;
@Autowired
private QuestionService questionService;
@Autowired
private SectionService sectionService;
@Autowired
@Qualifier("questionnaireDefinitionServiceImpl")
private QuestionnaireDefinitionService questionnaireDefinitionService;
@Autowired
private QuestionnaireAnswersService questionnaireAnswersService;
@Autowired
private AnswersPopulator answersPopulator;
@Autowired
private PageMetadataCreator metadataCreator;
@Autowired
private Mapper mapper;
public QuestionnaireFacadeImpl() {
super();
}
@Transactional(readOnly = true)
@Override
public QuestionnaireDefinitionDTO getDefinition(Integer questionnaireId) {
QuestionnaireDefinition definition = questionnaireService.getDefinition(questionnaireId);
QuestionnaireDefinitionDTO definitionDTO = mapper.map(definition, QuestionnaireDefinitionDTO.class);
Set<Language> translations = questionnaireDefinitionService.translationsSupported(definition.getId());
for (Language language : translations) {
definitionDTO.addSupportedLanguage(language);
}
definitionDTO.addSupportedLanguage(definition.getLanguage());
return definitionDTO;
}
@Override
public QuestionnairePageDTO resolvePage(Integer questionnaireId, RenderingMode mode, Language preferredLanguage,
NavigationAction action) {
Questionnaire questionnaire = questionnaireService.findOne(questionnaireId);
if (mode == null) {
mode = questionnaire.getQuestionnaireDefinition().getRenderingMode();
}
Topology topology = questionnaireDefinitionService.getTopology(questionnaire.getQuestionnaireDefinition().getId());
PageResolver resolver = resolverSelector.selectBy(mode, topology);
logger.info("Requesting page {} for questionnaireId = {} in language {} using renderingMode = {}",
action.toString(), questionnaireId, preferredLanguage, mode);
PageStructure pageStructure = resolver.resolveNextPage(questionnaire, action);
QuestionnairePageDTO page = new QuestionnairePageDTO();
if (pageStructure == null) { // TODO Handle exception
return page;
}
List<Section> sections = pageStructure.getSections();
List<QuestionDTO> allVisibleQuestions = new ArrayList<>();
for (Section section : sections) {
Section localizedSection = Section.with().build();
if (pageStructure.isSectionInfoAvailable()) {
localizedSection = sectionService.findOne(section.getId(), preferredLanguage);
}
SectionDTO sectionDTO = mapper.map(localizedSection, SectionDTO.class);
page.addSection(sectionDTO);
List<Integer> questionIds = section.getQuestionsId();
List<Question> fetchedQuestions = questionService.findInList(questionIds, preferredLanguage);
Iterator<Question> questionsIterator = section.getQuestions().iterator();
for (Question fetchedQuestion : fetchedQuestions) {
QuestionDTO questionDTO = mapper.map(fetchedQuestion, QuestionDTO.class);
questionDTO.setNumber(questionsIterator.next().getNumber());
sectionDTO.addQuestion(questionDTO);
allVisibleQuestions.add(questionDTO);
}
}
answersPopulator.populate(pageStructure.getAnswers(), allVisibleQuestions);
PageMetadataStructure metadata = pageStructure.getMetadata();
page.setMetadata(mapper.map(metadata, PageMetadataDTO.class));
page.setSectionInfoAvailable(pageStructure.isSectionInfoAvailable());
logger.info("Returning page {} of {} for questionnaireId = {}", metadata.getNumber(), metadata.getCount(),
questionnaireId);
return page;
}
@Override
public void saveAnswer(Integer questionnaireId, String questionCode, Answer answer) {
Questionnaire questionnaire = Questionnaire.with().id(questionnaireId).build();
if (!(answer instanceof SimpleAnswer)) {
logger.warn("Answer {} not supported", answer);
return;
}
String sufix = "";
if (answer instanceof BooleanAnswer) {
sufix = "_" + ((BooleanAnswer) answer).getOption();
}
questionnaireAnswersService.save(questionnaire, questionCode + sufix, answer.getValue());
}
}