001: package com.xoetrope.survey;
002:
003: import java.io.BufferedWriter;
004: import java.io.BufferedReader;
005: import java.io.File;
006: import java.io.FileInputStream;
007: import java.io.FileNotFoundException;
008: import java.io.FileWriter;
009: import java.io.IOException;
010: import java.io.Writer;
011: import java.sql.PreparedStatement;
012: import java.sql.ResultSet;
013: import java.sql.SQLException;
014: import java.sql.Statement;
015: import java.util.Date;
016: import java.util.Enumeration;
017: import java.util.HashMap;
018: import java.util.Properties;
019: import java.util.Vector;
020:
021: import net.n3.nanoxml.XMLElement;
022: import net.n3.nanoxml.XMLWriter;
023: import net.xoetrope.debug.DebugLogger;
024: import com.xoetrope.carousel.build.BuildProperties;
025: import net.xoetrope.optional.data.sql.ConnectionObject;
026: import net.xoetrope.optional.data.sql.NamedConnectionManager;
027: import net.xoetrope.xui.XLifeCycleListener;
028: import net.xoetrope.xui.XProject;
029: import net.xoetrope.xui.data.XModel;
030:
031: /**
032: * <p>Loads and manages surveys. The manager can maintain a number of surveys so
033: * that different surveys can be served up by the same application instance if
034: * for example a different set of questions were to be asked depending on the
035: * user (e.g. in a hotel a different survey would be asked for a conference
036: * attendee and a residential guest).</p>
037: *
038: * <p> Copyright (c) Xoetrope Ltd., 2001-2006, This software is licensed under
039: * the GNU Public License (GPL), please see license.txt for more details. If
040: * you make commercial use of this software you must purchase a commercial
041: * license from Xoetrope.</p>
042: * <p> $Revision: 1.5 $</p>
043: */
044: public class SurveyManager implements XLifeCycleListener {
045: public static final int DATA_FILE = 0;
046: public static final int DATA_DB = 1;
047:
048: private static final String DEF_EXCLUSIVE_TEMPLATE = "exclusiveTemplate";
049: private static final String DEF_MULTIPLE_TEMPLATE = "multipleTemplate";
050: private static final String DEF_FREETEXT_TEMPLATE = "freeTemplate";
051: private static final String DEF_SURVEY_DIR = "lang";
052: private static final String DEF_RESPONSES_FILE = "responses.xml";
053: private static final String LANGUAGE_FILE = "lang/LanguageList.properties";
054:
055: protected XProject currentProject;
056: protected Vector surveys;
057: protected Survey currentSurvey;
058:
059: // File/database
060: protected int outputType;
061:
062: // File/databse
063: protected int inputType;
064:
065: // responses db file
066: protected String resFile;
067:
068: // responses db configuration
069: protected Properties outputDbConfiguration;
070:
071: // input data db configuration
072: protected Properties inputDbConfiguration;
073:
074: // the name of the current survey
075: protected String surveyName;
076:
077: // the name of the last page
078: protected String thankYouPage;
079:
080: // the name of the first page
081: protected String startPage;
082:
083: // should the survey be restarted automatically
084: protected boolean restartSurvey;
085:
086: protected String exclusiveTemplate;
087: protected String multipleTemplate;
088: protected String freeTemplate;
089:
090: protected int questionsPerPage = 5;
091: protected int numLanguages;
092: protected Properties langProperties;
093:
094: protected NamedConnectionManager connMgr;
095:
096: /**
097: * Creates a new instance of Survey Manager
098: * @param p the properties of this survey manager
099: */
100: public SurveyManager() {
101: surveys = new Vector();
102: currentSurvey = null;
103: connMgr = (NamedConnectionManager) NamedConnectionManager
104: .getInstance();
105: }
106:
107: /**
108: * Create a survey manager
109: * @param proj the owner project
110: */
111: public SurveyManager(XProject proj) {
112: currentProject = proj;
113: surveys = new Vector();
114: currentSurvey = null;
115: connMgr = (NamedConnectionManager) NamedConnectionManager
116: .getInstance();
117: }
118:
119: /**
120: * Gets whether the user responses should be
121: * stored into the database or the file.
122: */
123: public int getSurveyOutputType() {
124: return outputType;
125: }
126:
127: /**
128: * Gets whether the survey questions should be read
129: * from the database or the file.
130: */
131: public int getSurveyInputType() {
132: return inputType;
133: }
134:
135: /**
136: * Gets the max number of questions that
137: * can be shown on a single page in the
138: * survey application.
139: * @return the number of questions
140: */
141: public int getQuestionsPerPage() {
142: return questionsPerPage;
143: }
144:
145: /**
146: * Indicates whether the survey should be restated
147: * automatically
148: * @return "restartSurvey" value
149: */
150: public boolean restartSurvey() {
151: return restartSurvey;
152: }
153:
154: /**
155: * Sets whether to restart automatically the survey application.
156: * @param restart true if the application should be restarted, false otherwise
157: */
158: public void setRestartSurvey(boolean restart) {
159: restartSurvey = restart;
160: }
161:
162: /**
163: * Gets the name of the first page
164: * in the survey application
165: * @return the page name
166: */
167: public String getStartPage() {
168: return startPage;
169: }
170:
171: /**
172: * Gets the name of the file defining the template
173: * for a "multiple choice" type of questions.
174: * @return the name of the file.
175: */
176: public String getMultipleChoiceTemplate() {
177: return multipleTemplate;
178: }
179:
180: /**
181: * Sets the name of the file defining the template
182: * for "multiple choice" type of questions.
183: * @param multipleChoiceTemplate the name of the file
184: */
185: public void setMultipleChoiceTemplate(String multipleChoiceTemplate) {
186: multipleTemplate = multipleChoiceTemplate;
187: }
188:
189: /**
190: * Gets the name of the file defining the template
191: * for "mutually exclusive" type of questions.
192: * @return the name of the file.
193: */
194: public String getMutuallyExclusiveTemplate() {
195: return exclusiveTemplate;
196: }
197:
198: /**
199: * Sets the name of the file defining the template
200: * for "mutually exclusive" type of questions.
201: * @param mutuallyExclusiveTemplate the name of the file
202: */
203: public void setMutuallyExclusiveTemplate(
204: String mutuallyExclusiveTemplate) {
205: exclusiveTemplate = mutuallyExclusiveTemplate;
206: }
207:
208: /**
209: * Gets the name of the file defining the template
210: * for "free text" type of questions.
211: */
212: public String getFreeTextTemplate() {
213: return freeTemplate;
214: }
215:
216: /**
217: * Sets the name of the file defining the template
218: * for "free text" type of questions.
219: * @return the name of the file.
220: */
221: public void setFreeTextTemplate(String freeTextTemplate) {
222: freeTemplate = freeTextTemplate;
223: }
224:
225: /**
226: * Gets the name of the last page ("thank you" page)
227: * in the survey application
228: * @return the page name
229: */
230: public String getFinishPage() {
231: return thankYouPage;
232: }
233:
234: /**
235: * Sets the name of the last page ("thank you" page)
236: * in the survey application
237: * @param fp the new name of the last page
238: */
239: public void setFinishPage(String fp) {
240: thankYouPage = fp;
241: }
242:
243: /**
244: * Reads the "output data" configuration from the
245: * project's startup.properties file.
246: */
247: private void setupOutputConfiguration() {
248: String ot = currentProject.getStartupParam("SurveyOutputType");
249: outputType = ("Db".equals(ot) ? DATA_DB : DATA_FILE);
250:
251: if (outputType == DATA_DB) {
252: outputDbConfiguration = new Properties();
253: String user = currentProject
254: .getStartupParam("SurveyOutputDbUser");
255: outputDbConfiguration.put("outputDbUser",
256: user != null ? user : "");
257: String password = currentProject
258: .getStartupParam("SurveyOutputDbPassword");
259: outputDbConfiguration.put("outputDbPassword",
260: password != null ? password : "");
261: String url = currentProject
262: .getStartupParam("SurveyOutputDbUrl");
263: outputDbConfiguration.put("outputDbUrl", url != null ? url
264: : "");
265: String driver = currentProject
266: .getStartupParam("SurveyOutputDbDriver");
267: outputDbConfiguration.put("outputDbDriver",
268: driver != null ? driver : "");
269: } else {
270: resFile = currentProject
271: .getStartupParam("SurveyOutputFile");
272: if (resFile == null)
273: resFile = DEF_RESPONSES_FILE;
274: }
275: }
276:
277: /**
278: * Reads the name of the default language from the project's
279: * startup properties file and sets it as an active language
280: */
281: private void setupDefaultLanguage() {
282: // set the default language
283: String langName = null;
284: String defLang = currentProject.getStartupParam("Language");
285: Enumeration langNamesEnum = langProperties.keys();
286: while (langNamesEnum.hasMoreElements() && (langName == null)) {
287: String key = (String) langNamesEnum.nextElement();
288: if (langProperties.getProperty(key).equals(defLang))
289: langName = key;
290: }
291: if (langName == null)
292: langName = "English";
293:
294: // save the default language to the model
295: XModel langModel = (XModel) currentProject.getModel().get(
296: "currentSurveyLanguage");
297: langModel.set(langName);
298: }
299:
300: /**
301: * Read the "input.data" configuration from the project's
302: * startup.properties file.
303: */
304: private void setupInputConfiguration() {
305: surveyName = currentProject.getStartupParam("SurveyName");
306:
307: // input type, either Db or File
308: String it = currentProject.getStartupParam("SurveyInputType");
309: inputType = ("Db".equals(it) ? DATA_DB : DATA_FILE);
310:
311: langProperties = new Properties();
312: try {
313: langProperties.load(new FileInputStream(new File(
314: LANGUAGE_FILE)));
315: } catch (Exception ex) {
316: langProperties.put("English", "en");
317: }
318:
319: // read the input database configuration
320: if (inputType == DATA_DB) {
321: inputDbConfiguration = new Properties();
322: String user = currentProject
323: .getStartupParam("SurveyInputDbUser");
324: if (user != null)
325: inputDbConfiguration.put("inputDbUser", user);
326: String password = currentProject
327: .getStartupParam("SurveyInputDbPassword");
328: if (password != null)
329: inputDbConfiguration.put("inputDbPassword", password);
330: String url = currentProject
331: .getStartupParam("SurveyInputDbUrl");
332: if (url != null)
333: inputDbConfiguration.put("inputDbUrl", url);
334: String driver = currentProject
335: .getStartupParam("SurveyInputDbDriver");
336: if (driver != null)
337: inputDbConfiguration.put("inputDbDriver", driver);
338: }
339: }
340:
341: /**
342: * Reads the survey configuration (i.e. questions per page, template names, etc..)
343: * from the project's startup.properties file.
344: */
345: private void setupBasicConfiguration() {
346: startPage = currentProject.getStartupParam("StartClass");
347:
348: // the max number of questions that can be shown on a single page
349: questionsPerPage = 5;
350: try {
351: questionsPerPage = new Integer(currentProject
352: .getStartupParam("QuestionsPerPage")).intValue();
353: } catch (NumberFormatException e) {
354: }
355:
356: // restart an application
357: restartSurvey = "true".equals(currentProject
358: .getStartupParam("RestartSurvey"));
359:
360: // question format
361: String questionFormat = currentProject
362: .getStartupParam("DefaultQuestionFormat");
363: if ("TemplateQuestion".equals(questionFormat)) {
364:
365: multipleTemplate = currentProject
366: .getStartupParam("MultipleChoiceTemplate");
367: if (multipleTemplate == null)
368: multipleTemplate = DEF_MULTIPLE_TEMPLATE;
369:
370: exclusiveTemplate = currentProject
371: .getStartupParam("MutuallyExclusiveTemplate");
372: if (exclusiveTemplate == null)
373: exclusiveTemplate = DEF_EXCLUSIVE_TEMPLATE;
374:
375: freeTemplate = currentProject
376: .getStartupParam("FreeTextTemplate");
377: if (freeTemplate == null)
378: freeTemplate = DEF_FREETEXT_TEMPLATE;
379: }
380:
381: thankYouPage = currentProject.getStartupParam("FinishPage");
382:
383: // build the ruleEngine via reflection
384: RuleEngine ruleEngine = null;
385: try {
386: String ruleEngineName = currentProject
387: .getStartupParam("RuleEngine");
388: ruleEngine = (RuleEngine) (ruleEngineName == null ? new DefaultRuleEngine()
389: : Class.forName(ruleEngineName).newInstance());
390: } catch (Exception e) {
391: ruleEngine = new DefaultRuleEngine();
392: }
393: currentProject.setObject("RuleEngine", ruleEngine);
394: }
395:
396: /**
397: * Initializes this survey manager
398: * @param project the owner project
399: */
400: public void initialize(XProject project) {
401: try {
402: currentProject = project;
403: currentProject.setObject("SurveyManager", this );
404:
405: surveys = new Vector();
406:
407: // rules engine, questions per page, etc...
408: setupBasicConfiguration();
409:
410: // questions
411: setupInputConfiguration();
412:
413: // responses
414: setupOutputConfiguration();
415:
416: // setup the default survey language
417: setupDefaultLanguage();
418:
419: // add the defined connections to the NamedConnectionManager
420: if (outputType == DATA_DB)
421: setupOutputConnection();
422:
423: if (inputType == DATA_DB)
424: setupInputConnection();
425:
426: } catch (Exception ex) {
427: ex.printStackTrace();
428: }
429: }
430:
431: /**
432: * Sets up the "output data" database connection.
433: */
434: private void setupOutputConnection() {
435: String user = outputDbConfiguration.getProperty("outputDbUser");
436: String password = outputDbConfiguration
437: .getProperty("outputDbPassword");
438: String url = outputDbConfiguration.getProperty("outputDbUrl");
439: String driver = outputDbConfiguration
440: .getProperty("outputDbDriver");
441: connMgr.addConnection("SurveyOutputDb", driver, url, user,
442: password);
443: }
444:
445: /**
446: * Sets up the "input data" database connection
447: */
448: private void setupInputConnection() {
449: String user = inputDbConfiguration.getProperty("inputDbUser");
450: String password = inputDbConfiguration
451: .getProperty("inputDbPassword");
452: String url = inputDbConfiguration.getProperty("inputDbUrl");
453: String driver = inputDbConfiguration
454: .getProperty("inputDbDriver");
455: connMgr.addConnection("SurveyInputDb", driver, url, user,
456: password);
457: }
458:
459: /**
460: * Gets the connectionObject used to store the user's responses in
461: * the specified database.
462: * @return the ConnectionObject
463: */
464: public ConnectionObject getOutputConnectionObject() {
465: try {
466: return connMgr.getConnection("SurveyOutputDb");
467: } catch (Exception ex) {
468: ex.printStackTrace();
469: }
470: return null;
471: }
472:
473: /**
474: * Gets the connectionObject used to retrieve the survey questions from
475: * the specified database.
476: * @return the ConnectionObject
477: */
478: public ConnectionObject getInputConnectionObject() {
479: try {
480: return connMgr.getConnection("SurveyInputDb");
481: } catch (Exception ex) {
482: ex.printStackTrace();
483: }
484: return null;
485: }
486:
487: public void shutdown() {
488: }
489:
490: /**
491: * Sets the specified survey as the current one
492: * @param survey survey to be set as current.
493: */
494: public void setCurrentSurvey(Survey survey) {
495: currentSurvey = survey;
496: }
497:
498: /**
499: * Gets the number of available languages
500: * @return the number of languages
501: */
502: public int getNumLanguages() {
503: return numLanguages;
504: }
505:
506: /**
507: * Gets the survey associated with the specified language.
508: * @param languageName the name of the language
509: * @return the name of the survey file.
510: */
511: public String getSurveyFile(String languageName) {
512: String langCode = langProperties
513: .getProperty(languageName, "en");
514: return (langCode + "_" + surveyName + ".xml");
515: }
516:
517: /**
518: * Gets the current survey
519: * @return current survey
520: */
521: public Survey getCurrentSurvey() {
522: return currentSurvey;
523: }
524:
525: /**
526: * Gets the id/name of the survey stored in
527: * the database
528: * @return the survey name
529: */
530: public String getCurrentSurveyName() {
531: return surveyName;
532: }
533:
534: /**
535: * Sets the id/name of the survey stored in
536: * the database
537: * @param sn the name of the survey
538: */
539: public void setSurveyName(String sn) {
540: surveyName = sn;
541: }
542:
543: /**
544: * Gets the number of survey currently loaded
545: * @return the number of surveys
546: */
547: public int getNumSurveys() {
548: return surveys.size();
549: }
550:
551: /**
552: * Gets a survey with the specified index
553: * @param index the index of the survey to return
554: * @return the survey with the specified index
555: */
556: public Survey getSurvey(int index) {
557: return (Survey) surveys.elementAt(index);
558: }
559:
560: /**
561: * Loads the specified survey and sets it as the current one.
562: * @param file the file containing the survey to be loaded
563: * @param surveyId the id of the survey
564: * @param surveyName the name of the survey
565: */
566: public void loadSurvey(File file, int surveyId, String surveyName)
567: throws Exception {
568: BufferedReader br = null;
569: try {
570: currentSurvey = new Survey();
571: currentSurvey.setName(surveyName);
572: currentSurvey.setId(surveyId);
573: currentSurvey.setNumQuestionsPerPage(questionsPerPage);
574: surveys.add(currentSurvey);
575: br = currentProject.getBufferedReader(file, null);
576: if (br != null)
577: currentSurvey.read(br);
578: } finally {
579: if (br != null)
580: br.close();
581: }
582: }
583:
584: /**
585: * Loads the specified survey and sets it as the current one.
586: * @param co ConnectionObject used to retrieve the survey questions from
587: * the database.
588: * @param surveyId the ID of the survey to be retrieved
589: * @param surveyName the name of the survey to be retrieved
590: */
591: public void loadSurvey(ConnectionObject co, String surveyName,
592: String languageName) {
593: currentSurvey = new Survey();
594: currentSurvey.setName(surveyName);
595: surveys.add(currentSurvey);
596: try {
597: currentSurvey.read(co, surveyName, languageName);
598: } catch (Exception ex) {
599: ex.printStackTrace();
600: }
601: }
602:
603: /**
604: * Loads the current survey's questions in
605: * the specified language
606: * @param langName the name of the language
607: */
608: public void loadSurvey(String langName) throws Exception {
609: if (inputType == DATA_DB) {
610: String langCode = langProperties
611: .getProperty(langName, "en");
612: loadSurveyFromDb(surveyName, langCode);
613: } else {
614: // get the file name containing the questions
615: String fileName = getSurveyFile(langName);
616: fileName = DEF_SURVEY_DIR + File.separator + fileName;
617: loadSurveyFromFile(new File(fileName));
618: }
619: }
620:
621: /**
622: * Loads the specified survey from the database
623: * @param surveyName the name of the survey to be loaded
624: * @param languageName the name of the language
625: */
626: public void loadSurveyFromDb(String surveyName, String languageName)
627: throws Exception {
628: ConnectionObject co = getInputConnectionObject();
629: loadSurvey(co, surveyName, languageName);
630: co.close();
631: }
632:
633: /**
634: * Loads the survey from the specified file
635: * @param file the file containing the survey
636: */
637: public void loadSurveyFromFile(File file) throws Exception {
638: loadSurvey(file, getNextSurveyId(), "");
639: }
640:
641: /**
642: * Gets the id of the next survey int survey list
643: * contained in this survey manager.
644: * @return the id of the next survey.
645: */
646: public int getNextSurveyId() {
647: int maxId = 0;
648: Enumeration enumSurveys = surveys.elements();
649: while (enumSurveys.hasMoreElements()) {
650: Survey survey = (Survey) enumSurveys.nextElement();
651: if (survey.getId() > maxId)
652: maxId = survey.getId();
653: }
654: return (maxId + 1);
655: }
656:
657: /**
658: * Loads a survey from file such that the file names is <name>_<language>.xml
659: * e.g. mysurvey_en.xml
660: * @param name the name of the survey
661: * @param index the index of the survey
662: * @param language the ISO language code
663: */
664:
665: public void loadSurvey(int index, String name, String language,
666: String path) {
667: Survey oldSurvey = currentSurvey;
668: if (index >= surveys.size()) {
669: currentSurvey = new Survey(name);
670: surveys.add(currentSurvey);
671: } else {
672: currentSurvey = getSurvey(index);
673: }
674:
675: String fileName = path + name + "_" + language + ".xml";
676: System.err.println(fileName);
677: try {
678: BufferedReader br = currentProject
679: .getBufferedReader(fileName);
680: if (br != null)
681: currentSurvey.read(br);
682: } catch (Exception ex) {
683: ex.printStackTrace();
684: }
685: if (currentSurvey != null)
686: currentSurvey.setNumQuestionsPerPage(questionsPerPage);
687: }
688:
689: public void saveUserResponses(Vector responses) {
690: if (outputType == DATA_DB) {
691: java.sql.Date startTime = new java.sql.Date(currentSurvey
692: .getStartTime().getTime());
693: java.sql.Date endTime = new java.sql.Date(new Date()
694: .getTime());
695: saveUserResponsesDb(responses, startTime, endTime);
696: } else {
697: saveUserResponsesFile(responses);
698: }
699: }
700:
701: /**
702: * Saves the given responses the the database
703: * @param responses the vector containing responses
704: * @param st startTime
705: * @param et endTime
706: */
707: protected void saveUserResponsesDb(Vector responses,
708: java.sql.Date startTime, java.sql.Date endTime) {
709: ConnectionObject connObj = getOutputConnectionObject();
710:
711: // respondant
712: int respondandId = 0;
713: try {
714: Statement resIdStmt = connObj.createStatement();
715: ResultSet rs = resIdStmt
716: .executeQuery("SELECT MAX(RespondandID) FROM Respondandts ");
717: if (rs.next())
718: respondandId = rs.getInt(1) + 1;
719: connObj.closeStatement();
720: } catch (Exception ex) {
721: ex.printStackTrace();
722: }
723:
724: // get the next resultset id
725: int resultSetId = 0;
726: try {
727: Statement setIdStmt = connObj.createStatement();
728: ResultSet rs = setIdStmt
729: .executeQuery("SELECT MAX(ResultSetID) FROM ResultSets ");
730: if (rs.next())
731: resultSetId = rs.getInt(1) + 1;
732: connObj.closeStatement();
733: } catch (Exception ex) {
734: ex.printStackTrace();
735: }
736:
737: int surveyId = currentSurvey.getId();
738:
739: try {
740: String sql = "INSERT INTO Respondants VALUES(?,?,?,?,?)";
741: PreparedStatement respondantStmt = connObj
742: .prepareStatement(sql);
743: respondantStmt.setInt(1, respondandId);
744: respondantStmt.setInt(2, resultSetId);
745: respondantStmt.setDate(3, startTime);
746: respondantStmt.setDate(4, endTime);
747: respondantStmt.setInt(5, surveyId);
748: respondantStmt.execute();
749: connObj.closePreparedStatement();
750:
751: sql = "INSERT INTO ResultSets VALUES(?,?,?,?)";
752: PreparedStatement resultStmt = connObj
753: .prepareStatement(sql);
754: Enumeration enumResponses = responses.elements();
755: while (enumResponses.hasMoreElements()) {
756: Condition condition = (Condition) enumResponses
757: .nextElement();
758: int questionId = condition.getQuestion().getId();
759:
760: int numResponses = condition.getOptions().size();
761: for (int i = 0; i < numResponses; i++) {
762: Option option = (Option) condition.getOptions()
763: .get(i);
764: int optionId = option.getId();
765: String answer = (String) condition.getAnswers()
766: .get(i);
767:
768: resultStmt.setInt(1, resultSetId);
769: resultStmt.setInt(2, questionId);
770: resultStmt.setInt(3, optionId);
771: resultStmt.setString(4, answer);
772:
773: resultStmt.execute();
774: }
775: }
776: connObj.closePreparedStatement();
777: } catch (Exception ex) {
778: ex.printStackTrace();
779: }
780: }
781:
782: /**
783: * Saves the responses given in the current survey to a file
784: * @param responses Vector containing user given repsonses
785: */
786: protected void saveUserResponsesFile(Vector responses) {
787: if (currentSurvey == null)
788: return;
789:
790: try {
791:
792: // if the file doesn't exists create it
793: File file = new File(resFile);
794: if (!file.exists())
795: file.createNewFile();
796:
797: FileWriter fw = new FileWriter(resFile);
798:
799: Writer bw = new BufferedWriter(fw);
800: if (bw != null) {
801: currentSurvey.writeUserResponses(bw, responses);
802: bw.flush();
803: bw.close();
804: }
805: } catch (Exception e) {
806: e.printStackTrace();
807: }
808: }
809:
810: /**
811: * Saves the repsonses given in the current survey to a file
812: * @param responses Vector containg user given responses
813: */
814: public void saveSurvey(int index, String name, String language,
815: String path) {
816: if (index < surveys.size()) {
817: Survey survey = getSurvey(index);
818: String fileName = path + name + "_" + language + ".xml";
819: try {
820: FileWriter fw = new FileWriter(fileName);
821: Writer bw = new BufferedWriter(fw);
822: if (bw != null)
823: survey.write(bw);
824: } catch (Exception ex) {
825: ex.printStackTrace();
826: }
827: }
828: }
829:
830: /**
831: * Saves the current survey (in the xml format) to
832: * the specified file
833: * @param file the file where the current survey is to
834: * be saved to
835: */
836: public void saveSurvey(File file) throws Exception {
837: FileWriter fw = null;
838: Writer bw = null;
839: try {
840: fw = new FileWriter(file);
841: bw = new BufferedWriter(fw);
842: currentSurvey.write(bw);
843: bw.flush();
844: } finally {
845: bw.close();
846: }
847: }
848:
849: /**
850: * Reset the current survey. Any unsaved session data will be saved prior to
851: * reset. The reset puts the survey into the same state as following the
852: * initial load. All counters are reset.
853: */
854: public void reset() {
855: currentSurvey.restartSurvey();
856: }
857:
858: /**
859: * Writes the survey to the output stream
860: * @param writer the output stream
861: */
862: public void write(Writer writer) {
863: try {
864: int numSurveys = surveys.size();
865: XMLElement xml = new XMLElement("Data");
866: for (int i = 0; i < numSurveys; i++) {
867: XMLElement surveyXml = new XMLElement("Survey");
868: Survey survey = (Survey) surveys.elementAt(i);
869: surveyXml.setAttribute("name", survey.getName());
870:
871: XResponseSet responses = survey.getResponses();
872: XMLElement questionXml = new XMLElement("Questions");
873: questionXml.setAttribute("values", responses
874: .getQuestions());
875:
876: int numSessions = responses.getNumSessions();
877: for (int j = 0; j < numSessions; j++) {
878: responses.selectSession(j);
879: XMLElement responseXml = new XMLElement("Response");
880: responseXml.setAttribute("values", responses
881: .getResponse());
882: responseXml.setAttribute("start", responses
883: .getStartTime());
884: responseXml.setAttribute("end", responses
885: .getEndTime());
886: questionXml.addChild(responseXml);
887: }
888:
889: surveyXml.addChild(questionXml);
890: xml.addChild(surveyXml);
891: }
892: XMLWriter xmlWriter = new XMLWriter(writer);
893: xmlWriter.write(xml, true, 4);
894: } catch (IOException ex) {
895: if (BuildProperties.DEBUG)
896: DebugLogger.logError("Unable to write survey results");
897: }
898: }
899:
900: /**
901: * Checks for saved sessions
902: * @return true if there are saved sessions, otherwise false
903: */
904: public boolean hasSessions() {
905: int numSurveys = surveys.size();
906: for (int i = 0; i < numSurveys; i++) {
907: Survey survey = (Survey) surveys.elementAt(i);
908: XResponseSet responses = survey.getResponses();
909: if (responses.getNumSessions() > 0)
910: return true;
911: }
912: return false;
913: }
914:
915: /**
916: * Restart the session recording
917: */
918: public void restart() {
919: int numSurveys = surveys.size();
920: for (int i = 0; i < numSurveys; i++)
921: ((Survey) surveys.elementAt(i)).restart();
922: }
923:
924: /**
925: * Can the current project close?
926: * @param project the project initiating the shutdown
927: * @return true if the application can close
928: */
929: public boolean canClose(XProject project) {
930: return true;
931: }
932: }
|