/*
* Copyright (c) 2005-2011 Grameen Foundation USA
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*
* See also http://www.apache.org/licenses/LICENSE-2.0.html for an
* explanation of the license and how it is applied.
*/
package org.mifos.platform.questionnaire.domain;
import static org.mifos.platform.questionnaire.QuestionnaireConstants.PPI_SURVEY_FILE_EXT;
import static org.mifos.platform.questionnaire.QuestionnaireConstants.PPI_SURVEY_FILE_PREFIX;
import static org.mifos.platform.util.CollectionUtils.isNotEmpty;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.mifos.application.master.business.LookUpValueEntity;
import org.mifos.framework.business.EntityMaster;
import org.mifos.framework.exceptions.SystemException;
import org.mifos.platform.questionnaire.QuestionnaireConstants;
import org.mifos.platform.questionnaire.domain.ppi.PPISurveyLocator;
import org.mifos.platform.questionnaire.mappers.QuestionnaireMapper;
import org.mifos.platform.questionnaire.parsers.QuestionGroupDefinitionParser;
import org.mifos.platform.questionnaire.persistence.EventSourceDao;
import org.mifos.platform.questionnaire.persistence.QuestionDao;
import org.mifos.platform.questionnaire.persistence.QuestionGroupDao;
import org.mifos.platform.questionnaire.persistence.QuestionGroupInstanceDao;
import org.mifos.platform.questionnaire.persistence.QuestionGroupLinkDao;
import org.mifos.platform.questionnaire.persistence.SectionLinkDao;
import org.mifos.platform.questionnaire.persistence.SectionQuestionDao;
import org.mifos.platform.questionnaire.persistence.SectionQuestionLinkDao;
import org.mifos.platform.questionnaire.service.InformationOrder;
import org.mifos.platform.questionnaire.service.QuestionDetail;
import org.mifos.platform.questionnaire.service.QuestionGroupDetail;
import org.mifos.platform.questionnaire.service.QuestionGroupDetails;
import org.mifos.platform.questionnaire.service.QuestionGroupInstanceDetail;
import org.mifos.platform.questionnaire.service.QuestionLinkDetail;
import org.mifos.platform.questionnaire.service.SectionDetail;
import org.mifos.platform.questionnaire.service.SectionLinkDetail;
import org.mifos.platform.questionnaire.service.SectionQuestionDetail;
import org.mifos.platform.questionnaire.service.dtos.EventSourceDto;
import org.mifos.platform.questionnaire.service.dtos.QuestionDto;
import org.mifos.platform.questionnaire.service.dtos.QuestionGroupDto;
import org.mifos.platform.questionnaire.service.dtos.QuestionGroupInstanceDto;
import org.mifos.platform.questionnaire.service.dtos.SectionDto;
import org.mifos.platform.questionnaire.validators.QuestionnaireValidator;
import org.mifos.platform.validations.ValidationException;
import org.springframework.beans.factory.annotation.Autowired;
@SuppressWarnings("PMD")
public class QuestionnaireServiceImpl implements QuestionnaireService {
@Autowired
private QuestionnaireValidator questionnaireValidator;
@Autowired
private QuestionDao questionDao;
@Autowired
private QuestionGroupDao questionGroupDao;
@Autowired
private EventSourceDao eventSourceDao;
@Autowired
private QuestionGroupInstanceDao questionGroupInstanceDao;
@Autowired
private QuestionnaireMapper questionnaireMapper;
@Autowired
private PPISurveyLocator ppiSurveyLocator;
@Autowired
private QuestionGroupDefinitionParser questionGroupDefinitionParser;
@Autowired
private SectionQuestionDao sectionQuestionDao;
@Autowired
private InformationOrderService informationOrderService;
@Autowired
private QuestionGroupLinkDao questionGroupLinkDao;
@Autowired
private SectionQuestionLinkDao sectionQuestionLinkDao;
@Autowired
private SectionLinkDao sectionLinkDao;
@SuppressWarnings({"UnusedDeclaration"})
private QuestionnaireServiceImpl() {
}
public QuestionnaireServiceImpl(QuestionnaireValidator questionnaireValidator, QuestionDao questionDao,
QuestionnaireMapper questionnaireMapper, QuestionGroupDao questionGroupDao,
EventSourceDao eventSourceDao, QuestionGroupInstanceDao questionGroupInstanceDao,
PPISurveyLocator ppiSurveyLocator, QuestionGroupDefinitionParser questionGroupDefinitionParser,
SectionQuestionDao sectionQuestionDao) {
this.questionnaireValidator = questionnaireValidator;
this.questionDao = questionDao;
this.questionnaireMapper = questionnaireMapper;
this.questionGroupDao = questionGroupDao;
this.eventSourceDao = eventSourceDao;
this.questionGroupInstanceDao = questionGroupInstanceDao;
this.ppiSurveyLocator = ppiSurveyLocator;
this.questionGroupDefinitionParser = questionGroupDefinitionParser;
this.sectionQuestionDao = sectionQuestionDao;
}
@Override
public QuestionDetail defineQuestion(QuestionDetail questionDetail) throws SystemException {
questionnaireValidator.validateForDefineQuestion(questionDetail);
QuestionEntity question = questionnaireMapper.mapToQuestion(questionDetail);
persistQuestion(question);
return questionnaireMapper.mapToQuestionDetail(question);
}
@Override
public List<QuestionDetail> getAllQuestions() {
List<QuestionEntity> questions = questionDao.retrieveAll();
return questionnaireMapper.mapToQuestionDetails(questions);
}
@Override
public List<QuestionDetail> getAllActiveQuestions(List<Integer> questionIdsToExclude) {
List<QuestionEntity> questions;
if (isNotEmpty(questionIdsToExclude)) {
questions = questionDao.retrieveByStateExcluding(questionIdsToExclude, QuestionState.ACTIVE.getValue());
questions.addAll(questionDao.retrieveByStateExcluding(questionIdsToExclude, QuestionState.ACTIVE_NOT_EDITABLE.getValue()));
} else {
questions = questionDao.retrieveByState(QuestionState.ACTIVE.getValue());
questions.addAll(questionDao.retrieveByState(QuestionState.ACTIVE_NOT_EDITABLE.getValue()));
}
return questionnaireMapper.mapToQuestionDetails(questions);
}
@Override
public QuestionGroupDetail defineQuestionGroup(QuestionGroupDetail questionGroupDetail) throws SystemException {
questionnaireValidator.validateForDefineQuestionGroup(questionGroupDetail);
generateNicknamesForQuestions(questionGroupDetail);
QuestionGroup questionGroup = questionnaireMapper.mapToQuestionGroup(questionGroupDetail);
questionGroupDao.create(questionGroup);
List<EntityMaster> usedSources = new ArrayList<EntityMaster>();
for (Section section: questionGroup.getSections()) {
for (SectionQuestion sectionQuestion: section.getQuestions()) {
usedSources.clear();
for (EventSourceEntity eventSourceEntity: questionGroup.getEventSources()) {
if (!(eventSourceEntity.getSource().getEntityType().equals("Client")
|| eventSourceEntity.getSource().getEntityType().equals("Loan"))) {
continue;
}
InformationOrder informationOrder =
new InformationOrder(null, "additional", sectionQuestion.getId(), eventSourceEntity.getSource().getEntityType(), 999);
if (!sectionQuestion.isShowOnPage()) {
informationOrderService.removeAdditionalQuestionIfExists(informationOrder);
}
if (usedSources.contains(eventSourceEntity.getSource())) {
continue;
}
if (sectionQuestion.isShowOnPage()) {
informationOrderService.addAdditionalQuestionIfNotExists(informationOrder);
}
usedSources.add(eventSourceEntity.getSource());
}
}
}
return questionnaireMapper.mapToQuestionGroupDetail(questionGroup);
}
@Override
public List<QuestionGroupDetail> getAllQuestionGroups() {
List<QuestionGroup> questionGroups = questionGroupDao.getDetailsAll();
return questionnaireMapper.mapToQuestionGroupDetails(questionGroups);
}
@Override
public boolean isDuplicateQuestionText(String title) {
List result = questionDao.retrieveCountOfQuestionsWithText(title);
return (Long) result.get(0) > 0;
}
@Override
public QuestionGroupDetail getQuestionGroup(int questionGroupId) throws SystemException {
QuestionGroup questionGroup = questionGroupDao.getDetails(questionGroupId);
if (questionGroup == null) {
throw new SystemException(QuestionnaireConstants.QUESTION_GROUP_NOT_FOUND);
}
return questionnaireMapper.mapToQuestionGroupDetail(questionGroup);
}
@Override
public QuestionDetail getQuestion(int questionId) throws SystemException {
QuestionEntity question = questionDao.getDetails(questionId);
if (question == null) {
throw new SystemException(QuestionnaireConstants.QUESTION_NOT_FOUND);
}
return questionnaireMapper.mapToQuestionDetail(question);
}
@Override
public List<EventSourceDto> getAllEventSources() {
return questionnaireMapper.mapToEventSources(eventSourceDao.retrieveAllEventSourcesOrdered());
}
@Override
public List<QuestionGroupDetail> getQuestionGroups(EventSourceDto eventSourceDto) throws SystemException {
questionnaireValidator.validateForEventSource(eventSourceDto);
List<QuestionGroup> questionGroups = questionGroupDao.retrieveQuestionGroupsByEventSource(eventSourceDto.getEvent(), eventSourceDto.getSource());
List<QuestionGroupDetail> questionGroupDetails = questionnaireMapper.mapToQuestionGroupDetails(questionGroups);
removeInActiveSectionsAndQuestions(questionGroupDetails);
return questionGroupDetails;
}
@Override
public void saveResponses(QuestionGroupDetails questionGroupDetails) {
questionnaireValidator.validateForQuestionGroupResponses(questionGroupDetails.getDetails());
questionGroupInstanceDao.saveOrUpdateAll(questionnaireMapper.mapToQuestionGroupInstances(questionGroupDetails));
}
@Override
public void validateResponses(List<QuestionGroupDetail> questionGroupDetails) {
questionnaireValidator.validateForQuestionGroupResponses(questionGroupDetails);
}
@Override
public List<QuestionGroupInstanceDetail> getQuestionGroupInstances(Integer entityId, EventSourceDto eventSourceDto, boolean includeUnansweredQuestionGroups, boolean fetchLastVersion) {
questionnaireValidator.validateForEventSource(eventSourceDto);
Integer eventSourceId = getEventSourceEntity(eventSourceDto).getId();
List<QuestionGroupInstance> questionGroupInstances = getQuestionGroupInstanceEntities(entityId, eventSourceId, fetchLastVersion);
List<QuestionGroupInstanceDetail> questionGroupInstanceDetails = questionnaireMapper.mapToQuestionGroupInstanceDetails(questionGroupInstances);
if (includeUnansweredQuestionGroups) {
List<QuestionGroup> questionGroups = questionGroupDao.retrieveQuestionGroupsByEventSource(eventSourceDto.getEvent(), eventSourceDto.getSource());
questionGroupInstanceDetails = mergeUnansweredQuestionGroups(questionGroupInstanceDetails, questionGroups);
}
return questionGroupInstanceDetails;
}
private List<QuestionGroupInstance> getQuestionGroupInstanceEntities(Integer entityId, Integer eventSourceId, boolean fetchLastVersion) {
List<QuestionGroupInstance> questionGroupInstances;
if(fetchLastVersion){
questionGroupInstances = questionGroupInstanceDao.retrieveLatestQuestionGroupInstancesByEntityIdAndEventSourceId(entityId, eventSourceId);
}else{
questionGroupInstances = questionGroupInstanceDao.retrieveQuestionGroupInstancesByEntityIdAndEventSourceId(entityId, eventSourceId);
}
return questionGroupInstances;
}
private List<QuestionGroupInstanceDetail> mergeUnansweredQuestionGroups(List<QuestionGroupInstanceDetail> instancesWithResponses, List<QuestionGroup> questionGroups) {
List<QuestionGroupInstanceDetail> allInstances = new ArrayList<QuestionGroupInstanceDetail>(instancesWithResponses);
for (QuestionGroup questionGroup : questionGroups) {
if (!hasResponse(questionGroup, instancesWithResponses)) {
allInstances.add(questionnaireMapper.mapToEmptyQuestionGroupInstanceDetail(questionGroup));
}
}
return allInstances;
}
private boolean hasResponse(QuestionGroup questionGroup, List<QuestionGroupInstanceDetail> questionGroupInstances) {
boolean result = false;
for (QuestionGroupInstanceDetail questionGroupInstance : questionGroupInstances) {
if (questionGroupInstance.getQuestionGroupDetail().getId() == questionGroup.getId()) {
result = true;
break;
}
}
return result;
}
@Override
public QuestionGroupInstanceDetail getQuestionGroupInstance(int questionGroupInstanceId) {
QuestionGroupInstance questionGroupInstance = questionGroupInstanceDao.getDetails(questionGroupInstanceId);
return questionnaireMapper.mapToQuestionGroupInstanceDetail(questionGroupInstance);
}
@Override
public Integer defineQuestionGroup(QuestionGroupDto questionGroupDto) {
return defineQuestionGroup(questionGroupDto, true);
}
@Override
public Integer defineQuestionGroup(QuestionGroupDto questionGroupDto, boolean withDuplicateQuestionTextCheck) {
questionnaireValidator.validateForDefineQuestionGroup(questionGroupDto, withDuplicateQuestionTextCheck);
QuestionGroup questionGroup = questionnaireMapper.mapToQuestionGroup(questionGroupDto);
return persistQuestionGroup(questionGroup);
}
/*
* When creating questions, if a question has no nickname (nickname == null),
* then try to find an existing question with the same text and use it
* instead. If a question we're about to create has a unique nickname,
* then go ahead and create a new question even if there is an existing
* question with the same text. If there is an an existing question with
* a nickname that matches the new question nickname, then use the existing
* question instead.
*/
private Integer persistQuestionGroup(QuestionGroup questionGroup) {
List<SectionQuestion> sectionQuestions = questionGroup.getAllSectionQuestions();
for (SectionQuestion sectionQuestion : sectionQuestions) {
List<QuestionEntity> questionEntities;
if (sectionQuestion.getQuestion().getNickname() == null) {
questionEntities = questionDao.retrieveByText(sectionQuestion.getQuestionText());
} else {
questionEntities = questionDao.retrieveByNickname(sectionQuestion.getQuestion().getNickname());
}
if (isNotEmpty(questionEntities)) {
QuestionEntity questionEntity = questionEntities.get(0);
questionEntity.setQuestionState(sectionQuestion.getQuestion().getQuestionState());
sectionQuestion.setQuestion(questionEntity);
}
}
generateNicknamesForQuestions(questionGroup);
return questionGroupDao.create(questionGroup);
}
private void generateNicknamesForQuestions(QuestionGroup questionGroup) {
for (SectionQuestion question : questionGroup.getAllSectionQuestions()) {
if (question.getQuestion().getNickname() == null) {
try {
question.getQuestion().setNickname(computeMD5(question.getQuestionText()));
} catch (NoSuchAlgorithmException e) {
throw new SystemException(e);
} catch (UnsupportedEncodingException e) {
throw new SystemException(e);
}
}
}
}
private void generateNicknamesForQuestions(QuestionGroupDetail questionGroupDetail) {
for (SectionDetail sectionDetail : questionGroupDetail.getSectionDetails()) {
for (SectionQuestionDetail sectionQuestionDetail : sectionDetail.getQuestions()) {
if (sectionQuestionDetail.getQuestionDetail().getNickname() == null) {
try {
sectionQuestionDetail.getQuestionDetail().setNickname(computeMD5(sectionQuestionDetail.getQuestionDetail().getText()));
} catch (NoSuchAlgorithmException e) {
throw new SystemException(e);
} catch (UnsupportedEncodingException e) {
throw new SystemException(e);
}
}
}
}
}
@Override
public List<String> getAllCountriesForPPI() {
List<String> ppiSurveyFiles = ppiSurveyLocator.getAllPPISurveyFiles();
List<String> countries = new ArrayList<String>();
for (String ppiSurveyFile : ppiSurveyFiles) {
String country = ppiSurveyFile.substring(PPI_SURVEY_FILE_PREFIX.length(), ppiSurveyFile.indexOf(PPI_SURVEY_FILE_EXT));
countries.add(country);
}
return countries;
}
@Override
public Integer uploadPPIQuestionGroup(String country) {
String ppiXmlForCountry = ppiSurveyLocator.getPPIUploadFileForCountry(country);
QuestionGroupDto questionGroupDto = questionGroupDefinitionParser.parse(ppiXmlForCountry);
activateQGWithQuestions(questionGroupDto); // according to MIFOS-4146 all uploaded QG and questions should be active
if (questionGroupDto.isPpi()) { // according to MIFOS-4149 PPI questions should be editable
makePPIQuestionsNotEditable(questionGroupDto);
}
return defineQuestionGroup(questionGroupDto, false);
}
private void makePPIQuestionsNotEditable(QuestionGroupDto questionGroupDto) {
for (SectionDto section : questionGroupDto.getSections()) {
for (QuestionDto question : section.getQuestions()) {
question.setEditable(false);
}
}
}
private void activateQGWithQuestions(QuestionGroupDto questionGroupDto) {
questionGroupDto.setActive(true);
for (SectionDto section : questionGroupDto.getSections()) {
for (QuestionDto question : section.getQuestions()) {
question.setActive(true);
question.setEditable(true);
}
}
}
@Override
public Integer saveQuestionGroupInstance(QuestionGroupInstanceDto questionGroupInstanceDto) {
QuestionGroupInstance questionGroupInstance = questionnaireMapper.mapToQuestionGroupInstance(questionGroupInstanceDto);
return questionGroupInstanceDao.create(questionGroupInstance);
}
@SuppressWarnings("PMD.NullAssignment")
@Override
public Integer getSectionQuestionId(String sectionName, Integer questionId, Integer questionGroupId) {
List<Integer> sectionQuestionIds = sectionQuestionDao.retrieveIdFromQuestionGroupIdQuestionIdSectionName(sectionName, questionId, questionGroupId);
return isNotEmpty(sectionQuestionIds)? sectionQuestionIds.get(0): null;
}
@Override
public Integer defineQuestion(QuestionDto questionDto) {
questionnaireValidator.validateForDefineQuestion(questionDto);
QuestionEntity questionEntity = questionnaireMapper.mapToQuestion(questionDto);
return createQuestion(questionEntity);
}
@Override
public EventSourceDto getEventSource(int eventSourceId) {
EventSourceEntity sourceEntity = eventSourceDao.getDetails(eventSourceId);
if (sourceEntity == null) {
throw new SystemException(QuestionnaireConstants.INVALID_EVENT_SOURCE);
}
return questionnaireMapper.mapToEventSources(Arrays.asList(sourceEntity)).get(0);
}
@Override
public Integer getEventSourceId(String event, String source) {
List<EventSourceEntity> events = eventSourceDao.retrieveByEventAndSource(event, source);
if (events == null || events.isEmpty()) {
throw new SystemException(QuestionnaireConstants.INVALID_EVENT_SOURCE);
}
return events.get(0).getId();
}
@SuppressWarnings("PMD.PreserveStackTrace")
private Integer createQuestion(QuestionEntity questionEntity) {
try {
if (questionEntity.getNickname() == null) {
try {
questionEntity.setNickname(computeMD5(questionEntity.getQuestionText()));
} catch (NoSuchAlgorithmException e) {
throw new SystemException(e);
} catch (UnsupportedEncodingException e) {
throw new SystemException(e);
}
}
return questionDao.create(questionEntity);
} catch (org.springframework.dao.DataIntegrityViolationException e) {
questionEntity.setNickname(null);
throw new ValidationException(QuestionnaireConstants.QUESTION_TITLE_DUPLICATE);
}
}
private EventSourceEntity getEventSourceEntity(EventSourceDto eventSourceDto) {
return eventSourceDao.retrieveByEventAndSource(eventSourceDto.getEvent(), eventSourceDto.getSource()).get(0);
}
private void persistQuestion(QuestionEntity question) throws SystemException {
try {
if (question.getNickname() == null) {
try {
question.setNickname(computeMD5(question.getQuestionText()));
} catch (NoSuchAlgorithmException e) {
throw new SystemException(e);
} catch (UnsupportedEncodingException e) {
throw new SystemException(e);
}
}
questionDao.saveOrUpdate(question);
} catch (org.springframework.dao.DataIntegrityViolationException e) {
question.setNickname(null);
throw new SystemException(QuestionnaireConstants.QUESTION_TITLE_DUPLICATE, e);
}
}
private void removeInActiveSectionsAndQuestions(List<QuestionGroupDetail> questionGroupDetails) {
for (Iterator<QuestionGroupDetail> questionGroupDetailIterator = questionGroupDetails.iterator(); questionGroupDetailIterator.hasNext();) {
QuestionGroupDetail questionGroupDetail = questionGroupDetailIterator.next();
removeInActiveSectionsAndQuestions(questionGroupDetail);
if (questionGroupDetail.hasNoActiveSectionsAndQuestions()) {
questionGroupDetailIterator.remove();
}
}
}
private void removeInActiveSectionsAndQuestions(QuestionGroupDetail questionGroupDetail) {
for (Iterator<SectionDetail> sectionDetailIterator = questionGroupDetail.getSectionDetails().iterator(); sectionDetailIterator.hasNext();) {
SectionDetail sectionDetail = sectionDetailIterator.next();
removeInActiveQuestions(sectionDetail);
if (sectionDetail.hasNoActiveQuestions()) {
sectionDetailIterator.remove();
}
}
}
private void removeInActiveQuestions(SectionDetail sectionDetail) {
for (Iterator<SectionQuestionDetail> sectionQuestionDetailIterator = sectionDetail.getQuestions().iterator(); sectionQuestionDetailIterator.hasNext();) {
if (sectionQuestionDetailIterator.next().isInactive()) {
sectionQuestionDetailIterator.remove();
}
}
}
private String computeMD5(String questionText) throws NoSuchAlgorithmException, UnsupportedEncodingException {
String md5hash = null;
if (questionText != null) {
MessageDigest md;
md = MessageDigest.getInstance("MD5");
md.update(questionText.getBytes("utf-8"), 0, questionText.length());
md5hash = convertToHex(md.digest());
}
return md5hash;
}
private String convertToHex(byte[] data) {
StringBuffer buf = new StringBuffer();
for (byte element : data) {
int halfbyte = (element >>> 4) & 0x0F;
int two_halfs = 0;
do {
if ((0 <= halfbyte) && (halfbyte <= 9)) {
buf.append((char) ('0' + halfbyte));
} else {
buf.append((char) ('a' + (halfbyte - 10)));
}
halfbyte = element & 0x0F;
} while(two_halfs++ < 1);
}
return buf.toString();
}
@Override
public QuestionGroup getQuestionGroupById(Integer questionGroupId) {
return questionGroupDao.getDetails(questionGroupId);
}
@Override
public Map<String, Map<Integer, Boolean>> getHiddenVisibleQuestionsAndSections(
Integer questionId, String response) throws ParseException {
Map<Integer, Boolean> questions = new HashMap<Integer, Boolean>();
Map<Integer, Boolean> sections = new HashMap<Integer, Boolean>();
SectionQuestion question = sectionQuestionDao.getDetails(questionId);
for (SectionQuestionLink dependantQuestionLink: sectionQuestionLinkDao.retrieveDependentSectionQuestionLinksFromQuestion(question.getId())) {
questions.put(dependantQuestionLink.getAffectedSectionQuestion().getId(),
isQuestionLinkMatched(dependantQuestionLink.getQuestionGroupLink(), response));
}
for (SectionLink dependantSectionLink: sectionLinkDao.retrieveDependentSectionLinksFromQuestion(question.getId())) {
sections.put(dependantSectionLink.getAffectedSection().getId(),
isQuestionLinkMatched(dependantSectionLink.getQuestionGroupLink(), response));
}
Map<String, Map<Integer, Boolean>> result = new HashMap<String, Map<Integer, Boolean>>();
result.put("questions", questions);
result.put("sections", sections);
return result;
}
public List<LookUpValueEntity> getAllConditions(){
return sectionQuestionLinkDao.retrieveAllConditions();
}
private boolean isQuestionLinkMatched(QuestionGroupLink link, String response) throws ParseException {
if (link.getConditionType().equals(QuestionGroupLink.CONDITION_TYPE_EQUALS)) {
return link.getValue().equals(response);
}
if (link.getConditionType().equals(QuestionGroupLink.CONDITION_TYPE_NOT_EQUALS)) {
return !link.getValue().equals(response);
}
if (link.getConditionType().equals(QuestionGroupLink.CONDITION_TYPE_GREATER)) {
return Integer.parseInt(response) > Integer.parseInt(link.getValue());
}
if (link.getConditionType().equals(QuestionGroupLink.CONDITION_TYPE_SMALLER)) {
return Integer.parseInt(response) < Integer.parseInt(link.getValue());
}
if (link.getConditionType().equals(QuestionGroupLink.CONDITION_TYPE_AFTER)) {
return new SimpleDateFormat("dd/MM/yyyy").parse(response)
.after(new SimpleDateFormat("dd/MM/yyyy").parse(link.getValue()));
}
if (link.getConditionType().equals(QuestionGroupLink.CONDITION_TYPE_BEFORE)) {
return new SimpleDateFormat("dd/MM/yyyy").parse(response)
.before(new SimpleDateFormat("dd/MM/yyyy").parse(link.getValue()));
}
if (link.getConditionType().equals(QuestionGroupLink.CONDITION_TYPE_DATE_RANGE)) {
Date responseDate = new SimpleDateFormat("dd/MM/yyyy").parse(response);
Date firstDate = new SimpleDateFormat("dd/MM/yyyy").parse(link.getValue());
Date secondDate = new SimpleDateFormat("dd/MM/yyyy").parse(link.getAdditionalValue());
return (responseDate.after(firstDate) && responseDate.before(secondDate)) || (responseDate.before(firstDate) && responseDate.after(secondDate));
}
if (link.getConditionType().equals(QuestionGroupLink.CONDITION_TYPE_RANGE)) {
int responseInt = Integer.parseInt(response);
return (responseInt >= Integer.parseInt(link.getValue()) &&
responseInt <= Integer.parseInt(link.getAdditionalValue())) || (responseInt <= Integer.parseInt(link.getValue()) &&
responseInt >= Integer.parseInt(link.getAdditionalValue()));
}
return false;
}
public void createQuestionLinks (List<QuestionLinkDetail> questionLinks){
for(QuestionLinkDetail questionLinkDetail : questionLinks){
QuestionGroupLink questionGroupLink = questionnaireMapper.mapToQuestionGroupLink(questionLinkDetail, null);
questionGroupLinkDao.saveOrUpdate(questionGroupLink);
SectionQuestionLink sectionQuestionLink = questionnaireMapper.mapToQuestionLink(questionLinkDetail, questionGroupLink);
sectionQuestionLinkDao.saveOrUpdate(sectionQuestionLink);
}
}
public void createSectionLinks(List<SectionLinkDetail> sectionLinks){
for(SectionLinkDetail sectionLinkDetail : sectionLinks){
QuestionGroupLink questionGroupLink = questionnaireMapper.mapToQuestionGroupLink(null, sectionLinkDetail);
questionGroupLinkDao.saveOrUpdate(questionGroupLink);
SectionLink sectionLink = questionnaireMapper.mapToSectionLink(sectionLinkDetail, questionGroupLink);
sectionLinkDao.saveOrUpdate(sectionLink);
}
}
@Override
public Map<String, List<String>>getHiddenQuestionsAndSections(String questionsId, String sectionsId) {
List<String> questionIds = new ArrayList(Arrays.asList(questionsId.split(",")));
List<String> sectionIds = new ArrayList(Arrays.asList(sectionsId.split(",")));
Iterator<String> itQ = questionIds.iterator();
while(itQ.hasNext()) {
Integer questionId = Integer.parseInt(itQ.next());
if (sectionQuestionLinkDao.retrieveSectionQuestionLinksByAffectedQuestionId(questionId).size() == 0) {
itQ.remove();
}
}
Iterator<String> itS = sectionIds.iterator();
while(itS.hasNext()) {
Integer sectionId = Integer.parseInt(itS.next());
if (sectionLinkDao.retrieveSectionLinksByAffectedSectionId(sectionId).size() == 0) {
itS.remove();
}
}
Map<String, List<String>> toRemove = new HashMap<String, List<String>>();
toRemove.put("questions", questionIds);
toRemove.put("sections", sectionIds);
return toRemove;
}
}