/***
* Copyright (c) 2008, Endless Loop Software, Inc.
*
* This file is part of EgoNet.
*
* EgoNet is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* EgoNet is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.egonet.model.question;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.egonet.exceptions.MalformedQuestionException;
import org.egonet.model.QuestionLink;
import org.egonet.model.answer.*;
/*******************************************************************************
* Routines for creating and handling atomic question elements
*
*
*
public enum QuestionType {
QuestionType(String niceName, String title)
{
this.niceName = niceName;
this.title = title;
}
}
*
*
*/
public abstract class Question implements Cloneable {
public static String getNiceName(Class<? extends Question> clazz) {
try {
Question instance = clazz.newInstance();
return instance.getNiceName();
}
catch (Exception ex) {
throw new RuntimeException(ex);
}
}
public static String getTitle(Class<? extends Question> clazz) {
try {
Question instance = clazz.newInstance();
return instance.getNiceName();
}
catch (Exception ex) {
throw new RuntimeException(ex);
}
}
public abstract String getNiceName();
public abstract String getTitle();
public boolean centralMarker = false;
private boolean statable = false;
public boolean followupOnly = false;
public boolean isFollowupOnly() {
return followupOnly;
}
public void setFollowupOnly(boolean followupOnly) {
this.followupOnly = followupOnly;
}
public Long UniqueId = new Long(new Date().getTime());
public String title = "";
public String text = "";
public String citation = "";
public Class<? extends Answer> answerType = TextAnswer.class;
public QuestionLink link = new QuestionLink();
private List<Selection> selections = new ArrayList<Selection>(0);
private Answer answer = Answer.newInstance(TextAnswer.class);
public static final int MAX_CATEGORICAL_CHOICES = 9;
/***************************************************************************
* Creates question
*
* @return question new question
*/
public Question() {
}
/***************************************************************************
* Creates question with string as title
*
* @param s
* question title
* @return question new question
*/
public Question(String s) {
this.title = s;
}
/***************************************************************************
* Returns whether a given selection is adjacent based on the values stored
* in the question. Is used to override value found in an interview file
*
* @param value
* @return true iff that selection is marked as adjacent
*/
public boolean selectionAdjacent(int value) {
boolean rval = false;
if(getSelections() == null || getSelections().size() <= 0)
return false;
for (Selection sel : getSelections()) {
if (value == sel.getValue()) {
rval = sel.isAdjacent();
break;
}
}
return rval;
}
/**
* Does the answer to this question determine whether alters are adjacent?
*/
public boolean determinesAdjacency() {
for(Selection selection : getSelections()) {
if(selection.isAdjacent()) {
return true;
}
}
return false;
}
/***************************************************************************
* Overrides toString method for question, returns title
*
* @return String title of question
*/
public String toString() {
if (title == null) {
return (new String("Untitled"));
} else {
return (title);
}
}
/***************************************************************************
* Implements Clone interface for conducting an interview and cloning the study question. The clone is attached to the interview.
*
* @return Clone of Question
*/
public Object clone() {
Question q;
try {
q = (Question) super.clone();
q.link = (QuestionLink) this.link.clone();
q.followupOnly = this.followupOnly;
/*******************************************************************
* Dangerous to clone answers as multiple answers refer to same
* question Make sure they are assigned explicitly
*/
q.setAnswer(null);
} catch (CloneNotSupportedException ex) {
q = null;
}
return q;
}
public String getString() {
String str = "";
str = "ID : " + UniqueId + ", Qtype="+getClass().getSimpleName()+",Atype="+answerType+", Title : " + title + " text : " + text
+ "\nAnswer : " + getAnswer().getString();
return str;
}
public void setSelections(List<Selection> selections) {
this.selections = selections;
}
public List<Selection> getSelections() {
return selections;
}
public Answer getAnswer() {
return answer;
}
public void setAnswer(Answer answer) {
this.answer = answer;
}
public boolean isStatable() {
return statable;
}
public void setStatable(boolean statable) {
this.statable = statable;
}
public static Question newInstance(String questionType) {
try {
Class<? extends Question> clazz = asSubclass(questionType);
return newInstance(clazz);
}
catch (Exception ex) {
throw new MalformedQuestionException(ex);
}
}
public static Question newInstance(Class<? extends Question> clazz) {
try {
return clazz.newInstance();
}
catch (Exception ex) {
throw new MalformedQuestionException("could not instantiate an instance of class " + clazz.getCanonicalName(),ex);
}
}
/**
* Given a string representation of a question subclass, return the class object. This is mostly used when unserializing textual representations of subclasses.
*
* @param questionType type of question subclass
* @return a class object representing that type
*/
public static Class<? extends Question> asSubclass(String questionType) {
try {
@SuppressWarnings("unchecked")
Class<? extends Question> clazz = (Class<? extends Question>)Class.forName(questionType);
return clazz;
}
catch (Exception ex) {
throw new MalformedQuestionException(ex);
}
}
}