📄 question.java
字号:
//Title: Curriculum Development Tool
//Copyright: Copyright (c) 2001
//Author: David Bradford - dbrad@medstat.med.utah.edu
//Company: Knowledge Weavers - http://medstat.med.utah.edu/kw/
//File: projects/tree/Item.java
//Description: A node in a project tree that contains a web page.
package cdt.projects.tree.nodes;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import cdt.projects.Project;
/**
* This class is for a node in the tree that will be a page in the tree. So it will store the
* text that is edited by the user.
*
* @version 1.1
* @author David Bradford<BR>
* Brad Schaefer (<A HREF="mailto:schaefer@medstat.med.utah.edu">schaefer@medstat.med.utah.edu</A>)
*/
public class Question extends Node {
/** html representing the question in this quiz . */
private String questionText;
/** An ArrayList containing the choices for this question. */
private ArrayList choices;
/** An ArrayList containing the feedback for the choices. */
private ArrayList feedbacks;
/** The text containing any extra text that is after the choices. */
private String extraText;
/** The number of the correct choice. */
private int correctChoice;
/** Whether or not this node has been loaded yet */
private boolean isLoaded;
/**
* Creates a Question.
*
* @param name name of the question node.
*/
public Question(String name) {
setName(name);
this.questionText = new String();
this.choices = new ArrayList();
this.feedbacks = new ArrayList();
this.correctChoice = 0;
this.isLoaded = false;
}
/**
* Generates the html representation of the question node.
*
* @return html representing the question.
*/
public String getData() {
StringBuffer text = new StringBuffer("<html><body>");
if(false == this.isLoaded) {
loadQuestion();
}
text.append(this.questionText);
text.append("\n<form>\n");
Iterator iter = this.choices.iterator();
int count = 0;
while(iter.hasNext()) {
String choice = (String)iter.next();
while(choice.startsWith(" ") && choice.length() > 1) {
choice = choice.substring(1, choice.length());
}
choice = "<input onclick='parent.checkAnswer(" +count+ ")' name='answer' type='radio'>"
+choice.replaceAll("\n|\r", "")+ "\n";
text.append(choice);
++count;
}
text.append("</form>\n\n");
if(null != this.extraText) {
text.append(this.extraText);
}
text.append("</body></html");
return text.toString();
}
/**
* Loads the question from the project's datafile.
*/
public void loadQuestion() {
StringBuffer ret = new StringBuffer();
String filepath = this.getFilePath();
File datFile = Project.currentProject.getDataFile();
if(null != datFile) {
ZipFile zip;
try {
zip = new ZipFile(datFile, ZipFile.OPEN_READ);
ZipEntry entry = zip.getEntry(filepath);
InputStream in;
if(null != entry) {
in = zip.getInputStream(entry);
byte data[] = new byte[1000];
int numBytes;
while( (numBytes = in.read(data)) != -1) {
ret.append(new String(data, 0, numBytes));
}
in.close();
}
zip.close();
} catch(Exception e) {
e.printStackTrace();
// cdt.ErrorD.ErrorDlg.ErrorMsg("Unable to read from '" +filename+ "'");
}
} else {
// cdt.ErrorD.ErrorDlg.ErrorMsg("Unable to find a data file for the current project.");
}
setData(ret.toString().trim());
}
/**
* Parses through the HTML in the parameter and sets up the question object
* accordingly.
*
* @param s new html to have this question set up with.
*/
public void setData(String s) {
this.choices = new ArrayList();
this.feedbacks = new ArrayList();
String lc = s.toLowerCase();
// This text SHOULD be the text containing the choices
TagPosition t = getTextBetweenTags("form", "/form", lc);
String choicesText = s.substring(t.startPos, t.endPos);
// Stores the text before the form.
t = getTextBetweenTags("body", "form", lc);
this.questionText = s.substring(t.startPos, t.endPos);
// Stores the text after the form.
t = getTextBetweenTags("/form", "/body", lc);
this.extraText = s.substring(t.startPos, t.endPos);
// Stores the choices/feedback, separated by 'input' tags
lc = choicesText.toLowerCase();
TagPosition newPos;
TagPosition oldPos = new TagPosition(0, 0);
newPos = getTextBetweenTags("input", "input", lc);
String choice = choicesText.substring(newPos.startPos, newPos.endPos);
int count = 0;
while(!choice.equals("")) {
if(count++ > 1000) { System.out.println("Forced loop break"); break; }
this.choices.add(choice);
this.feedbacks.add("");
oldPos = newPos;
newPos = getTextBetweenTags("input", "input", lc, oldPos.endPos);
choice = choicesText.substring(newPos.startPos, newPos.endPos);
}
this.choices.add(choicesText.substring(choicesText.indexOf(">", oldPos.endPos)+1));
this.feedbacks.add("");
this.isLoaded = true;
}
/**
* Gets the text between opening and closing tags specified by the
* arguments.
*
* @param startTag The tag indicating the beginning of the text in
* the substring being searched for. Usually this should be in the form
* "tag".
* @param endTag The tag indicating the end of the text in the substring
* being searched for. Usually this should be in the form "/tag".
* @param s The text containing the substring being searched for.
* @return The text between the opening and closing tag specified.
* If that text cannot be found, an empty String is returned.
*/
private TagPosition getTextBetweenTags(String startTag, String endTag, String s) {
return getTextBetweenTags(startTag, endTag, s, 0);
}
/**
* Gets the text between opening and closing tags specified by the
* arguments. Note: this function will attempt to find the endTag that
* MATCHES the startTag, so that means if there is a startTag nested
* between the first startTag and the first endTag, it will try to find
* an endTag past the end of the first endTag. If startTag and endTag
* are NOT the same kind of tag, this function may not produce the desired
* results -- use with care in that type of situation.
*
* @param startTag The tag indicating the beginning of the text in
* the substring being searched for. Usually this should be in the form
* "tag".
* @param endTag The tag indicating the end of the text in the substring
* being searched for. Usually this should be in the form "/tag".
* @param s The text in which to find the tags.
* @param start The character to begin searching from.
* @return The start and end positions of the text between the opening and
* closing tag specified. If that text cannot be found, null is returned.
*/
private TagPosition getTextBetweenTags(String startTag, String endTag, String s, int start) {
TagPosition ret = new TagPosition(0, 0);
start = s.indexOf("<" +startTag, start);
if(-1 == start) {
return ret;
}
start = s.indexOf(">", start) + 1;
if(0 == start) {
return ret;
}
int end = s.indexOf(("<" +endTag), start);
if(-1 == end) {
return ret;
}
int foo = s.indexOf("<" + startTag, start);
while(foo > start && foo < end && end != -1) {
end = s.indexOf(("<" +endTag), end+1);
foo = s.indexOf(("<" +startTag), foo+1);
}
if(-1 == end) {
return ret;
}
ret = new TagPosition(start, end);
return ret;
}
/**
* Retrieves the text of the question.
*
* @return The HTML representing the question.
*/
public String getQuestion() {
if(false == this.isLoaded) {
loadQuestion();
}
return this.questionText;
}
/**
* Assigns a value to the question.
*
* @param questionText The new value to be stored as the question.
*/
public void setQuestion(String questionText) {
TagPosition t = getTextBetweenTags("body", "/body", questionText);
String questionFragment = questionText.substring(t.startPos, t.endPos);
if(false == questionFragment.equals("")) {
this.questionText = questionFragment;
} else {
this.questionText = questionText;
}
}
/**
* Gets the multiple choices for this question.
*
* @return Returns an <code>ArrayList</code> of the choices for this
* question.
*/
public ArrayList getChoices() {
if(false == this.isLoaded) {
loadQuestion();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -