001: package com.xoetrope.survey;
002:
003: import java.io.Reader;
004: import java.util.Enumeration;
005: import java.util.Vector;
006:
007: import net.xoetrope.xml.XmlElement;
008: import net.xoetrope.xml.XmlSource;
009: import net.xoetrope.xui.XProject;
010: import net.xoetrope.xui.XProjectManager;
011: import net.xoetrope.xui.data.XDataBinding;
012: import net.xoetrope.xui.data.XModel;
013:
014: /**
015: * An XSurvey contains the definition of a survey, the questions
016: * and the responses. The definitions are read from file and passed on to the
017: * question manager for rotation. The survey definition is largely independant
018: * of how the surveys are presented or rendered</p>
019: *
020: * <p> Copyright (c) Xoetrope Ltd., 2001-2006, This software is licensed under
021: * the GNU Public License (GPL), please see license.txt for more details. If
022: * you make commercial use of this software you must purchase a commercial
023: * license from Xoetrope.</p>
024: * <p> $Revision: 1.9 $</p>
025: */
026: public class XSurvey {
027: private String name;
028:
029: private Vector questionGroups;
030: private Vector bindings;
031: private XResponseSet responseSet;
032: private boolean hasQuestions = false;
033:
034: /**
035: * The owning project / the context for this object
036: */
037: XProject currentProject = XProjectManager.getCurrentProject();
038:
039: /**
040: * Creates a new survey
041: * @param n the name of the survey
042: */
043: public XSurvey(String n) {
044: name = n;
045: questionGroups = new Vector();
046: bindings = new Vector();
047: responseSet = new XResponseSet(name);
048: }
049:
050: /**
051: * Gets the survey name
052: * @return the survey name
053: */
054: public String getName() {
055: return name;
056: }
057:
058: /**
059: * Reads the survey from the input stream
060: * @param r the input stream reader
061: */
062: public void read(Reader r) {
063: XmlElement ele = XmlSource.read(r);
064: Vector v = ele.getChildren();
065: if (v != null) {
066: int numGroups = v.size();
067: int scale = new Integer(ele.getAttribute("scale"))
068: .intValue();
069: XModel model = currentProject.getModel();
070: for (int i = 0; i < numGroups; i++) {
071: XmlElement xmlGroup = (XmlElement) v.elementAt(i);
072: char c = xmlGroup.getName().charAt(0);
073: if (c == 'G') {
074: //QuestionGroup currentGroup = new QuestionGroup( new Integer( xmlGroup.getAttribute( "id" )).intValue());
075: QuestionGroup currentGroup = new QuestionGroup(
076: new Integer(xmlGroup.getAttribute("id "))
077: .intValue(), "group");
078: Vector children = xmlGroup.getChildren();
079: int numQuestions = children.size();
080: for (int j = 0; j < numQuestions; j++) {
081: XmlElement xmlQuestion = (XmlElement) children
082: .elementAt(j);
083: char cq = xmlQuestion.getName().charAt(0);
084: if (cq == 'Q') {
085: Question currentQuestion = new Question(
086: Integer.parseInt(xmlQuestion
087: .getAttribute("id")),
088: currentGroup);
089: Vector questionResponses = xmlQuestion
090: .getChildren();
091: int numResponses = questionResponses.size();
092: currentQuestion.setSize(Math.max(
093: numResponses, scale));
094: for (int k = 0; k < numResponses; k++) {
095: XmlElement xmlResponse = (XmlElement) questionResponses
096: .elementAt(k);
097: char cr = xmlResponse.getName().charAt(
098: 0);
099: if (cr == 'R')
100: currentQuestion
101: .addOption(
102: new Integer(
103: xmlResponse
104: .getAttribute("id"))
105: .intValue(),
106: xmlResponse
107: .getAttribute("A"));
108: }
109: currentGroup.addQuestion(currentQuestion);
110: }
111: }
112: questionGroups.add(currentGroup);
113: }
114: }
115: }
116: }
117:
118: /**
119: * Get the next question
120: * @return the next question
121: */
122: /*
123: public Question getNextQuestion()
124: {
125: try {
126:
127: return ((QuestionGroup)questionGroups.elementAt( 0 )).getNextQuestion();
128: }
129: catch ( ArrayIndexOutOfBoundsException aiobe ) {
130: return null;
131: }
132: }
133: */
134:
135: public Question getNextQuestion() {
136: return null;
137: }
138:
139: /**
140: * Binding a question interface/representation to the survey
141: * @param binding the survey data
142: */
143: public void bindQuestion(XDataBinding binding) {
144: bindings.addElement(binding);
145: }
146:
147: /**
148: * Reset all questions
149: */
150: public void reset() {
151: XModel csModel = ((XModel) currentProject.getModel().get(
152: "currentSurvey/question"));
153:
154: // Push the bound data onto the model
155: Enumeration enumeration = bindings.elements();
156: while (enumeration.hasMoreElements())
157: ((XDataBinding) enumeration.nextElement()).set();
158:
159: int numAnswers = csModel.getNumChildren();
160: for (int i = 0; i < numAnswers; i++) {
161: XModel node = csModel.get(i);
162: int nv = new Integer(node.getId()).intValue();
163: if (!hasQuestions)
164: responseSet.addQuestion(nv);
165: responseSet.addResponse((String) node.get());
166: node.set("-1");
167: }
168:
169: hasQuestions = true;
170: responseSet.closeSession();
171:
172: // Pull the bound data from the model, they should all now be reset
173: enumeration = bindings.elements();
174: while (enumeration.hasMoreElements())
175: ((XDataBinding) enumeration.nextElement()).get();
176: }
177:
178: /**
179: * Restart the session recording
180: */
181: public void restart() {
182: hasQuestions = false;
183: questionGroups = new Vector();
184: responseSet = new XResponseSet(name);
185: }
186:
187: /**
188: * Gets the current response set
189: * @return the response set
190: */
191: public XResponseSet getResponses() {
192: return responseSet;
193: }
194:
195: /**
196: * Get the total number of questions in this survey
197: * @return the number of questions in all groups
198: */
199: public int getNumQuestions() {
200: int numQuestions = 0;
201: int numGroups = questionGroups.size();
202:
203: for (int i = 0; i < numGroups; i++) {
204: QuestionGroup currentGroup = (QuestionGroup) questionGroups
205: .elementAt(i);
206: numQuestions += currentGroup.getNumQuestions();
207: }
208:
209: return numQuestions;
210: }
211: }
|