Java tutorial
/* * Copyright (c) 2005-2010 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.application.questionnaire.migration; import static java.lang.String.format; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; import org.hibernate.FlushMode; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.mifos.application.questionnaire.migration.mappers.QuestionnaireMigrationMapper; import org.mifos.customers.ppi.business.PPISurvey; import org.mifos.customers.ppi.business.PPISurveyInstance; import org.mifos.customers.surveys.business.Question; import org.mifos.customers.surveys.business.SurveyInstance; import org.mifos.customers.surveys.business.SurveyQuestion; import org.mifos.platform.questionnaire.service.QuestionnaireServiceFacade; import org.mifos.platform.questionnaire.service.dtos.EventSourceDto; import org.mifos.platform.questionnaire.service.dtos.QuestionGroupDto; import org.mifos.platform.questionnaire.service.dtos.QuestionGroupInstanceDto; import org.mifos.platform.questionnaire.service.dtos.QuestionGroupResponseDto; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; public class QuestionnaireMigration { private static final Logger logger = LoggerFactory.getLogger(QuestionnaireMigration.class); private final QuestionnaireMigrationMapper questionnaireMigrationMapper; private final QuestionnaireServiceFacade questionnaireServiceFacade; private final SessionFactory sessionFactory; private static Integer dateSurveyTakenQuestionId; private Session session; private final SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy"); @Autowired public QuestionnaireMigration(QuestionnaireMigrationMapper questionnaireMigrationMapper, QuestionnaireServiceFacade questionnaireServiceFacade, SessionFactory sessionFactory) { this.questionnaireMigrationMapper = questionnaireMigrationMapper; this.questionnaireServiceFacade = questionnaireServiceFacade; this.sessionFactory = sessionFactory; session = sessionFactory.openSession(); session.setFlushMode(FlushMode.COMMIT); } public List<Integer> migratePPISurveys() { List<Integer> questionGroupIds = new ArrayList<Integer>(); questionGroupIds.addAll(performMigrationOfPPIPPISurvey()); return questionGroupIds; } private List<Integer> performMigrationOfPPIPPISurvey() { List<Integer> questionGroupIds = new ArrayList<Integer>(); List<PPISurvey> surveys = retrieveAllPPIPPISurveys(); if (surveys.size() > 1) { logger.warn("There are more than one PPI survey instances in your database"); for (PPISurvey survey : surveys) { logger.warn(survey.getName()); } } Integer surveyId = surveys.get(0).getSurveyId(); fixQuestionTextAndNickName(surveyId); fixChoiceText(); getSession().close(); getSession().beginTransaction(); PPISurvey survey = (PPISurvey) getSession().get(PPISurvey.class, surveyId); Integer questionGroupId = migratePPISurvey(survey); if (questionGroupId != null) { questionGroupIds.add(questionGroupId); } return questionGroupIds; } private void fixChoiceText() { getSession().beginTransaction(); getSession().createSQLQuery( "update question_choices set choice_text='Labourers (agricultural, plantation, other farm), " + "hunters, tobacco preparers and tobacco product makers, and other labourers / ? (/ /) ? ? " + "/ ?? ?? ? / , , ? ? ' where choice_text='Labourers(farm workers),hunters, tobacco preparers" + "/tobacco product makers,and other labourers / ? (/ /) ? ? / ?? ?? ? / , , ? ? ';") .executeUpdate(); getSession().createSQLQuery( "update question_choices set choice_text='Five or more / ?? / ? ' where choice_text='5 or more / ?? / ? '") .executeUpdate(); getSession().getTransaction().commit(); getSession().close(); } private void fixQuestionTextAndNickName(Integer surveyId) { getSession().close(); getSession().beginTransaction(); PPISurvey survey = (PPISurvey) getSession().get(PPISurvey.class, surveyId); for (SurveyQuestion sq : survey.getQuestions()) { Question q = sq.getQuestion(); q.setNickname(getNickName(q)); q.setQuestionText(getQuestionText(q)); } getSession().getTransaction().commit(); getSession().close(); } private String getNickName(Question question) { if (question.getQuestionText().contains("How many children aged 0 to 17 are in the household?")) { return "ppi_india_2008_family_members_0_to_17"; } else if (question.getQuestionText().contains("What is the household`s principal occupation?")) { return "ppi_india_2008_principal_occupation"; } else if (question.getQuestionText().contains("Is the residence all pacca (burnt bricks, stone")) { return "ppi_india_2008_has_pucca_home"; } else if (question.getQuestionText().contains("What is the household`s primary source of energy for")) { return "ppi_india_2008_cooking_fuel"; } else if (question.getQuestionText().contains("Does the household own a television?")) { return "ppi_india_2008_owns_television"; } else if (question.getQuestionText().contains("Does the household own a bicycle, scooter, or motor")) { return "ppi_india_2008_owns_bicycle_scooter_motorcycle"; } else if (question.getQuestionText().contains("Does the household own a almirah/dressing table?")) { return "ppi_india_2008_owns_almirah"; } else if (question.getQuestionText().contains("Does the household own a sewing machine?")) { return "ppi_india_2008_owns_sewing_machine"; } else if (question.getQuestionText().contains("How many pressure cookers or pressure pans does")) { return "ppi_india_2008_pressure_cookers"; } else if (question.getQuestionText().contains("How many electric fans does the household own?")) { return "ppi_india_2008_electric_fans"; } return question.getNickname(); } private String getQuestionText(Question question) { if (question.getQuestionText().contains("How many children aged 0 to 17 are in the household?")) { return "How many people aged 0 to 17 are in the household? / ? ? - ?? ?? ?? ( ?? ?? ?? ??) / ? ? - ?"; } else if (question.getQuestionText().contains("What is the household`s principal occupation?")) { return "What is the household's principal occupation? / ? ?? ?? ? ??? / ?? ?? ? ?"; } else if (question.getQuestionText().contains("Is the residence all pacca (burnt bricks, stone")) { return "Is the residence all pucca (burnt bricks, stone, cement, concrete, jackboard/cement-plastered reeds, timber, tiles, galvanised tin or asbestos cement sheets)? / ? ? ? ? ? (?/??/?//??/? ??/??? ? ??/) / ? ? ?(/?//?, ?/ -??? ?/?/ / /??? )"; } else if (question.getQuestionText().contains("What is the household`s primary source of energy for")) { return "What is the household's primary source of energy for cooking? / ? ? ? ? ??? / ?? ? ? ?"; } else if (question.getQuestionText().contains("Does the household own a television?")) { return "Does the household own a television? / ? ? ? / ? ?"; } else if (question.getQuestionText().contains("Does the household own a bicycle, scooter, or motor")) { return "Does the household own a bicycle, scooter, or motor cycle? / ? ? ? / ?? ? / ? , ? ?"; } else if (question.getQuestionText().contains("Does the household own a almirah/dressing table?")) { return "Does the household own an almirah/dressing table? / ? ? ?/??? ? ? / ? ?? ?"; } else if (question.getQuestionText().contains("Does the household own a sewing machine?")) { return "Does the household own a sewing machine? / ? ? ? ? / ? ?"; } else if (question.getQuestionText().contains("How many pressure cookers or pressure pans does")) { return "How many pressure cookers or pressure pans does the household own? / ? ? ?? ??? ?? ?? ? / ? ?? ?"; } else if (question.getQuestionText().contains("How many electric fans does the household own?")) { return "How many electric fans does the household own? / ? ? ??? ?? ? / ?"; } return question.getQuestionText(); } private Integer migratePPISurvey(PPISurvey survey) { Integer questionGroupId = null; getSession().beginTransaction(); getSession().setFlushMode(FlushMode.MANUAL); try { QuestionGroupDto questionGroupDto = mapPPISurveyToQuestionGroupDto(survey); questionGroupId = createQuestionGroup(questionGroupDto, survey); Integer eventSourceId = getEventSourceId(questionGroupDto); if (migratePPISurveyResponses(survey, questionGroupId, eventSourceId)) { /* todo - we don't want to remove surveys */ getSession().getTransaction().commit(); logger.info(format("Completed migration for survey '%s' with ID %s", survey.getName(), survey.getSurveyId())); } } catch (Exception e) { logger.error(format("Unable to remove survey '%s' with ID %s", survey.getName(), survey.getSurveyId()), e); } return questionGroupId; } private Integer getEventSourceId(QuestionGroupDto questionGroupDto) { Integer eventSourceId = null; if (questionGroupDto != null) { EventSourceDto eventSourceDto = questionGroupDto.getEventSourceDtos().get(0); eventSourceId = getEventSourceId(eventSourceDto.getEvent(), eventSourceDto.getSource()); } return eventSourceId; } private Integer getEventSourceId(String event, String source) { try { return questionnaireServiceFacade.getEventSourceId(event, source); } catch (Exception e) { logger.error(format("Unable to obtain the event source ID for event %s and source %s'", event, source), e); } return null; } private QuestionGroupDto mapPPISurveyToQuestionGroupDto(PPISurvey survey) { try { return questionnaireMigrationMapper.map(survey); } catch (Exception e) { logger.error(format("Unable to convert the ppi survey, '%s' with ID, %s to a Question Group", survey.getName(), survey.getSurveyId()), e); } return null; } private Integer createQuestionGroup(QuestionGroupDto questionGroupDto, PPISurvey survey) { if (questionGroupDto != null) { try { return questionnaireServiceFacade.createQuestionGroup(questionGroupDto); } catch (Exception e) { logger.error(format("Unable to convert the ppi survey, '%s' with ID, %s to a Question Group", survey.getName(), survey.getSurveyId()), e); } } return null; } private static int surveysCount = 0; private boolean migratePPISurveyResponses(PPISurvey survey, Integer questionGroupId, Integer eventSourceId) { boolean result = false; if (questionGroupId != null && eventSourceId != null) { result = true; List<Integer> surveyInstanceIterator = null; try { getSession().beginTransaction(); surveyInstanceIterator = retrieveInstances(survey); getSession().close(); getSession().beginTransaction(); for (Integer surveyInstanceId : surveyInstanceIterator) { ++surveysCount; if (surveysCount % 1000 == 0) { getSession().getTransaction().commit(); getSession().close(); getSession().beginTransaction(); System.out.printf("%d migrated %d survey instances\n", System.currentTimeMillis(), surveysCount); } PPISurveyInstance surveyInstance = (PPISurveyInstance) getSession().get(SurveyInstance.class, surveyInstanceId); if (saveQuestionGroupInstance( mapToQuestionGroupInstance(questionGroupId, eventSourceId, surveyInstance), surveyInstance)) { /* todo - we don't want to remove surveys */ } else { result = false; } } } catch (Exception e) { getSession().getTransaction().rollback(); logger.error(format("Unable to remove survey instance '%s' (survey id: %d)", survey.getName(), survey.getSurveyId()), e); result = false; } } return result; } private QuestionGroupInstanceDto mapToQuestionGroupInstance(Integer questionGroupId, Integer eventSourceId, PPISurveyInstance surveyInstance) { QuestionGroupInstanceDto questionGroupInstanceDto = null; try { questionGroupInstanceDto = questionnaireMigrationMapper.map(surveyInstance, questionGroupId, eventSourceId); addDateSurveyTakenQuestionResponse(questionGroupInstanceDto, questionGroupId, surveyInstance); } catch (Exception e) { logger.error(format("Unable to migrate a survey instance with ID, %s for the ppi survey", surveyInstance.getInstanceId()), e); } return questionGroupInstanceDto; } private void addDateSurveyTakenQuestionResponse(QuestionGroupInstanceDto questionGroupInstanceDto, Integer questionGroupId, PPISurveyInstance surveyInstance) { Integer questionId = getDateSurveyTakenQuestionId(); Integer sectionQuestionId = questionnaireServiceFacade.getSectionQuestionId("PPI India 2008", questionId, questionGroupId); QuestionGroupResponseDto questionGroupResponseDto = new QuestionGroupResponseDto(); questionGroupResponseDto.setResponse(sdf.format((surveyInstance.getDateConducted()))); questionGroupResponseDto.setSectionQuestionId(sectionQuestionId); questionGroupInstanceDto.addQuestionGroupResponseDto(questionGroupResponseDto); } private boolean saveQuestionGroupInstance(QuestionGroupInstanceDto questionGroupInstanceDto, PPISurveyInstance surveyInstance) { if (questionGroupInstanceDto != null) { try { questionnaireServiceFacade.saveQuestionGroupInstance(questionGroupInstanceDto); return true; } catch (Exception e) { logger.error(format("Unable to migrate a survey instance with ID, %s for the ppi survey", surveyInstance.getInstanceId()), e); } } return false; } public Session getSession() { if (session == null || !session.isOpen() || !session.isConnected()) { session = sessionFactory.openSession(); session.setFlushMode(FlushMode.COMMIT); } return session; } public Integer getDateSurveyTakenQuestionId() { if (dateSurveyTakenQuestionId == null) { dateSurveyTakenQuestionId = (Integer) getSession() .createSQLQuery("select question_id from questions where question_text='Date Survey Was Taken'") .uniqueResult(); } return dateSurveyTakenQuestionId; } @SuppressWarnings("unchecked") public List<PPISurvey> retrieveAllPPIPPISurveys() { Query query = getSession().createQuery("from PPISurvey"); return query.list(); } @SuppressWarnings("unchecked") public List<Integer> retrieveInstances(PPISurvey survey) { Query query = getSession().createQuery( "select instance.instanceId from SurveyInstance as instance where instance.survey.surveyId=:SURVEY_ID"); query.setParameter("SURVEY_ID", survey.getSurveyId()); return query.list(); } }