/* * 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.framework.util; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.List; import java.util.Properties; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Option; import org.apache.commons.cli.OptionBuilder; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.commons.cli.PosixParser; import org.mifos.accounts.financial.exceptions.FinancialException; import org.mifos.config.exceptions.ConfigurationException; import org.mifos.customers.business.CustomerBO; import org.mifos.customers.persistence.CustomerDao; import org.mifos.customers.persistence.CustomerDaoHibernate; import org.mifos.framework.ApplicationInitializer; import org.mifos.framework.components.batchjobs.exceptions.TaskSystemException; import org.mifos.framework.exceptions.PersistenceException; import org.mifos.platform.questionnaire.builders.QuestionGroupInstanceDtoBuilder; import org.mifos.platform.questionnaire.builders.QuestionGroupResponseDtoBuilder; import org.mifos.platform.questionnaire.service.QuestionGroupDetail; import org.mifos.platform.questionnaire.service.QuestionnaireServiceFacade; import org.mifos.platform.questionnaire.service.SectionQuestionDetail; import org.mifos.service.test.TestingService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; @SuppressWarnings( { "PMD.SystemPrintln", "PMD.SingularField" }) public class PPITestDataGenerator { // Command line flag configuration. private static final String HELP_OPTION_NAME = "h"; private static final String TEST_DATA_FILE_OPTION_NAME = "f"; private static final String TEST_DATA_DIRECTORY_OPTION_NAME = "a"; private static final String CLIENT_GLOBAL_ID_OPTION_NAME = "i"; // Options private final Options options = new Options(); private Option helpOption; private Option allFilesInDirecoryOption; private Option testDataFileOption; private Option clientGlobalIdOption; // Variables for data from command line String testDataDirectoryName; String dataSetName; String clientGlobalId; QuestionnaireServiceFacade questionnaireServiceFacade; CustomerDao customerDao; public static void main(String[] args) throws Exception { PPITestDataGenerator util = new PPITestDataGenerator(); util.loadTestDataFiles(args); } public PPITestDataGenerator() { defineOptions(); } private QuestionGroupDetail findQuestionGroup(String name) { List<QuestionGroupDetail> list = questionnaireServiceFacade.getAllQuestionGroups(); for (QuestionGroupDetail qg: list) { if (qg.getTitle().compareTo(name) == 0) { return qg; } } throw new RuntimeException("Could not find a question group named: " + name); } public void loadTestDataFiles(String[] args) throws IOException, TaskSystemException, PersistenceException, ConfigurationException, FinancialException { parseOptions(args); ApplicationContext applicationContext = initializeSpring(); customerDao = applicationContext.getBean(CustomerDaoHibernate.class); questionnaireServiceFacade = applicationContext.getBean(QuestionnaireServiceFacade.class); if (testDataDirectoryName != null) { File directory = new File(testDataDirectoryName); File[] listOfFiles = directory.listFiles(); if (listOfFiles != null ) { int totalFilesToLoad = countFilesToUpgrade(listOfFiles); int filesLoaded = 0; for (File listOfFile : listOfFiles) { String currentFilename = listOfFile.getName(); if (listOfFile.isFile() && currentFilename.endsWith("Testing.properties")) { String dataFileName = testDataDirectoryName + File.separator + currentFilename; loadData(dataFileName, applicationContext); filesLoaded++; System.out.println("Finished " + filesLoaded + "/" + totalFilesToLoad); } } } else { fail("No files found in directory: " + testDataDirectoryName); } } else { loadData(dataSetName, applicationContext); } } private int countFilesToUpgrade(File[] listOfFiles) { int fileCount = 0; for (File listOfFile : listOfFiles) { String currentFilename = listOfFile.getName(); if (listOfFile.isFile() && currentFilename.endsWith("Testing.properties")) { ++fileCount; } } return fileCount; } private void loadData(String filename, ApplicationContext applicationContext) throws TaskSystemException, PersistenceException, ConfigurationException, FinancialException, FileNotFoundException, IOException { System.setProperty(TestingService.TEST_MODE_SYSTEM_PROPERTY,"acceptance"); ApplicationInitializer applicationInitializer = new ApplicationInitializer(); applicationInitializer.dbUpgrade(applicationContext); applicationInitializer.setAttributesOnContext(null); CustomerBO customer = customerDao.findClientBySystemId(clientGlobalId); if (customer == null) { fail("Could not find customer for global id: " + clientGlobalId); } System.out.println("Found: " + customer.getDisplayName()); Properties properties = new Properties(); properties.load(new FileReader(filename)); System.out.println("Loading data for: " + properties.getProperty("questionGroup.name")); questionnaireServiceFacade.uploadPPIQuestionGroup(properties.getProperty("questionGroup.xml.filename")); QuestionGroupDetail qg = findQuestionGroup(properties.getProperty("questionGroup.name")); int surveyCount = Integer.parseInt(properties.getProperty("survey.count")); for (int surveyNum = 1; surveyNum <= surveyCount; ++surveyNum) { createSurveyInstance(customer, properties, qg, surveyNum); } System.out.println("done!"); } private void createSurveyInstance(CustomerBO customer, Properties properties, QuestionGroupDetail qg, int surveyNum) { Integer creatorId = 1; QuestionGroupInstanceDtoBuilder instanceBuilder = new QuestionGroupInstanceDtoBuilder(); instanceBuilder.withQuestionGroup(qg.getId()).withCompleted(true).withCreator(creatorId). withEventSource(1).withEntity(customer.getCustomerId()).withVersion(1); List<SectionQuestionDetail> questions = qg.getSectionDetail(0).getQuestions(); for (SectionQuestionDetail question: questions) { String responseKey = "survey." + surveyNum + ".question." + question.getSequenceNumber() + ".response.text"; String questionResponse = properties.getProperty(responseKey); QuestionGroupResponseDtoBuilder responseBuilder = new QuestionGroupResponseDtoBuilder(); responseBuilder.withSectionQuestion(question.getQuestionId()).withResponse(questionResponse); instanceBuilder.addResponses(responseBuilder.build()); } questionnaireServiceFacade.saveQuestionGroupInstance(instanceBuilder.build()); } public static ApplicationContext initializeSpring() { return new ClassPathXmlApplicationContext( "classpath:/org/mifos/config/resources/applicationContext.xml", "classpath:/META-INF/spring/QuestionnaireContext.xml"); } private void defineOptions() { helpOption = OptionBuilder .withLongOpt("help") .withDescription( "display help" ) .create( HELP_OPTION_NAME ); allFilesInDirecoryOption = OptionBuilder.withArgName( "test data directory" ) .withLongOpt("dataDirectory") .hasArg() .withDescription( "Use all test data in this directory-- include the full path (e.g. /home/me/testData )" ) .create( TEST_DATA_DIRECTORY_OPTION_NAME ); testDataFileOption = OptionBuilder.withArgName( "test data file name" ) .withLongOpt("dataset") .hasArg() .withDescription( "Use the test data file with this name-- include the full file path (e.g. /home/me/testData/Bangladesh2009Testing.properties" ) .create( TEST_DATA_FILE_OPTION_NAME ); clientGlobalIdOption = OptionBuilder.withArgName( "global id of client" ) .withLongOpt("clientGlobalId") .hasArg() .withDescription( "The global (or system) Id of the client to use when creating PPI survey results (e.g. 0003-000000006)") .create( CLIENT_GLOBAL_ID_OPTION_NAME ); options.addOption(helpOption); options.addOption(allFilesInDirecoryOption); options.addOption(testDataFileOption); options.addOption(clientGlobalIdOption); } public void parseOptions(String[] args) { // create the command line parser CommandLineParser parser = new PosixParser(); try { // parse the command line arguments CommandLine line = parser.parse( options, args ); if( line.hasOption( HELP_OPTION_NAME ) ) { showHelp(options); System.exit(0); } if( line.hasOption( TEST_DATA_FILE_OPTION_NAME ) ) { if (line.hasOption( TEST_DATA_DIRECTORY_OPTION_NAME)) { fail("Specify either a data set (-f) or data directory (-a) but not both."); } dataSetName = line.getOptionValue(TEST_DATA_FILE_OPTION_NAME); } else if( line.hasOption( TEST_DATA_DIRECTORY_OPTION_NAME ) ) { testDataDirectoryName = line.getOptionValue(TEST_DATA_DIRECTORY_OPTION_NAME); } else { fail("Specify either a data set (-f) or data directory (-a)"); } if( line.hasOption( CLIENT_GLOBAL_ID_OPTION_NAME ) ) { clientGlobalId = line.getOptionValue(CLIENT_GLOBAL_ID_OPTION_NAME); } else { missingOption(clientGlobalIdOption); } } catch( ParseException exp ) { fail( "Parsing failed. Reason: " + exp.getMessage() ); } } private static void showHelp(Options options) { HelpFormatter formatter = new HelpFormatter(); formatter.printHelp( "PPITestDataGenerator", options ); } private static void missingOption(Option option) { fail("Missing required option: " + option.getArgName()); } private static void fail(String string) { System.err.println( string ); System.exit(0); } }