package net.sf.egonet.persistence;
import java.util.ArrayList;
import java.util.List;
import net.sf.egonet.model.Expression;
import net.sf.egonet.model.Question;
import net.sf.egonet.model.QuestionOption;
import org.hibernate.Session;
import com.google.common.base.Function;
public class Options {
public static List<QuestionOption> getOptionsForStudy(final Long studyId) {
return DB.withTx(new DB.Action<List<QuestionOption>>() {
public List<QuestionOption> get() {
return getOptionsForStudy(session,studyId);
}
});
}
public static List<QuestionOption>
getOptionsForStudy(Session session, final Long studyId)
{
return session.createQuery("from QuestionOption where active = 1 and " +
" studyId = :studyId")
.setLong("studyId", studyId)
.list();
}
@SuppressWarnings("unchecked")
public static ArrayList<QuestionOption>
getOptionsForQuestion(Session session, final Long questionId)
{
ArrayList<QuestionOption> options = new ArrayList<QuestionOption>(
session.createQuery("from QuestionOption o where o.active = 1 and " +
"o.questionId = :questionId order by o.ordering")
.setLong("questionId", questionId)
.list());
// Add values to those that don't have them (null or "").
for(QuestionOption option : options) {
if(option.getValue() == null || option.getValue().isEmpty()) {
for(Integer possibleValue = options.size()+1; possibleValue > 0; possibleValue--) {
Boolean foundMatch = false;
for(QuestionOption otherOption : options) {
if(otherOption.getValue() != null && otherOption.getValue().equals(possibleValue.toString())) {
foundMatch = true;
}
}
if(! foundMatch) {
option.setValue(possibleValue.toString());
}
}
DB.save(session, option);
}
}
return options;
}
public static ArrayList<QuestionOption> getOptionsForQuestion(final Long questionId) {
return DB.withTx(new DB.Action<ArrayList<QuestionOption>>() {
public ArrayList<QuestionOption> get() {
return getOptionsForQuestion(session,questionId);
}
});
}
@SuppressWarnings("unchecked")
public static void delete(Session session, final QuestionOption option) {
for(QuestionOption dbOption : matchingOptionsFor(session,option)) {
// TODO: Delete single-selection answers to the same question that reference this option
// TODO: Remove references to this option from multiple-selection answers
List<Expression> expressions =
Expressions.getSimpleExpressionsForQuestion(session, dbOption.getQuestionId());
for(Expression expression : expressions) {
if(expression.getType().equals(Expression.Type.Selection)) {
List<Long> optionIds = (List<Long>) expression.getValue();
optionIds.remove(dbOption.getId());
expression.setValue(optionIds);
DB.save(expression);
}
}
DB.delete(dbOption);
}
}
public static void delete(final QuestionOption option) {
DB.withTx(new Function<Session,Object>(){
public Object apply(Session session) {
delete(session,option);
return null;
}
});
}
public static void addOption(final Question question, final String optionName, final String optionValue) {
new DB.Action<Object>() {
public Object get() {
addOption(session, question, optionName, optionValue);
return null;
}
}.execute();
}
public static void addOption(Session session, Question question, String optionName, String optionValue) {
List<QuestionOption> options = getOptionsForQuestion(session,question.getId());
QuestionOption newOption = new QuestionOption(question.getId(),optionName);
if(optionValue == null || optionValue.isEmpty()) {
for(Integer possibleValue = options.size()+1; possibleValue > 0; possibleValue--) {
Boolean foundMatch = false;
for(QuestionOption option : options) {
if(option.getValue() != null && option.getValue().equals(possibleValue.toString())) {
foundMatch = true;
}
}
if(! foundMatch) {
newOption.setValue(possibleValue.toString());
}
}
} else {
newOption.setValue(optionValue);
}
options.add(newOption);
for(Integer i = 0; i < options.size(); i++) {
options.get(i).setOrdering(i);
options.get(i).setStudyId(question.getStudyId());
DB.save(session, options.get(i));
}
}
public static void moveEarlier(Session session, final QuestionOption option) {
List<QuestionOption> options = getOptionsForQuestion(session,option.getQuestionId());
Integer i = null;
for(Integer j = 0; j < options.size(); j++) {
if(options.get(j).getId().equals(option.getId())) {
i = j;
}
}
if(i != null && i > 0) {
QuestionOption swap = options.get(i);
options.set(i, options.get(i-1));
options.set(i-1, swap);
}
Long studyId = null;
for(Integer j = 0; j < options.size(); j++) {
QuestionOption thisOption = options.get(j);
thisOption.setOrdering(j);
if(thisOption.getStudyId() == null) {
if(studyId == null) {
studyId = Questions.getQuestion(session,option.getQuestionId()).getStudyId();
}
thisOption.setStudyId(studyId);
}
DB.save(options.get(j));
}
}
public static void moveEarlier(final QuestionOption option) {
DB.withTx(new Function<Session,Object>() {
public Object apply(Session session) {
moveEarlier(session,option);
return null;
}
});
}
@SuppressWarnings("unchecked")
public static List<QuestionOption> matchingOptionsFor(Session session, final QuestionOption option) {
return
session.createQuery(
"from QuestionOption where id = :id and name = :name and questionId = :questionId and active = 1")
.setParameter("id", option.getId())
.setParameter("name", option.getName())
.setParameter("questionId", option.getQuestionId())
.list();
}
}