Index: lams_common/src/java/org/lamsfoundation/lams/dbupdates/patch20190722.sql =================================================================== diff -u -r4e7112f26061bd5120444ea3eb1517acd1c3b88a -rf49dd9f6b076828f464fc954bb9c3dc0c87e8b37 --- lams_common/src/java/org/lamsfoundation/lams/dbupdates/patch20190722.sql (.../patch20190722.sql) (revision 4e7112f26061bd5120444ea3eb1517acd1c3b88a) +++ lams_common/src/java/org/lamsfoundation/lams/dbupdates/patch20190722.sql (.../patch20190722.sql) (revision f49dd9f6b076828f464fc954bb9c3dc0c87e8b37) @@ -695,13 +695,112 @@ AND activity.learning_design_id = design.learning_design_id; -- cleanup -ALTER TABLE lams_qb_question DROP COLUMN tmp_question_id; ALTER TABLE tl_laasse10_question_result DROP COLUMN assessment_question_uid, - DROP COLUMN submitted_option_uid; - + DROP COLUMN submitted_option_uid; + DROP TABLE tl_laasse10_question_option, - tl_laasse10_assessment_unit, - tmp_question, + tl_laasse10_assessment_unit; + +-- prepare for next tool migration, recreate tables +DROP TABLE tmp_question; +DROP TABLE tmp_question_match; + +CREATE TABLE tmp_question (question_uid BIGINT PRIMARY KEY, + content MEDIUMTEXT); + +CREATE TABLE tmp_question_match (question_uid BIGINT PRIMARY KEY, + target_uid BIGINT); +ALTER TABLE tmp_question_match ADD INDEX (target_uid); + + + +-- QUESTION & ANSWERS (Q&A) + +SET @max_tool_question_id = (SELECT MAX(tool_question_uid) FROM lams_qb_tool_question); +-- remove characters that prevent detecting identical questions +UPDATE tl_laqa11_que_content SET `question` = TRIM(REPLACE(REPLACE(REPLACE(question, '> ', '>' ), '\r', '' ), '\n', '')), + `feedback` = TRIM(REPLACE(REPLACE(REPLACE(feedback, '> ', '>' ), '\r', '' ), '\n', '')), + uid = uid + @max_tool_question_id ORDER BY uid DESC; +UPDATE tl_laqa11_usr_resp SET `answer` = TRIM(REPLACE(REPLACE(REPLACE(answer, '> ', '>' ), '\r', '' ), '\n', '')); + +-- create a mapping of Q&A question UID -> its question text in a single column +-- if this column is not *exactly* as in an other row, it means it should be a separate question in QB +-- Also remove all whitespace just for less demanding matching + +INSERT INTO tmp_question + SELECT q.uid AS question_uid, + REPLACE(REPLACE(REPLACE(strip_tags(question) COLLATE utf8mb4_0900_ai_ci, + ' ', ''), + '\t', ''), + ' ', '') AS content + FROM tl_laqa11_que_content AS q + GROUP BY q.uid; + +-- create a mapping of Q&A question UID -> UID of one of Q&A questions which holds the same content +INSERT INTO tmp_question_match + SELECT q.question_uid, merged.question_uid AS target_uid + FROM (SELECT * FROM tmp_question GROUP BY content) AS merged + JOIN tmp_question AS q USING (content) + GROUP BY q.question_uid; + +-- reset column for matching QB questions with Scratchie questions +UPDATE lams_qb_question SET tmp_question_id = -1; + +INSERT INTO lams_qb_question (uid, `type`, question_id, version, create_date, + name, + description, max_mark, feedback, answer_required, min_words_limit, tmp_question_id) + SELECT NULL, 6, @question_id:=@question_id + 1, 1, IFNULL(c.creation_date, NOW()), + SUBSTRING(TRIM(REPLACE(REPLACE(strip_tags(qa.question) COLLATE utf8mb4_0900_ai_ci, ' ', ' '), '\t', '')), 1, 80), + qa.question, 1, qa.feedback, qa.answer_required, qa.min_words_limit, q.target_uid + FROM (SELECT uid, + question AS question, + IF(TRIM(feedback) = '', NULL, TRIM(feedback)) AS feedback, + answer_required, + min_words_limit, + qa_content_id + FROM tl_laqa11_que_content) AS qa + JOIN (SELECT DISTINCT target_uid FROM tmp_question_match) AS q + ON qa.uid = q.target_uid + JOIN tl_laqa11_content AS c + ON qa.qa_content_id = c.uid; + +-- set up references to QB question UIDs created above +INSERT INTO lams_qb_tool_question + SELECT q.question_uid, qb.uid, c.qa_content_id, qa.display_order + FROM lams_qb_question AS qb + JOIN tmp_question_match AS q + ON qb.tmp_question_id = q.target_uid + JOIN tl_laqa11_que_content AS qa + ON q.question_uid = qa.uid + JOIN tl_laqa11_content AS c + ON qa.qa_content_id = c.uid; + +-- remove columns from Q&A which are duplicated in Question Bank +ALTER TABLE tl_laqa11_que_content DROP COLUMN question, + DROP COLUMN display_order, + DROP COLUMN feedback, + DROP COLUMN answer_required, + DROP COLUMN min_words_limit; + +ALTER TABLE tl_laqa11_usr_resp DROP FOREIGN KEY FK_tl_laqa11_usr_resp_2, + -- to keep consistency with other tools + RENAME COLUMN response_id TO uid; + +-- shift Q&A answer UIDs by offset equal to existing UIDs of Q&A and Assessment answers in lams_qb_tool_answer +SET @max_answer_uid = (SELECT MAX(answer_uid) FROM lams_qb_tool_answer); +UPDATE tl_laqa11_usr_resp SET uid = uid + @max_answer_uid ORDER BY uid DESC; + + +-- prepare for answer inheritance +INSERT INTO lams_qb_tool_answer + SELECT uid, qa_que_content_id, NULL FROM tl_laqa11_usr_resp; + +-- clean up +ALTER TABLE tl_laqa11_usr_resp DROP COLUMN qa_que_content_id; + + +ALTER TABLE lams_qb_question DROP COLUMN tmp_question_id; +DROP TABLE tmp_question, tmp_question_match, tmp_qb_question, tmp_qb_question_match, Index: lams_common/src/java/org/lamsfoundation/lams/qb/model/QbToolAnswer.java =================================================================== diff -u -rb41c8a8bc5134e78088378360a37f3906fadb3de -rf49dd9f6b076828f464fc954bb9c3dc0c87e8b37 --- lams_common/src/java/org/lamsfoundation/lams/qb/model/QbToolAnswer.java (.../QbToolAnswer.java) (revision b41c8a8bc5134e78088378360a37f3906fadb3de) +++ lams_common/src/java/org/lamsfoundation/lams/qb/model/QbToolAnswer.java (.../QbToolAnswer.java) (revision f49dd9f6b076828f464fc954bb9c3dc0c87e8b37) @@ -1,55 +1,76 @@ -package org.lamsfoundation.lams.qb.model; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Inheritance; -import javax.persistence.InheritanceType; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; - -/** - * - * @author Marcin Cieslak - */ -@Entity -@Table(name = "lams_qb_tool_answer") -@Inheritance(strategy = InheritanceType.JOINED) -public abstract class QbToolAnswer { - @Id - @Column(name = "answer_uid") - @GeneratedValue(strategy = GenerationType.IDENTITY) - protected Long uid; - - @ManyToOne(optional = false, fetch = FetchType.LAZY) - @JoinColumn(name = "tool_question_uid") - protected QbToolQuestion qbToolQuestion; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "qb_option_uid") - protected QbOption qbOption; - - public QbToolQuestion getQbToolQuestion() { - return qbToolQuestion; - } - - public void setQbToolQuestion(QbToolQuestion qbToolQuestion) { - this.qbToolQuestion = qbToolQuestion; - } - - public QbOption getQbOption() { - return qbOption; - } - - public void setQbOption(QbOption qbOption) { - this.qbOption = qbOption; - } - - public Long getUid() { - return this.uid; - } -} +package org.lamsfoundation.lams.qb.model; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +/** + * + * @author Marcin Cieslak + */ +@Entity +@Table(name = "lams_qb_tool_answer") +@Inheritance(strategy = InheritanceType.JOINED) +public abstract class QbToolAnswer { + @Id + @Column(name = "answer_uid") + @GeneratedValue(strategy = GenerationType.IDENTITY) + protected Long uid; + + @ManyToOne(optional = false, fetch = FetchType.LAZY) + @JoinColumn(name = "tool_question_uid") + protected QbToolQuestion qbToolQuestion; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "qb_option_uid") + protected QbOption qbOption; + + public QbToolQuestion getQbToolQuestion() { + return qbToolQuestion; + } + + public void setQbToolQuestion(QbToolQuestion qbToolQuestion) { + this.qbToolQuestion = qbToolQuestion; + } + + public QbOption getQbOption() { + return qbOption; + } + + public void setQbOption(QbOption qbOption) { + this.qbOption = qbOption; + } + + public Long getUid() { + return this.uid; + } + + @Override + public int hashCode() { + return new HashCodeBuilder().append(getUid()).toHashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof QbToolAnswer)) { + return false; + } + + QbToolAnswer other = (QbToolAnswer) obj; + return new EqualsBuilder().append(this.getUid(), other.getUid()).isEquals(); + } +} Index: lams_common/src/java/org/lamsfoundation/lams/qb/model/QbToolQuestion.java =================================================================== diff -u -r114a48edf9af0975b8d67d3240ae2de2a773de46 -rf49dd9f6b076828f464fc954bb9c3dc0c87e8b37 --- lams_common/src/java/org/lamsfoundation/lams/qb/model/QbToolQuestion.java (.../QbToolQuestion.java) (revision 114a48edf9af0975b8d67d3240ae2de2a773de46) +++ lams_common/src/java/org/lamsfoundation/lams/qb/model/QbToolQuestion.java (.../QbToolQuestion.java) (revision f49dd9f6b076828f464fc954bb9c3dc0c87e8b37) @@ -15,6 +15,9 @@ import javax.persistence.ManyToOne; import javax.persistence.Table; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + /** * * Serves as a super class for all tools' questions. @@ -86,4 +89,19 @@ public void setDisplayOrder(int displayOrder) { this.displayOrder = displayOrder; } + + @Override + public boolean equals(Object other) { + if (!(other instanceof QbToolQuestion)) { + return false; + } + QbToolQuestion castOther = (QbToolQuestion) other; + return new EqualsBuilder().append(this.getUid(), castOther.getUid()).isEquals(); + } + + @Override + public int hashCode() { + return new HashCodeBuilder().append(getUid()).toHashCode(); + } + } \ No newline at end of file Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentQuestionResult.java =================================================================== diff -u -rb41c8a8bc5134e78088378360a37f3906fadb3de -rf49dd9f6b076828f464fc954bb9c3dc0c87e8b37 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentQuestionResult.java (.../AssessmentQuestionResult.java) (revision b41c8a8bc5134e78088378360a37f3906fadb3de) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentQuestionResult.java (.../AssessmentQuestionResult.java) (revision f49dd9f6b076828f464fc954bb9c3dc0c87e8b37) @@ -97,24 +97,6 @@ @Transient private QuestionDTO questionDto; - @Override - public int hashCode() { - return new HashCodeBuilder().append(getUid()).toHashCode(); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof AssessmentQuestionResult)) { - return false; - } - - final AssessmentQuestionResult genericEntity = (AssessmentQuestionResult) obj; - return new EqualsBuilder().append(this.getUid(), genericEntity.getUid()).isEquals(); - } - public QbQuestion getQbQuestion() { return qbToolQuestion.getQbQuestion(); } Index: lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/model/McUsrAttempt.java =================================================================== diff -u -r5893f827ac7db4160980f332015d28b47f9ecc6d -rf49dd9f6b076828f464fc954bb9c3dc0c87e8b37 --- lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/model/McUsrAttempt.java (.../McUsrAttempt.java) (revision 5893f827ac7db4160980f332015d28b47f9ecc6d) +++ lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/model/McUsrAttempt.java (.../McUsrAttempt.java) (revision f49dd9f6b076828f464fc954bb9c3dc0c87e8b37) @@ -91,36 +91,6 @@ public McUsrAttempt() { } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((uid == null) ? 0 : uid.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - McUsrAttempt other = (McUsrAttempt) obj; - if (uid == null) { - if (other.uid != null) { - return false; - } - } else if (!uid.equals(other.uid)) { - return false; - } - return true; - } - public Date getAttemptTime() { return this.attemptTime; } @@ -137,7 +107,7 @@ this.qbToolQuestion = mcQueContent; } - public org.lamsfoundation.lams.tool.mc.model.McQueUsr getMcQueUsr() { + public McQueUsr getMcQueUsr() { return this.mcQueUsr; } Index: lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/dao/IQaQuestionDAO.java =================================================================== diff -u -r69092337b728f903f824a74377bd0ebf9391120c -rf49dd9f6b076828f464fc954bb9c3dc0c87e8b37 --- lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/dao/IQaQuestionDAO.java (.../IQaQuestionDAO.java) (revision 69092337b728f903f824a74377bd0ebf9391120c) +++ lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/dao/IQaQuestionDAO.java (.../IQaQuestionDAO.java) (revision f49dd9f6b076828f464fc954bb9c3dc0c87e8b37) @@ -25,16 +25,17 @@ import java.util.List; +import org.lamsfoundation.lams.dao.IBaseDAO; import org.lamsfoundation.lams.tool.qa.model.QaQueContent; /** * @author Ozgur Demirtas */ -public interface IQaQuestionDAO { +public interface IQaQuestionDAO extends IBaseDAO { void createQueContent(QaQueContent queContent); - void saveOrUpdateQaQueContent(QaQueContent qaQuestion); + void saveOrUpdate(Object object); void removeQueContent(long qaQueContentId); @@ -47,4 +48,4 @@ QaQueContent getQuestionByUid(Long questionUid); List getAllQuestionEntriesSorted(final long qaContentId); -} +} \ No newline at end of file Index: lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/dao/hibernate/QaQuestionDAO.java =================================================================== diff -u -r69092337b728f903f824a74377bd0ebf9391120c -rf49dd9f6b076828f464fc954bb9c3dc0c87e8b37 --- lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/dao/hibernate/QaQuestionDAO.java (.../QaQuestionDAO.java) (revision 69092337b728f903f824a74377bd0ebf9391120c) +++ lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/dao/hibernate/QaQuestionDAO.java (.../QaQuestionDAO.java) (revision f49dd9f6b076828f464fc954bb9c3dc0c87e8b37) @@ -21,7 +21,6 @@ * **************************************************************** */ - package org.lamsfoundation.lams.tool.qa.dao.hibernate; import java.util.List; @@ -46,8 +45,8 @@ @Override public QaQueContent getQuestionByDisplayOrder(Integer displayOrder, Long contentUid) { List list = getSessionFactory().getCurrentSession() - .createQuery(QaQuestionDAO.LOAD_QUESTION_BY_DISPLAY_ORDER) - .setParameter("displayOrder", displayOrder).setParameter("uid", contentUid).list(); + .createQuery(QaQuestionDAO.LOAD_QUESTION_BY_DISPLAY_ORDER).setParameter("displayOrder", displayOrder) + .setParameter("uid", contentUid).list(); if (list != null && list.size() > 0) { QaQueContent qa = list.get(0); @@ -82,8 +81,8 @@ @SuppressWarnings("unchecked") @Override public List getAllQuestionEntries(final long contentUid) { - List list = getSessionFactory().getCurrentSession().createQuery(QaQuestionDAO.LOAD_QUESTION_BY_CONTENT_UID) - .setParameter("uid", contentUid).list(); + List list = getSessionFactory().getCurrentSession() + .createQuery(QaQuestionDAO.LOAD_QUESTION_BY_CONTENT_UID).setParameter("uid", contentUid).list(); return list; } @@ -94,13 +93,13 @@ } @Override - public void saveOrUpdateQaQueContent(QaQueContent qaQuestion) { - getSession().saveOrUpdate(qaQuestion); + public void saveOrUpdate(Object object) { + getSession().saveOrUpdate(object); } @Override public void removeQueContent(long qaQueContentId) { - QaQueContent qaQuestion = (QaQueContent) getSession().load(QaQueContent.class, new Long(qaQueContentId)); + QaQueContent qaQuestion = getSession().load(QaQueContent.class, new Long(qaQueContentId)); getSession().delete(qaQuestion); } Index: lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/dto/QaConditionDTO.java =================================================================== diff -u -r69092337b728f903f824a74377bd0ebf9391120c -rf49dd9f6b076828f464fc954bb9c3dc0c87e8b37 --- lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/dto/QaConditionDTO.java (.../QaConditionDTO.java) (revision 69092337b728f903f824a74377bd0ebf9391120c) +++ lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/dto/QaConditionDTO.java (.../QaConditionDTO.java) (revision f49dd9f6b076828f464fc954bb9c3dc0c87e8b37) @@ -20,7 +20,6 @@ * **************************************************************** */ - package org.lamsfoundation.lams.tool.qa.dto; import java.util.Set; @@ -32,13 +31,12 @@ import org.lamsfoundation.lams.tool.qa.util.QaQueContentComparator; public class QaConditionDTO extends TextSearchConditionDTO { - private Set questions = new TreeSet(new QaQueContentComparator()); + private Set questions = new TreeSet<>(new QaQueContentComparator()); public QaConditionDTO(QaCondition condition, Integer toolActivityUIID) { super(condition, toolActivityUIID); for (QaQueContent question : condition.getQuestions()) { - QaQueContent questionCopy = new QaQueContent(question.getQuestion(), question.getDisplayOrder(), null, - question.isRequired(), question.getMinWordsLimit(), null); + QaQueContent questionCopy = new QaQueContent(question.getQbQuestion(), question.getDisplayOrder(), null); getQuestions().add(questionCopy); } } Index: lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/dto/QaQuestionDTO.java =================================================================== diff -u -r69092337b728f903f824a74377bd0ebf9391120c -rf49dd9f6b076828f464fc954bb9c3dc0c87e8b37 --- lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/dto/QaQuestionDTO.java (.../QaQuestionDTO.java) (revision 69092337b728f903f824a74377bd0ebf9391120c) +++ lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/dto/QaQuestionDTO.java (.../QaQuestionDTO.java) (revision f49dd9f6b076828f464fc954bb9c3dc0c87e8b37) @@ -30,7 +30,7 @@ * * @author Ozgur Demirtas */ -public class QaQuestionDTO implements Comparable { +public class QaQuestionDTO implements Comparable { private Long uid; private String question; private String displayOrder; @@ -39,11 +39,11 @@ private int minWordsLimit; public QaQuestionDTO(QaQueContent que) { - this.question = que.getQuestion(); - this.displayOrder = new Integer(que.getDisplayOrder()).toString(); - this.feedback = que.getFeedback() != null ? que.getFeedback() : ""; - this.required = que.isRequired(); - this.minWordsLimit = que.getMinWordsLimit(); + this.question = que.getQbQuestion().getName(); + this.displayOrder = String.valueOf(que.getDisplayOrder()); + this.feedback = que.getQbQuestion().getFeedback() != null ? que.getQbQuestion().getFeedback() : ""; + this.required = que.getQbQuestion().isAnswerRequired(); + this.minWordsLimit = que.getQbQuestion().getMinWordsLimit(); this.uid = que.getUid(); } @@ -56,10 +56,8 @@ } @Override - public int compareTo(Object o) { - QaMonitoredUserDTO qaMonitoredUserDTO = (QaMonitoredUserDTO) o; - - if (qaMonitoredUserDTO == null) { + public int compareTo(QaMonitoredUserDTO o) { + if (o == null) { return 1; } else { return 0; @@ -167,6 +165,6 @@ @Override public int hashCode() { - return new Integer(getDisplayOrder()); + return Integer.valueOf(displayOrder); } } Index: lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/model/QaCondition.java =================================================================== diff -u -r69092337b728f903f824a74377bd0ebf9391120c -rf49dd9f6b076828f464fc954bb9c3dc0c87e8b37 --- lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/model/QaCondition.java (.../QaCondition.java) (revision 69092337b728f903f824a74377bd0ebf9391120c) +++ lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/model/QaCondition.java (.../QaCondition.java) (revision f49dd9f6b076828f464fc954bb9c3dc0c87e8b37) @@ -20,7 +20,6 @@ * **************************************************************** */ - package org.lamsfoundation.lams.tool.qa.model; import java.util.Set; @@ -68,21 +67,20 @@ @Cascade({ CascadeType.SAVE_UPDATE }) @JoinTable(name = "tl_laqa11_condition_questions", joinColumns = @JoinColumn(name = "condition_id"), inverseJoinColumns = @JoinColumn(name = "question_uid")) @OrderBy("uid ASC") - private Set questions = new TreeSet(new QaQueContentComparator()); + private Set questions = new TreeSet<>(new QaQueContentComparator()); @Transient public SortedSet temporaryQuestionDTOSet; public QaCondition() { - this.temporaryQuestionDTOSet = new TreeSet(new QaQuestionContentDTOComparator()); + this.temporaryQuestionDTOSet = new TreeSet<>(new QaQuestionContentDTOComparator()); } public QaCondition(QaConditionDTO conditionDTO) { super(conditionDTO); - this.temporaryQuestionDTOSet = new TreeSet(new QaQuestionContentDTOComparator()); + this.temporaryQuestionDTOSet = new TreeSet<>(new QaQuestionContentDTOComparator()); for (QaQueContent question : conditionDTO.getQuestions()) { - QaQueContent questionCopy = new QaQueContent(question.getQuestion(), question.getDisplayOrder(), null, - question.isRequired(), question.getMinWordsLimit(), null); + QaQueContent questionCopy = new QaQueContent(question.getQbQuestion(), question.getDisplayOrder(), null); getQuestions().add(questionCopy); } } @@ -91,7 +89,7 @@ String allWords, String phrase, String anyWords, String excludedWords, Set questions) { super(conditionId, conditionUIID, orderId, name, displayName, BranchCondition.OUTPUT_TYPE_COMPLEX, null, null, null, allWords, phrase, anyWords, excludedWords); - this.temporaryQuestionDTOSet = new TreeSet(new QaQuestionContentDTOComparator()); + this.temporaryQuestionDTOSet = new TreeSet<>(new QaQuestionContentDTOComparator()); setQuestions(questions); } @@ -135,7 +133,7 @@ */ @Override public Object clone() { - Set questionsCopy = new TreeSet(new QaQueContentComparator()); + Set questionsCopy = new TreeSet<>(new QaQueContentComparator()); questionsCopy.addAll(questions); return new QaCondition(null, null, orderId, name, displayName, allWords, phrase, anyWords, excludedWords, questionsCopy); @@ -150,11 +148,10 @@ @Override public QaCondition clone(int uiidOffset) { Integer newConditionUIID = LearningDesign.addOffset(conditionUIID, uiidOffset); - Set questionsCopy = new TreeSet(new QaQueContentComparator()); + Set questionsCopy = new TreeSet<>(new QaQueContentComparator()); for (QaQueContent question : getQuestions()) { - QaQueContent questionCopy = new QaQueContent(question.getQuestion(), question.getDisplayOrder(), null, - question.isRequired(), question.getMinWordsLimit(), null); + QaQueContent questionCopy = new QaQueContent(question.getQbQuestion(), question.getDisplayOrder(), null); questionsCopy.add(questionCopy); } return new QaCondition(null, newConditionUIID, orderId, name, displayName, allWords, phrase, anyWords, @@ -168,7 +165,7 @@ */ public QaCondition clone(QaContent qaContent) { - Set questionsCopy = new TreeSet(new QaQueContentComparator()); + Set questionsCopy = new TreeSet<>(new QaQueContentComparator()); for (QaQueContent conditionQuestion : getQuestions()) { for (QaQueContent contentQuestion : qaContent.getQaQueContents()) { if (conditionQuestion.getDisplayOrder() == contentQuestion.getDisplayOrder()) { Index: lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/model/QaQueContent.java =================================================================== diff -u -r1ee503e3d0e0228ea8a45025fddf15d9623c0377 -rf49dd9f6b076828f464fc954bb9c3dc0c87e8b37 --- lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/model/QaQueContent.java (.../QaQueContent.java) (revision 1ee503e3d0e0228ea8a45025fddf15d9623c0377) +++ lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/model/QaQueContent.java (.../QaQueContent.java) (revision f49dd9f6b076828f464fc954bb9c3dc0c87e8b37) @@ -25,20 +25,16 @@ import java.io.Serializable; -import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; +import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.Table; -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.commons.lang.builder.ToStringBuilder; -import org.lamsfoundation.lams.tool.qa.Nullable; +import org.lamsfoundation.lams.qb.model.QbQuestion; +import org.lamsfoundation.lams.qb.model.QbToolQuestion; /** * @@ -51,192 +47,43 @@ */ @Entity @Table(name = "tl_laqa11_que_content") -public class QaQueContent implements Serializable, Comparable, Nullable { +//in this entity's table primary key is "uid", but it references "tool_question_uid" in lams_qb_tool_question +@PrimaryKeyJoinColumn(name = "uid") +public class QaQueContent extends QbToolQuestion implements Serializable { private static final long serialVersionUID = -4028785701106936621L; - @Id - @Column - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long uid; - - @Column - private String question; - - @Column(name = "display_order") - private int displayOrder; - - @Column - private String feedback; - - @Column(name = "answer_required") - private boolean required; - - @Column(name = "min_words_limit") - private int minWordsLimit; - @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "qa_content_id") private QaContent qaContent; - /** default constructor */ public QaQueContent() { } - public QaQueContent(String question, int displayOrder, String feedback, boolean required, int minWordsLimit, - QaContent qaContent) { - this.question = question; - this.displayOrder = displayOrder; - this.feedback = feedback; - this.required = required; - this.minWordsLimit = minWordsLimit; + public QaQueContent(QbQuestion qbQuestion, int displayOrder, QaContent qaContent) { + this.qbQuestion = qbQuestion; this.qaContent = qaContent; + this.displayOrder = displayOrder; } public static QaQueContent newInstance(QaQueContent queContent, QaContent newQaContent) { - QaQueContent newQueContent = new QaQueContent(queContent.getQuestion(), queContent.getDisplayOrder(), - queContent.getFeedback(), queContent.isRequired(), queContent.minWordsLimit, newQaContent); + QaQueContent newQueContent = new QaQueContent(queContent.getQbQuestion(), queContent.getDisplayOrder(), + newQaContent); return newQueContent; } @Override public String toString() { - return new ToStringBuilder(this).append("qaQueContentId: ", getUid()).append("question: ", getQuestion()) + return new ToStringBuilder(this).append("uid: ", getUid()).append("name: ", getQbQuestion().getName()) .append("displayOrder: ", getDisplayOrder()).toString(); } - @Override - public boolean equals(Object other) { - if (!(other instanceof QaQueContent)) { - return false; - } - QaQueContent castOther = (QaQueContent) other; - return new EqualsBuilder().append(this.getUid(), castOther.getUid()).isEquals(); - } - - @Override - public int hashCode() { - return new HashCodeBuilder().append(getUid()).toHashCode(); - } - - /** - * @return Returns the displayOrder. - */ - public int getDisplayOrder() { - return displayOrder; - } - - /** - * @param required - * Does this question have to be answered. - */ - public void setRequired(boolean required) { - this.required = required; - } - - /** - * @return Does this question have to be answered. - */ - public boolean isRequired() { - return required; - } - - /** - * @param minWordsLimit - * minWordsLimit - */ - public void setMinWordsLimit(int minWordsLimit) { - this.minWordsLimit = minWordsLimit; - } - - /** - * @return minWordsLimit - */ - public int getMinWordsLimit() { - return minWordsLimit; - } - - /** - * @param displayOrder - * The displayOrder to set. - */ - public void setDisplayOrder(int displayOrder) { - this.displayOrder = displayOrder; - } - - /** - * @return Returns the qaContent. - */ - public org.lamsfoundation.lams.tool.qa.model.QaContent getQaContent() { + public QaContent getQaContent() { return qaContent; } - /** - * @param qaContent - * The qaContent to set. - */ - public void setQaContent(org.lamsfoundation.lams.tool.qa.model.QaContent qaContent) { + public void setQaContent(QaContent qaContent) { this.qaContent = qaContent; + this.toolContentId = qaContent.getQaContentId(); } - - /** - * @return Returns the question. - */ - public String getQuestion() { - return question; - } - - /** - * @param question - * The question to set. - */ - public void setQuestion(String question) { - this.question = question; - } - - @Override - public boolean isNull() { - return false; - } - - @Override - public int compareTo(Object o) { - //QaQueContent queContent = (QaQueContent) o; - - // if the object does not exist yet, then just return any one of 0, -1, 1. Should not make a difference. - /* - * if (uid == null) return 1; else return (int) (uid.longValue() - queContent.uid.longValue()); - */ - return 1; - } - - /** - * @return Returns the uid. - */ - public Long getUid() { - return uid; - } - - /** - * @param uid - * The uid to set. - */ - public void setUid(Long uid) { - this.uid = uid; - } - - /** - * @return Returns the feedback. - */ - public String getFeedback() { - return feedback; - } - - /** - * @param feedback - * The feedback to set. - */ - public void setFeedback(String feedback) { - this.feedback = feedback; - } -} +} \ No newline at end of file Index: lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/model/QaUsrResp.java =================================================================== diff -u -r1ee503e3d0e0228ea8a45025fddf15d9623c0377 -rf49dd9f6b076828f464fc954bb9c3dc0c87e8b37 --- lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/model/QaUsrResp.java (.../QaUsrResp.java) (revision 1ee503e3d0e0228ea8a45025fddf15d9623c0377) +++ lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/model/QaUsrResp.java (.../QaUsrResp.java) (revision f49dd9f6b076828f464fc954bb9c3dc0c87e8b37) @@ -29,17 +29,15 @@ import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; +import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.Table; import javax.persistence.Transient; -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.commons.lang.builder.ToStringBuilder; +import org.hibernate.Hibernate; +import org.lamsfoundation.lams.qb.model.QbToolAnswer; import org.lamsfoundation.lams.rating.dto.ItemRatingDTO; /** @@ -54,12 +52,11 @@ @Entity @Table(name = "tl_laqa11_usr_resp") -public class QaUsrResp implements Serializable, Comparable { +//in this entity's table primary key is "uid", but it references "answer_uid" in lams_qb_tool_answer +@PrimaryKeyJoinColumn(name = "uid") +public class QaUsrResp extends QbToolAnswer implements Serializable { - @Id - @Column(name = "response_id") - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long responseId; + private static final long serialVersionUID = 3446870699674533029L; @Column private String answer; @@ -70,10 +67,6 @@ @Column(name = "attempt_time") private Date attemptTime; - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "qa_que_content_id") - private QaQueContent qaQuestion; - @Column private boolean visible; @@ -91,195 +84,85 @@ private Long portraitId; /** full constructor */ - public QaUsrResp(Long responseId, String answer, String answerAutosaved, Date attemptTime, String timezone, + public QaUsrResp(Long uid, String answer, String answerAutosaved, Date attemptTime, String timezone, QaQueContent qaQuestion, QaQueUsr qaQueUser) { - this.responseId = responseId; + this.uid = uid; this.answer = answer; this.answerAutosaved = answerAutosaved; this.attemptTime = attemptTime; this.timezone = timezone; - this.qaQuestion = qaQuestion; + this.qbToolQuestion = qaQuestion; this.qaQueUser = qaQueUser; } public QaUsrResp(String answer, String answerAutosaved, Date attemptTime, String timezone, QaQueContent qaQuestion, QaQueUsr qaQueUser, boolean visible) { - this.answer = answer; - this.answerAutosaved = answerAutosaved; - this.attemptTime = attemptTime; - this.timezone = timezone; - this.qaQuestion = qaQuestion; - this.qaQueUser = qaQueUser; + this(null, answer, answerAutosaved, attemptTime, timezone, qaQuestion, qaQueUser); this.visible = visible; } /** default constructor */ public QaUsrResp() { } - /** - * Copy construtor. Delegate to full construtor to achieve the object - * creation. - * - * @param response - * the original survey user response - * @return the new qa user response cloned from original object - */ - public static QaUsrResp newInstance(QaUsrResp response) { - return new QaUsrResp(response.getResponseId(), response.getAnswer(), response.getAnswerAutosaved(), - response.getAttemptTime(), response.getTimezone(), response.getQaQuestion(), response.qaQueUser); - } - @Override public String toString() { - return new ToStringBuilder(this).append("responseId: ", getResponseId()).append("answer:", getAnswer()) + return new ToStringBuilder(this).append("uid: ", getUid()).append("answer:", getAnswer()) .append("attempt time: ", getAttemptTime()).toString(); } - @Override - public boolean equals(Object other) { - if (!(other instanceof QaUsrResp)) { - return false; - } - QaUsrResp castOther = (QaUsrResp) other; - return new EqualsBuilder().append(this.getResponseId(), castOther.getResponseId()).isEquals(); - } - - @Override - public int hashCode() { - return new HashCodeBuilder().append(getResponseId()).toHashCode(); - } - - /** - * @return Returns the answer. - */ public String getAnswer() { return answer; } - /** - * @param answer - * The answer to set. - */ public void setAnswer(String answer) { this.answer = answer; } - /** - * @return Returns the answerAutosaved. - */ public String getAnswerAutosaved() { return answerAutosaved; } - /** - * @param answerAutosaved - * The answerAutosaved to set. - */ public void setAnswerAutosaved(String answerAutosaved) { this.answerAutosaved = answerAutosaved; } - /** - * @return Returns the attemptTime. - */ public Date getAttemptTime() { return attemptTime; } - /** - * @param attemptTime - * The attemptTime to set. - */ public void setAttemptTime(Date attemptTime) { this.attemptTime = attemptTime; } - /** - * @return Returns the qaQuestion. - */ public QaQueContent getQaQuestion() { - return qaQuestion; + return (QaQueContent) Hibernate.unproxy(qbToolQuestion); } - /** - * @param qaQuestion - * The qaQuestion to set. - */ public void setQaQuestion(QaQueContent qaQuestion) { - this.qaQuestion = qaQuestion; + this.qbToolQuestion = qaQuestion; } - /** - * @return Returns the qaQueUsr. - */ public QaQueUsr getQaQueUser() { return qaQueUser; } - /** - * @param qaQueUsr - * The qaQueUsr to set. - */ public void setQaQueUser(QaQueUsr qaQueUser) { this.qaQueUser = qaQueUser; } - /** - * @return Returns the responseId. - */ - public Long getResponseId() { - return responseId; - } - - /** - * @param responseId - * The responseId to set. - */ - public void setResponseId(Long responseId) { - this.responseId = responseId; - } - - @Override - public int compareTo(Object o) { - QaUsrResp response = (QaUsrResp) o; - - if (responseId == null) { - return -1; - } - if (response.responseId == null) { - return 1; - } - - return (int) (responseId.longValue() - response.responseId.longValue()); - } - - /** - * @return Returns the timezone. - */ public String getTimezone() { return timezone; } - /** - * @param timezone - * The timezone to set. - */ public void setTimezone(String timezone) { this.timezone = timezone; } - /** - * @return Returns the visible. - */ public boolean isVisible() { return visible; } - /** - * @param visible - * The visible to set. - */ public void setVisible(boolean visible) { this.visible = visible; } @@ -299,5 +182,4 @@ public void setPortraitId(Long portraitId) { this.portraitId = portraitId; } - -} +} \ No newline at end of file Index: lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/qaApplicationContext.xml =================================================================== diff -u -r8384e056e833d8aadcd6cb12a219094f89c67042 -rf49dd9f6b076828f464fc954bb9c3dc0c87e8b37 --- lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/qaApplicationContext.xml (.../qaApplicationContext.xml) (revision 8384e056e833d8aadcd6cb12a219094f89c67042) +++ lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/qaApplicationContext.xml (.../qaApplicationContext.xml) (revision f49dd9f6b076828f464fc954bb9c3dc0c87e8b37) @@ -80,6 +80,7 @@ + Index: lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/service/IQaService.java =================================================================== diff -u -r3bb7e0141ae1cc15ccd737c95d90b5762a34ad61 -rf49dd9f6b076828f464fc954bb9c3dc0c87e8b37 --- lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/service/IQaService.java (.../IQaService.java) (revision 3bb7e0141ae1cc15ccd737c95d90b5762a34ad61) +++ lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/service/IQaService.java (.../IQaService.java) (revision f49dd9f6b076828f464fc954bb9c3dc0c87e8b37) @@ -138,7 +138,7 @@ List getAllQuestionEntriesSorted(final long qaContentId); - void saveOrUpdateQuestion(QaQueContent qaQuestion); + void saveOrUpdate(Object entity); /** * Return the qa session object according to the requested session id. Index: lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/service/QaOutputFactory.java =================================================================== diff -u -r69092337b728f903f824a74377bd0ebf9391120c -rf49dd9f6b076828f464fc954bb9c3dc0c87e8b37 --- lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/service/QaOutputFactory.java (.../QaOutputFactory.java) (revision 69092337b728f903f824a74377bd0ebf9391120c) +++ lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/service/QaOutputFactory.java (.../QaOutputFactory.java) (revision f49dd9f6b076828f464fc954bb9c3dc0c87e8b37) @@ -23,7 +23,6 @@ package org.lamsfoundation.lams.tool.qa.service; import java.util.ArrayList; -import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -60,7 +59,7 @@ @Override public SortedMap getToolOutputDefinitions(Object toolContentObject, int definitionType) throws ToolException { - SortedMap definitionMap = new TreeMap(); + SortedMap definitionMap = new TreeMap<>(); if (toolContentObject != null) { QaContent qaContent = (QaContent) toolContentObject; // Different definitions are provided, depending how the output will be used @@ -99,9 +98,9 @@ public SortedMap getToolOutput(List names, IQaService qaService, Long toolSessionId, Long learnerId) { // result - TreeMap outputs = new TreeMap(); + TreeMap outputs = new TreeMap<>(); // tool output cache - TreeMap baseOutputs = new TreeMap(); + TreeMap baseOutputs = new TreeMap<>(); if (names == null) { // output will be set for all the existing conditions @@ -166,10 +165,10 @@ String[] dummyStringArray = new String[] {}; // answers sorted by time of adding, so "usersAndAnswers" has the newest answers at the beginning - Map timeAndAnswers = new TreeMap(); + Map timeAndAnswers = new TreeMap<>(); for (QaQueUsr user : users) { if (user != null) { - List answers = new LinkedList(); + List answers = new LinkedList<>(); long lastAttemptTime = Long.MAX_VALUE; for (QaQueContent question : questions) { @@ -229,7 +228,7 @@ String[] questionArray = new String[questions.size()]; int questionIndex = 0; for (QaQueContent question : questions) { - questionArray[questionIndex++] = question.getQuestion(); + questionArray[questionIndex++] = question.getQbQuestion().getName(); } return new ToolOutput(name, getI18NText(QaAppConstants.QUESTIONS_DEFINITION_NAME, true), questionArray, false); Index: lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/service/QaService.java =================================================================== diff -u -r3bb7e0141ae1cc15ccd737c95d90b5762a34ad61 -rf49dd9f6b076828f464fc954bb9c3dc0c87e8b37 --- lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/service/QaService.java (.../QaService.java) (revision 3bb7e0141ae1cc15ccd737c95d90b5762a34ad61) +++ lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/service/QaService.java (.../QaService.java) (revision f49dd9f6b076828f464fc954bb9c3dc0c87e8b37) @@ -47,6 +47,8 @@ import org.lamsfoundation.lams.notebook.model.NotebookEntry; import org.lamsfoundation.lams.notebook.service.CoreNotebookConstants; import org.lamsfoundation.lams.notebook.service.ICoreNotebookService; +import org.lamsfoundation.lams.qb.model.QbQuestion; +import org.lamsfoundation.lams.qb.service.IQbService; import org.lamsfoundation.lams.rating.dto.ItemRatingDTO; import org.lamsfoundation.lams.rating.model.LearnerItemRatingCriteria; import org.lamsfoundation.lams.rating.model.RatingCriteria; @@ -114,6 +116,7 @@ private ICoreNotebookService coreNotebookService; private IRatingService ratingService; private IEventNotificationService eventNotificationService; + private IQbService qbService; private MessageService messageService; private Random generator = new Random(); @@ -169,7 +172,7 @@ return; } - for (QaUsrResp leaderResponse : (Set) leader.getQaUsrResps()) { + for (QaUsrResp leaderResponse : leader.getQaUsrResps()) { QaQueContent question = leaderResponse.getQaQuestion(); QaUsrResp response = qaUsrRespDAO.getResponseByUserAndQuestion(user.getQueUsrId(), question.getUid()); @@ -235,8 +238,8 @@ } @Override - public void saveOrUpdateQuestion(QaQueContent question) { - qaQuestionDAO.saveOrUpdateQaQueContent(question); + public void saveOrUpdate(Object entity) { + qaQuestionDAO.saveOrUpdate(entity); } @Override @@ -434,13 +437,13 @@ List questionDTOs, List deletedQuestions) { // create list of modified questions - List modifiedQuestions = new ArrayList(); + List modifiedQuestions = new ArrayList<>(); for (QaQueContent oldQuestion : oldQuestions) { for (QaQuestionDTO questionDTO : questionDTOs) { if (oldQuestion.getUid().equals(questionDTO.getUid())) { // question is different - if (!oldQuestion.getQuestion().equals(questionDTO.getQuestion())) { + if (!oldQuestion.getQbQuestion().getName().equals(questionDTO.getQuestion())) { modifiedQuestions.add(questionDTO); } } @@ -534,7 +537,7 @@ // save questions first, because if Hibernate decides to flush Conditions first, // there is no cascade to questions and it may trigger an error for (QaQueContent question : toContent.getQaQueContents()) { - qaQuestionDAO.saveOrUpdateQaQueContent(question); + qaQuestionDAO.saveOrUpdate(question); } qaDAO.saveQa(toContent); } @@ -550,7 +553,7 @@ return; } - for (QaSession session : (Set) qaContent.getQaSessions()) { + for (QaSession session : qaContent.getQaSessions()) { List entries = coreNotebookService.getEntry(session.getQaSessionId(), CoreNotebookConstants.NOTEBOOK_TOOL, QaAppConstants.MY_SIGNATURE); for (NotebookEntry entry : entries) { @@ -570,10 +573,10 @@ QaContent content = qaDAO.getQaByContentId(toolContentId); if (content != null) { - for (QaSession session : (Set) content.getQaSessions()) { + for (QaSession session : content.getQaSessions()) { QaQueUsr user = qaQueUsrDAO.getQaUserBySession(userId.longValue(), session.getQaSessionId()); if (user != null) { - for (QaUsrResp response : (Set) user.getQaUsrResps()) { + for (QaUsrResp response : user.getQaUsrResps()) { qaUsrRespDAO.removeUserResponse(response); } @@ -620,7 +623,7 @@ Date attemptTime = new Date(); String message = new String(); for (QaUsrResp response : responses) { - String question = response.getQaQuestion().getQuestion(); + String question = response.getQaQuestion().getQbQuestion().getName(); String answer = response.getAnswer(); message += NEW_LINE_CHARACTER + NEW_LINE_CHARACTER + question + " " + answer; @@ -735,7 +738,7 @@ @Override public boolean isReadOnly(Long toolContentId) { QaContent content = qaDAO.getQaByContentId(toolContentId); - for (QaSession session : (Set) content.getQaSessions()) { + for (QaSession session : content.getQaSessions()) { if (!session.getQaQueUsers().isEmpty()) { return true; } @@ -899,7 +902,7 @@ @Override public List getToolOutputs(String name, Long toolContentId) { - return new ArrayList(); + return new ArrayList<>(); } @Override @@ -981,7 +984,7 @@ public void auditLogStartEditingActivityInMonitor(long toolContentID) { toolService.auditLogStartEditingActivityInMonitor(toolContentID); } - + @Override public boolean isLastActivity(Long toolSessionId) { return toolService.isLastActivity(toolSessionId); @@ -1059,6 +1062,10 @@ this.exportContentService = exportContentService; } + public void setQbService(IQbService qbService) { + this.qbService = qbService; + } + // ========================================================================================= /** * @return Returns the coreNotebookService. @@ -1222,11 +1229,20 @@ // Questions ArrayNode questions = JsonUtil.optArray(toolContentJSON, RestTags.QUESTIONS); for (JsonNode questionData : questions) { - QaQueContent question = new QaQueContent(JsonUtil.optString(questionData, RestTags.QUESTION_TEXT), - JsonUtil.optInt(questionData, RestTags.DISPLAY_ORDER), JsonUtil.optString(questionData, "feedback"), - JsonUtil.optBoolean(questionData, "required", Boolean.FALSE), - JsonUtil.optInt(questionData, "minWordsLimit", 0), qa); - saveOrUpdateQuestion(question); + QbQuestion qbQuestion = new QbQuestion(); + qbQuestion.setType(QbQuestion.TYPE_ESSAY); + qbQuestion.setQuestionId(qbService.generateNextQuestionId()); + qbQuestion.setVersion(1); + + qbQuestion.setName(JsonUtil.optString(questionData, RestTags.QUESTION_TEXT)); + qbQuestion.setFeedback(JsonUtil.optString(questionData, "feedback")); + qbQuestion.setAnswerRequired(JsonUtil.optBoolean(questionData, "required", Boolean.FALSE)); + qbQuestion.setMinWordsLimit(JsonUtil.optInt(questionData, "minWordsLimit", 0)); + saveOrUpdate(qbQuestion); + + QaQueContent question = new QaQueContent(qbQuestion, JsonUtil.optInt(questionData, RestTags.DISPLAY_ORDER), + qa); + saveOrUpdate(question); } // TODO Index: lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/web/controller/QaAuthoringController.java =================================================================== diff -u -ra7690b14578fa656e8782755c2f45b9ee7aa00db -rf49dd9f6b076828f464fc954bb9c3dc0c87e8b37 --- lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/web/controller/QaAuthoringController.java (.../QaAuthoringController.java) (revision a7690b14578fa656e8782755c2f45b9ee7aa00db) +++ lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/web/controller/QaAuthoringController.java (.../QaAuthoringController.java) (revision f49dd9f6b076828f464fc954bb9c3dc0c87e8b37) @@ -1,1222 +1,1231 @@ -/**************************************************************** - * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) - * ============================================================= - * License Information: http://lamsfoundation.org/licensing/lams/2.0/ - * - * This program 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. - * - * This program 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - * - * http://www.gnu.org/licenses/gpl.txt - * **************************************************************** - */ - -package org.lamsfoundation.lams.tool.qa.web.controller; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; -import java.util.SortedSet; -import java.util.TreeSet; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; - -import org.apache.log4j.Logger; -import org.lamsfoundation.lams.learningdesign.TextSearchConditionComparator; -import org.lamsfoundation.lams.qb.model.QbOption; -import org.lamsfoundation.lams.qb.model.QbQuestion; -import org.lamsfoundation.lams.qb.service.IQbService; -import org.lamsfoundation.lams.rating.model.RatingCriteria; -import org.lamsfoundation.lams.tool.ToolAccessMode; -import org.lamsfoundation.lams.tool.qa.QaAppConstants; -import org.lamsfoundation.lams.tool.qa.dto.QaQuestionDTO; -import org.lamsfoundation.lams.tool.qa.model.QaCondition; -import org.lamsfoundation.lams.tool.qa.model.QaContent; -import org.lamsfoundation.lams.tool.qa.model.QaQueContent; -import org.lamsfoundation.lams.tool.qa.service.IQaService; -import org.lamsfoundation.lams.tool.qa.util.AuthoringUtil; -import org.lamsfoundation.lams.tool.qa.util.QaApplicationException; -import org.lamsfoundation.lams.tool.qa.util.QaQueContentComparator; -import org.lamsfoundation.lams.tool.qa.util.QaQuestionContentDTOComparator; -import org.lamsfoundation.lams.tool.qa.util.QaUtils; -import org.lamsfoundation.lams.tool.qa.web.form.QaAuthoringForm; -import org.lamsfoundation.lams.usermanagement.dto.UserDTO; -import org.lamsfoundation.lams.util.CommonConstants; -import org.lamsfoundation.lams.util.MessageService; -import org.lamsfoundation.lams.util.WebUtil; -import org.lamsfoundation.lams.web.session.SessionManager; -import org.lamsfoundation.lams.web.util.AttributeNames; -import org.lamsfoundation.lams.web.util.SessionMap; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.stereotype.Controller; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; - -/** - * Q&A Tool's authoring methods. Additionally, there is one more method that initializes authoring and it's located in - * QaStarterAction.java. - * - * @author Ozgur Demirtas - */ -@Controller -@RequestMapping("/authoring") -public class QaAuthoringController implements QaAppConstants { - private static Logger logger = Logger.getLogger(QaAuthoringController.class.getName()); - - @Autowired - private IQaService qaService; - - @Autowired - private IQbService qbService; - - @Autowired - @Qualifier("qaMessageService") - private MessageService messageService; - - @RequestMapping("") - public String unspecified() { - return "authoring/AuthoringTabsHolder"; - } - - @RequestMapping("/authoring") - public String execute(@ModelAttribute("authoringForm") QaAuthoringForm authoringForm, HttpServletRequest request) - throws IOException, ServletException, QaApplicationException { - - QaUtils.cleanUpSessionAbsolute(request); - - String contentFolderID = WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID); - authoringForm.setContentFolderID(contentFolderID); - - authoringForm.resetRadioBoxes(); - - validateDefaultContent(request, authoringForm); - - String strToolContentID = request.getParameter(AttributeNames.PARAM_TOOL_CONTENT_ID); - authoringForm.setToolContentID(strToolContentID); - - SessionMap sessionMap = new SessionMap<>(); - sessionMap.put(QaAppConstants.ACTIVITY_TITLE_KEY, ""); - sessionMap.put(QaAppConstants.ACTIVITY_INSTRUCTIONS_KEY, ""); - sessionMap.put(AttributeNames.PARAM_CONTENT_FOLDER_ID, contentFolderID); - sessionMap.put(AttributeNames.PARAM_TOOL_CONTENT_ID, strToolContentID); - authoringForm.setHttpSessionID(sessionMap.getSessionID()); - - if (strToolContentID == null || strToolContentID.equals("")) { - QaUtils.cleanUpSessionAbsolute(request); - throw new ServletException("No Tool Content ID found"); - } - - QaContent qaContent = qaService.getQaContent(new Long(strToolContentID).longValue()); - if (qaContent == null) { - /* fetch default content */ - long defaultContentID = qaService.getToolDefaultContentIdBySignature(QaAppConstants.MY_SIGNATURE); - qaContent = qaService.getQaContent(defaultContentID); - qaContent = QaContent.newInstance(qaContent, new Long(strToolContentID)); - } - - prepareDTOandForm(request, authoringForm, qaContent, qaService, sessionMap); - - ToolAccessMode mode = WebUtil.readToolAccessModeAuthorDefaulted(request); - // request is from monitoring module - if (mode.isTeacher()) { - qaService.setDefineLater(strToolContentID, true); - } - request.setAttribute(AttributeNames.ATTR_MODE, mode.toString()); - - SortedSet conditionList = getQaConditionList(sessionMap); - conditionList.clear(); - conditionList.addAll(qaContent.getConditions()); - - authoringForm.setAllowRichEditor(qaContent.isAllowRichEditor()); - authoringForm.setUseSelectLeaderToolOuput(qaContent.isUseSelectLeaderToolOuput()); - - sessionMap.put(QaAppConstants.ATTR_QA_AUTHORING_FORM, authoringForm); - request.getSession().setAttribute(sessionMap.getSessionID(), sessionMap); - - // get rating criterias from DB - List ratingCriterias = qaService.getRatingCriterias(qaContent.getQaContentId()); - sessionMap.put(AttributeNames.ATTR_RATING_CRITERIAS, ratingCriterias); - - return "authoring/AuthoringTabsHolder"; - } - - /** - * retrives the existing content information from the db and prepares the data for presentation purposes. - * - * @param request - * @param mapping - * @param authoringForm - * @param mapQuestionContent - * @param toolContentID - * @return ActionForward - */ - protected QaContent prepareDTOandForm(HttpServletRequest request, - @ModelAttribute("authoringForm") QaAuthoringForm authoringForm, QaContent qaContent, IQaService qaService, - SessionMap sessionMap) { - - authoringForm.setUsernameVisible(qaContent.isUsernameVisible() ? "1" : "0"); - authoringForm.setAllowRateAnswers(qaContent.isAllowRateAnswers() ? "1" : "0"); - authoringForm.setNotifyTeachersOnResponseSubmit(qaContent.isNotifyTeachersOnResponseSubmit() ? "1" : "0"); - authoringForm.setShowOtherAnswers(qaContent.isShowOtherAnswers() ? "1" : "0"); - authoringForm.setQuestionsSequenced(qaContent.isQuestionsSequenced() ? "1" : "0"); - authoringForm.setLockWhenFinished(qaContent.isLockWhenFinished() ? "1" : "0"); - authoringForm.setNoReeditAllowed(qaContent.isNoReeditAllowed() ? "1" : "0"); - authoringForm.setMaximumRates(qaContent.getMaximumRates()); - authoringForm.setMinimumRates(qaContent.getMinimumRates()); - authoringForm.setReflect(qaContent.isReflect() ? "1" : "0"); - authoringForm.setReflectionSubject(qaContent.getReflectionSubject()); - authoringForm.setTitle(qaContent.getTitle()); - authoringForm.setInstructions(qaContent.getInstructions()); - authoringForm.setUseSelectLeaderToolOuput(qaContent.isUseSelectLeaderToolOuput()); - authoringForm.setAllowRichEditor(qaContent.isAllowRichEditor()); - sessionMap.put(QaAppConstants.ACTIVITY_TITLE_KEY, qaContent.getTitle()); - sessionMap.put(QaAppConstants.ACTIVITY_INSTRUCTIONS_KEY, qaContent.getInstructions()); - - List questionDTOs = new LinkedList<>(); - - /* - * get the existing question content - */ - Iterator queIterator = qaContent.getQaQueContents().iterator(); - while (queIterator.hasNext()) { - - QaQueContent qaQuestion = (QaQueContent) queIterator.next(); - if (qaQuestion != null) { - QaQuestionDTO qaQuestionDTO = new QaQuestionDTO(qaQuestion); - questionDTOs.add(qaQuestionDTO); - } - } - - request.setAttribute(QaAppConstants.TOTAL_QUESTION_COUNT, new Integer(questionDTOs.size())); - request.setAttribute(QaAppConstants.LIST_QUESTION_DTOS, questionDTOs); - sessionMap.put(QaAppConstants.LIST_QUESTION_DTOS, questionDTOs); - - SortedSet conditionSet = new TreeSet<>(new TextSearchConditionComparator()); - for (QaCondition condition : qaContent.getConditions()) { - conditionSet.add(condition); - for (QaQuestionDTO dto : questionDTOs) { - for (QaQueContent question : condition.getQuestions()) { - if (dto.getDisplayOrder().equals(String.valueOf(question.getDisplayOrder()))) { - condition.temporaryQuestionDTOSet.add(dto); - } - } - } - } - sessionMap.put(QaAppConstants.ATTR_CONDITION_SET, conditionSet); - - List listDeletedQuestionDTOs = new ArrayList<>(); - sessionMap.put(QaAppConstants.LIST_DELETED_QUESTION_DTOS, listDeletedQuestionDTOs); - - authoringForm.resetUserAction(); - - return qaContent; - } - - /** - * each tool has a signature. QA tool's signature is stored in MY_SIGNATURE. - * The default tool content id and other depending content ids are obtained - * in this method. if all the default content has been setup properly the - * method persists DEFAULT_CONTENT_ID in the session. - * - * @param request - * @param mapping - * @return ActionForward - */ - public boolean validateDefaultContent(HttpServletRequest request, - @ModelAttribute("authoringForm") QaAuthoringForm authoringForm) { - - /* - * retrieve the default content id based on tool signature - */ - long defaultContentID = 0; - try { - defaultContentID = qaService.getToolDefaultContentIdBySignature(QaAppConstants.MY_SIGNATURE); - if (defaultContentID == 0) { - QaAuthoringController.logger.debug("default content id has not been setup"); - return false; - } - } catch (Exception e) { - QaAuthoringController.logger.error("error getting the default content id: " + e.getMessage()); - persistError(request, "error.defaultContent.notSetup"); - return false; - } - - /* - * retrieve uid of the content based on default content id determined above - */ - try { - //retrieve uid of the content based on default content id determined above - QaContent qaContent = qaService.getQaContent(defaultContentID); - if (qaContent == null) { - QaAuthoringController.logger.error("Exception occured: No default content"); - persistError(request, "error.defaultContent.notSetup"); - return false; - } - - } catch (Exception e) { - QaAuthoringController.logger.error("Exception occured: No default question content"); - persistError(request, "error.defaultContent.notSetup"); - return false; - } - - return true; - } - - /** - * persists error messages to request scope - * - * @param request - * @param message - */ - public void persistError(HttpServletRequest request, String message) { - MultiValueMap errorMap = new LinkedMultiValueMap<>(); - errorMap.add("GLOBAL", messageService.getMessage(message)); - request.setAttribute("errorMap", errorMap); - } - - private SortedSet getQaConditionList(SessionMap sessionMap) { - SortedSet list = (SortedSet) sessionMap.get(QaAppConstants.ATTR_CONDITION_SET); - if (list == null) { - list = new TreeSet<>(new TextSearchConditionComparator()); - sessionMap.put(QaAppConstants.ATTR_CONDITION_SET, list); - } - return list; - } - - /** - * submits content into the tool database - */ - @RequestMapping("/submitAllContent") - public String submitAllContent(@ModelAttribute("authoringForm") QaAuthoringForm authoringForm, - HttpServletRequest request) throws IOException, ServletException { - - String httpSessionID = authoringForm.getHttpSessionID(); - SessionMap sessionMap = (SessionMap) request.getSession() - .getAttribute(httpSessionID); - - String contentFolderID = WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID); - authoringForm.setContentFolderID(contentFolderID); - - String strToolContentID = request.getParameter(AttributeNames.PARAM_TOOL_CONTENT_ID); - Long toolContentID = new Long(strToolContentID); - - List questionDTOs = (List) sessionMap.get(QaAppConstants.LIST_QUESTION_DTOS); - - MultiValueMap errorMap = new LinkedMultiValueMap<>(); - if (questionDTOs.size() == 0) { - errorMap.add("GLOBAL", messageService.getMessage("questions.none.submitted")); - } - - String richTextTitle = request.getParameter(QaAppConstants.TITLE); - String richTextInstructions = request.getParameter(QaAppConstants.INSTRUCTIONS); - - authoringForm.setTitle(richTextTitle); - authoringForm.setInstructions(richTextInstructions); - - sessionMap.put(QaAppConstants.ACTIVITY_TITLE_KEY, richTextTitle); - sessionMap.put(QaAppConstants.ACTIVITY_INSTRUCTIONS_KEY, richTextInstructions); - - if (!errorMap.isEmpty()) { - request.setAttribute("errorMap", errorMap); - QaAuthoringController.logger.debug("errors saved: " + errorMap); - } - - QaContent qaContent = qaService.getQaContent(toolContentID); - if (errorMap.isEmpty()) { - ToolAccessMode mode = WebUtil.readToolAccessModeAuthorDefaulted(request); - request.setAttribute(AttributeNames.ATTR_MODE, mode.toString()); - - List deletedQuestionDTOs = (List) sessionMap.get(LIST_DELETED_QUESTION_DTOS); - - // in case request is from monitoring module - recalculate User Answers - if (mode.isTeacher()) { - Set oldQuestions = qaContent.getQaQueContents(); - qaService.removeQuestionsFromCache(qaContent); - qaService.setDefineLater(strToolContentID, false); - - // audit log the teacher has started editing activity in monitor - qaService.auditLogStartEditingActivityInMonitor(toolContentID); - - // recalculate User Answers - qaService.recalculateUserAnswers(qaContent, oldQuestions, questionDTOs, deletedQuestionDTOs); - } - - // remove deleted questions - for (QaQuestionDTO deletedQuestionDTO : deletedQuestionDTOs) { - QaQueContent removeableQuestion = qaService.getQuestionByUid(deletedQuestionDTO.getUid()); - if (removeableQuestion != null) { - qaContent.getQaQueContents().remove(removeableQuestion); - qaService.removeQuestion(removeableQuestion); - } - } - - // store content - SortedSet conditionSet = (SortedSet) sessionMap - .get(QaAppConstants.ATTR_CONDITION_SET); - qaContent = saveOrUpdateQaContent(questionDTOs, request, qaContent, toolContentID, conditionSet); - - //reOrganizeDisplayOrder - List sortedQuestions = qaService.getAllQuestionEntriesSorted(qaContent.getUid().longValue()); - Iterator iter = sortedQuestions.iterator(); - int displayOrder = 1; - while (iter.hasNext()) { - QaQueContent question = iter.next(); - - QaQueContent existingQaQueContent = qaService.getQuestionByUid(question.getUid()); - existingQaQueContent.setDisplayOrder(displayOrder); - qaService.saveOrUpdateQuestion(existingQaQueContent); - displayOrder++; - } - - // ************************* Handle rating criterias ******************* - List oldCriterias = (List) sessionMap - .get(AttributeNames.ATTR_RATING_CRITERIAS); - qaService.saveRatingCriterias(request, oldCriterias, toolContentID); - - QaUtils.setFormProperties(request, authoringForm, strToolContentID, httpSessionID); - - request.setAttribute(CommonConstants.LAMS_AUTHORING_SUCCESS_FLAG, Boolean.TRUE); - - } else { - if (qaContent != null) { - QaUtils.setFormProperties(request, authoringForm, strToolContentID, httpSessionID); - } - } - - List delConditionList = getDeletedQaConditionList(sessionMap); - Iterator iter = delConditionList.iterator(); - while (iter.hasNext()) { - QaCondition condition = iter.next(); - iter.remove(); - qaService.deleteCondition(condition); - } - - authoringForm.resetUserAction(); - authoringForm.setToolContentID(strToolContentID); - authoringForm.setHttpSessionID(httpSessionID); - authoringForm.setCurrentTab("1"); - - request.setAttribute(QaAppConstants.LIST_QUESTION_DTOS, questionDTOs); - request.getSession().setAttribute(httpSessionID, sessionMap); - request.setAttribute(QaAppConstants.TOTAL_QUESTION_COUNT, new Integer(questionDTOs.size())); - sessionMap.put(QaAppConstants.LIST_QUESTION_DTOS, questionDTOs); - - return "authoring/AuthoringTabsHolder"; - } - - private QaContent saveOrUpdateQaContent(List questionDTOs, HttpServletRequest request, - QaContent qaContent, Long toolContentId, Set conditions) { - UserDTO toolUser = (UserDTO) SessionManager.getSession().getAttribute(AttributeNames.USER); - - String richTextTitle = request.getParameter(QaAppConstants.TITLE); - String richTextInstructions = request.getParameter(QaAppConstants.INSTRUCTIONS); - String usernameVisible = request.getParameter(QaAppConstants.USERNAME_VISIBLE); - String allowRateQuestions = request.getParameter(QaAppConstants.ALLOW_RATE_ANSWERS); - String notifyTeachersOnResponseSubmit = request.getParameter(QaAppConstants.NOTIFY_TEACHERS_ON_RESPONSE_SUBMIT); - String showOtherAnswers = request.getParameter("showOtherAnswers"); - String questionsSequenced = request.getParameter(QaAppConstants.QUESTIONS_SEQUENCED); - String lockWhenFinished = request.getParameter("lockWhenFinished"); - String noReeditAllowed = request.getParameter("noReeditAllowed"); - String allowRichEditor = request.getParameter("allowRichEditor"); - String useSelectLeaderToolOuput = request.getParameter("useSelectLeaderToolOuput"); - String reflect = request.getParameter(QaAppConstants.REFLECT); - String reflectionSubject = request.getParameter(QaAppConstants.REFLECTION_SUBJECT); - int minimumRates = WebUtil.readIntParam(request, "minimumRates"); - int maximumRates = WebUtil.readIntParam(request, "maximumRates"); - - boolean questionsSequencedBoolean = false; - boolean lockWhenFinishedBoolean = false; - boolean noReeditAllowedBoolean = false; - boolean usernameVisibleBoolean = false; - boolean allowRateQuestionsBoolean = false; - boolean notifyTeachersOnResponseSubmitBoolean = false; - boolean showOtherAnswersBoolean = false; - boolean reflectBoolean = false; - boolean allowRichEditorBoolean = false; - boolean useSelectLeaderToolOuputBoolean = false; - - if (questionsSequenced != null && questionsSequenced.equalsIgnoreCase("1")) { - questionsSequencedBoolean = true; - } - - if (lockWhenFinished != null && lockWhenFinished.equalsIgnoreCase("1")) { - lockWhenFinishedBoolean = true; - } - - if (noReeditAllowed != null && noReeditAllowed.equalsIgnoreCase("1")) { - noReeditAllowedBoolean = true; - lockWhenFinishedBoolean = true; - } - - if (usernameVisible != null && usernameVisible.equalsIgnoreCase("1")) { - usernameVisibleBoolean = true; - } - - if (showOtherAnswers != null && showOtherAnswers.equalsIgnoreCase("1")) { - showOtherAnswersBoolean = true; - } - - if (allowRateQuestions != null && allowRateQuestions.equalsIgnoreCase("1") && showOtherAnswersBoolean) { - allowRateQuestionsBoolean = true; - } - - if (notifyTeachersOnResponseSubmit != null && notifyTeachersOnResponseSubmit.equalsIgnoreCase("1")) { - notifyTeachersOnResponseSubmitBoolean = true; - } - - if (allowRichEditor != null && allowRichEditor.equalsIgnoreCase("true")) { - allowRichEditorBoolean = true; - } - - if (useSelectLeaderToolOuput != null && useSelectLeaderToolOuput.equalsIgnoreCase("true")) { - useSelectLeaderToolOuputBoolean = true; - } - - if (reflect != null && reflect.equalsIgnoreCase("1")) { - reflectBoolean = true; - } - long userId = 0; - if (toolUser != null) { - userId = toolUser.getUserID().longValue(); - } else { - HttpSession ss = SessionManager.getSession(); - UserDTO user = (UserDTO) ss.getAttribute(AttributeNames.USER); - if (user != null) { - userId = user.getUserID().longValue(); - } else { - userId = 0; - } - } - - boolean newContent = false; - if (qaContent == null) { - qaContent = new QaContent(); - newContent = true; - } - - qaContent.setQaContentId(toolContentId); - qaContent.setTitle(richTextTitle); - qaContent.setInstructions(richTextInstructions); - qaContent.setUpdateDate(new Date(System.currentTimeMillis())); - /** keep updating this one */ - qaContent.setCreatedBy(userId); - /** make sure we are setting the userId from the User object above */ - - qaContent.setUsernameVisible(usernameVisibleBoolean); - qaContent.setAllowRateAnswers(allowRateQuestionsBoolean); - qaContent.setNotifyTeachersOnResponseSubmit(notifyTeachersOnResponseSubmitBoolean); - qaContent.setShowOtherAnswers(showOtherAnswersBoolean); - qaContent.setQuestionsSequenced(questionsSequencedBoolean); - qaContent.setLockWhenFinished(lockWhenFinishedBoolean); - qaContent.setNoReeditAllowed(noReeditAllowedBoolean); - qaContent.setReflect(reflectBoolean); - qaContent.setReflectionSubject(reflectionSubject); - qaContent.setAllowRichEditor(allowRichEditorBoolean); - qaContent.setUseSelectLeaderToolOuput(useSelectLeaderToolOuputBoolean); - qaContent.setMinimumRates(minimumRates); - qaContent.setMaximumRates(maximumRates); - - qaContent.setConditions(new TreeSet(new TextSearchConditionComparator())); - if (newContent) { - qaService.createQaContent(qaContent); - } else { - qaService.updateQaContent(qaContent); - } - - qaContent = qaService.getQaContent(toolContentId); - - // persist questions - int displayOrder = 0; - for (QaQuestionDTO questionDTO : questionDTOs) { - - String questionText = questionDTO.getQuestion(); - - // skip empty questions - if (questionText.isEmpty()) { - continue; - } - - ++displayOrder; - - QaQueContent question = qaService.getQuestionByUid(questionDTO.getUid()); - - // in case question doesn't exist - if (question == null) { - question = new QaQueContent(questionText, displayOrder, questionDTO.getFeedback(), - questionDTO.isRequired(), questionDTO.getMinWordsLimit(), qaContent); - qaContent.getQaQueContents().add(question); - question.setQaContent(qaContent); - - // in case question exists already - } else { - - question.setQuestion(questionText); - question.setFeedback(questionDTO.getFeedback()); - question.setDisplayOrder(displayOrder); - question.setRequired(questionDTO.isRequired()); - question.setMinWordsLimit(questionDTO.getMinWordsLimit()); - } - - qaService.saveOrUpdateQuestion(question); - } - - for (QaCondition condition : conditions) { - condition.setQuestions(new TreeSet<>(new QaQueContentComparator())); - for (QaQuestionDTO dto : condition.temporaryQuestionDTOSet) { - for (QaQueContent queContent : qaContent.getQaQueContents()) { - if (dto.getDisplayOrder().equals(String.valueOf(queContent.getDisplayOrder()))) { - condition.getQuestions().add(queContent); - } - } - } - } - qaContent.setConditions(conditions); - qaService.updateQaContent(qaContent); - - return qaContent; - } - - /** - * Adds QbQuestion, selected in the question bank, to the current question list. - */ - @SuppressWarnings("unchecked") - @RequestMapping(value = "/importQbQuestion", method = RequestMethod.POST) - private String importQbQuestion(@ModelAttribute("newQuestionForm") QaAuthoringForm authoringForm, - HttpServletRequest request, @RequestParam String httpSessionID, @RequestParam Long qbQuestionUid) { - SessionMap sessionMap = (SessionMap) request.getSession() - .getAttribute(httpSessionID); - - //get QbQuestion from DB - QbQuestion qbQuestion = qbService.getQuestionByUid(qbQuestionUid); - - List questionDTOs = (List) sessionMap.get(QaAppConstants.LIST_QUESTION_DTOS); - boolean duplicates = AuthoringUtil.checkDuplicateQuestions(questionDTOs, qbQuestion.getName()); - if (!duplicates) { - String displayOrder = String.valueOf(questionDTOs.size() + 1); - boolean requiredBoolean = false; - int minWordsLimit = 0; - QaQuestionDTO qaQuestionDTO = new QaQuestionDTO(qbQuestion.getName(), displayOrder, qbQuestion.getFeedback(), - requiredBoolean, minWordsLimit); - questionDTOs.add(qaQuestionDTO); - } else { - //entry duplicate, not adding - } - - request.setAttribute(QaAppConstants.LIST_QUESTION_DTOS, questionDTOs); - sessionMap.put(QaAppConstants.LIST_QUESTION_DTOS, questionDTOs); - - String contentFolderID = (String) sessionMap.get(AttributeNames.PARAM_CONTENT_FOLDER_ID); - String toolContentID = (String) sessionMap.get(AttributeNames.PARAM_TOOL_CONTENT_ID); - authoringForm.setContentFolderID(contentFolderID); - authoringForm.setHttpSessionID(httpSessionID); - authoringForm.setToolContentID(toolContentID); - request.setAttribute("authoringForm", authoringForm); - return "authoring/itemlist"; - } - - /** - * saveSingleQuestion - */ - @RequestMapping("/saveSingleQuestion") - public String saveSingleQuestion(@ModelAttribute("newQuestionForm") QaAuthoringForm newQuestionForm, - HttpServletRequest request) throws IOException, ServletException { - - String httpSessionID = newQuestionForm.getHttpSessionID(); - - SessionMap sessionMap = (SessionMap) request.getSession() - .getAttribute(httpSessionID); - - String contentFolderID = WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID); - newQuestionForm.setContentFolderID(contentFolderID); - - String strToolContentID = request.getParameter(AttributeNames.PARAM_TOOL_CONTENT_ID); - - String editQuestionBoxRequest = request.getParameter("editQuestionBoxRequest"); - - List questionDTOs = (List) sessionMap.get(QaAppConstants.LIST_QUESTION_DTOS); - - String newQuestion = request.getParameter("newQuestion"); - - String feedback = request.getParameter("feedback"); - - String editableQuestionIndex = request.getParameter("editableQuestionIndex"); - - boolean requiredBoolean = newQuestionForm.isRequired(); - - int minWordsLimit = WebUtil.readIntParam(request, "minWordsLimit"); - - if (newQuestion != null && newQuestion.length() > 0) { - if (editQuestionBoxRequest != null && editQuestionBoxRequest.equals("false")) { - //request for add and save - boolean duplicates = AuthoringUtil.checkDuplicateQuestions(questionDTOs, newQuestion); - - if (!duplicates) { - QaQuestionDTO qaQuestionDTO = null; - Iterator iter = questionDTOs.iterator(); - while (iter.hasNext()) { - qaQuestionDTO = iter.next(); - - String displayOrder = qaQuestionDTO.getDisplayOrder(); - if (displayOrder != null && !displayOrder.equals("")) { - if (displayOrder.equals(editableQuestionIndex)) { - break; - } - - } - } - - qaQuestionDTO.setQuestion(newQuestion); - qaQuestionDTO.setFeedback(feedback); - qaQuestionDTO.setDisplayOrder(editableQuestionIndex); - qaQuestionDTO.setRequired(requiredBoolean); - qaQuestionDTO.setMinWordsLimit(minWordsLimit); - - questionDTOs = AuthoringUtil.reorderUpdateQuestionDTOs(questionDTOs, qaQuestionDTO, - editableQuestionIndex); - } else { - //duplicate question entry, not adding - } - } else { - //request for edit and save - QaQuestionDTO qaQuestionDTO = null; - Iterator iter = questionDTOs.iterator(); - while (iter.hasNext()) { - qaQuestionDTO = iter.next(); - - String displayOrder = qaQuestionDTO.getDisplayOrder(); - - if (displayOrder != null && !displayOrder.equals("")) { - if (displayOrder.equals(editableQuestionIndex)) { - break; - } - - } - } - - qaQuestionDTO.setQuestion(newQuestion); - qaQuestionDTO.setFeedback(feedback); - qaQuestionDTO.setDisplayOrder(editableQuestionIndex); - qaQuestionDTO.setRequired(requiredBoolean); - qaQuestionDTO.setMinWordsLimit(minWordsLimit); - - questionDTOs = AuthoringUtil.reorderUpdateQuestionDTOs(questionDTOs, qaQuestionDTO, - editableQuestionIndex); - } - } else { - //entry blank, not adding - } - - request.setAttribute(QaAppConstants.LIST_QUESTION_DTOS, questionDTOs); - sessionMap.put(QaAppConstants.LIST_QUESTION_DTOS, questionDTOs); - - String richTextTitle = request.getParameter(QaAppConstants.TITLE); - String richTextInstructions = request.getParameter(QaAppConstants.INSTRUCTIONS); - - newQuestionForm.setTitle(richTextTitle); - newQuestionForm.setInstructions(richTextInstructions); - - sessionMap.put(QaAppConstants.ACTIVITY_TITLE_KEY, richTextTitle); - sessionMap.put(QaAppConstants.ACTIVITY_INSTRUCTIONS_KEY, richTextInstructions); - - request.getSession().setAttribute(httpSessionID, sessionMap); - - QaUtils.setFormProperties(request, newQuestionForm, strToolContentID, httpSessionID); - - newQuestionForm.setToolContentID(strToolContentID); - newQuestionForm.setHttpSessionID(httpSessionID); - newQuestionForm.setCurrentTab("1"); - - request.getSession().setAttribute(httpSessionID, sessionMap); - request.setAttribute(QaAppConstants.TOTAL_QUESTION_COUNT, new Integer(questionDTOs.size())); - request.setAttribute("authoringForm", newQuestionForm); - - return "authoring/AuthoringTabsHolder"; - } - - /** - * addSingleQuestion - */ - @RequestMapping("/addSingleQuestion") - public String addSingleQuestion(@ModelAttribute("newQuestionForm") QaAuthoringForm newQuestionForm, - HttpServletRequest request) throws IOException, ServletException { - - String httpSessionID = newQuestionForm.getHttpSessionID(); - - SessionMap sessionMap = (SessionMap) request.getSession() - .getAttribute(httpSessionID); - - String contentFolderID = WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID); - newQuestionForm.setContentFolderID(contentFolderID); - - String strToolContentID = request.getParameter(AttributeNames.PARAM_TOOL_CONTENT_ID); - - List questionDTOs = (List) sessionMap.get(QaAppConstants.LIST_QUESTION_DTOS); - - String newQuestion = request.getParameter("newQuestion"); - String feedback = request.getParameter("feedback"); - boolean requiredBoolean = newQuestionForm.isRequired(); - int minWordsLimit = WebUtil.readIntParam(request, "minWordsLimit"); - - int listSize = questionDTOs.size(); - - if (newQuestion != null && newQuestion.length() > 0) { - boolean duplicates = AuthoringUtil.checkDuplicateQuestions(questionDTOs, newQuestion); - - if (!duplicates) { - QaQuestionDTO qaQuestionDTO = new QaQuestionDTO(newQuestion, new Long(listSize + 1).toString(), - feedback, requiredBoolean, minWordsLimit); - questionDTOs.add(qaQuestionDTO); - } else { - //entry duplicate, not adding - } - } else { - //entry blank, not adding - } - - request.setAttribute(QaAppConstants.LIST_QUESTION_DTOS, questionDTOs); - sessionMap.put(QaAppConstants.LIST_QUESTION_DTOS, questionDTOs); - - String richTextTitle = request.getParameter(QaAppConstants.TITLE); - String richTextInstructions = request.getParameter(QaAppConstants.INSTRUCTIONS); - - newQuestionForm.setTitle(richTextTitle); - newQuestionForm.setInstructions(richTextInstructions); - - sessionMap.put(QaAppConstants.ACTIVITY_TITLE_KEY, richTextTitle); - sessionMap.put(QaAppConstants.ACTIVITY_INSTRUCTIONS_KEY, richTextInstructions); - - request.getSession().setAttribute(httpSessionID, sessionMap); - - QaUtils.setFormProperties(request, newQuestionForm, strToolContentID, httpSessionID); - - newQuestionForm.setToolContentID(strToolContentID); - newQuestionForm.setHttpSessionID(httpSessionID); - newQuestionForm.setCurrentTab("1"); - - request.getSession().setAttribute(httpSessionID, sessionMap); - request.setAttribute(QaAppConstants.TOTAL_QUESTION_COUNT, new Integer(questionDTOs.size())); - request.setAttribute("authoringForm", newQuestionForm); - return "authoring/AuthoringTabsHolder"; - } - - /** - * opens up an new screen within the current page for adding a new question - */ - @RequestMapping("/newQuestionBox") - public String newQuestionBox(@ModelAttribute("newQuestionForm") QaAuthoringForm newQuestionForm, - HttpServletRequest request) throws IOException, ServletException { - - String httpSessionID = newQuestionForm.getHttpSessionID(); - - SessionMap sessionMap = (SessionMap) request.getSession() - .getAttribute(httpSessionID); - - String contentFolderID = WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID); - - newQuestionForm.setContentFolderID(contentFolderID); - - String strToolContentID = request.getParameter(AttributeNames.PARAM_TOOL_CONTENT_ID); - - String richTextTitle = request.getParameter(QaAppConstants.TITLE); - - String richTextInstructions = request.getParameter(QaAppConstants.INSTRUCTIONS); - - newQuestionForm.setTitle(richTextTitle); - newQuestionForm.setInstructions(richTextInstructions); - - QaUtils.setFormProperties(request, newQuestionForm, strToolContentID, httpSessionID); - - Collection questionDTOs = (Collection) sessionMap - .get(QaAppConstants.LIST_QUESTION_DTOS); - request.setAttribute(QaAppConstants.TOTAL_QUESTION_COUNT, new Integer(questionDTOs.size())); - request.setAttribute("authoringForm", newQuestionForm); - - return "authoring/newQuestionBox"; - } - - /** - * opens up an new screen within the current page for editing a question - */ - @RequestMapping("/newEditableQuestionBox") - public String newEditableQuestionBox(@ModelAttribute("newQuestionForm") QaAuthoringForm newQuestionForm, - HttpServletRequest request) throws IOException, ServletException { - - String httpSessionID = newQuestionForm.getHttpSessionID(); - - SessionMap sessionMap = (SessionMap) request.getSession() - .getAttribute(httpSessionID); - - String questionIndex = request.getParameter("questionIndex"); - - newQuestionForm.setEditableQuestionIndex(questionIndex); - - List questionDTOs = (List) sessionMap.get(QaAppConstants.LIST_QUESTION_DTOS); - - String editableQuestion = ""; - String editableFeedback = ""; - boolean requiredBoolean = false; - int minWordsLimit = 0; - Iterator iter = questionDTOs.iterator(); - while (iter.hasNext()) { - QaQuestionDTO qaQuestionDTO = iter.next(); - String displayOrder = qaQuestionDTO.getDisplayOrder(); - - if (displayOrder != null && !displayOrder.equals("")) { - if (displayOrder.equals(questionIndex)) { - editableFeedback = qaQuestionDTO.getFeedback(); - editableQuestion = qaQuestionDTO.getQuestion(); - requiredBoolean = qaQuestionDTO.isRequired(); - minWordsLimit = qaQuestionDTO.getMinWordsLimit(); - break; - } - - } - } - - String contentFolderID = WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID); - newQuestionForm.setContentFolderID(contentFolderID); - - String strToolContentID = request.getParameter(AttributeNames.PARAM_TOOL_CONTENT_ID); - - String richTextTitle = request.getParameter(QaAppConstants.TITLE); - String richTextInstructions = request.getParameter(QaAppConstants.INSTRUCTIONS); - - newQuestionForm.setTitle(richTextTitle); - newQuestionForm.setInstructions(richTextInstructions); - - QaUtils.setFormProperties(request, newQuestionForm, strToolContentID, httpSessionID); - - newQuestionForm.setRequired(requiredBoolean); - newQuestionForm.setMinWordsLimit(minWordsLimit); - newQuestionForm.setEditableQuestionText(editableQuestion); - newQuestionForm.setFeedback(editableFeedback); - - request.setAttribute(QaAppConstants.TOTAL_QUESTION_COUNT, new Integer(questionDTOs.size())); - request.setAttribute("authoringForm", newQuestionForm); - - return "authoring/newQuestionBox"; - } - - /** - * removes a question from the questions map - */ - @RequestMapping("/removeQuestion") - public String removeQuestion(@ModelAttribute("newQuestionForm") QaAuthoringForm newQuestionForm, - HttpServletRequest request) throws IOException, ServletException { - - String httpSessionID = newQuestionForm.getHttpSessionID(); - SessionMap sessionMap = (SessionMap) request.getSession() - .getAttribute(httpSessionID); - - String questionIndexToDelete = request.getParameter("questionIndex"); - QaQuestionDTO questionToDelete = null; - List questionDTOs = (List) sessionMap.get(QaAppConstants.LIST_QUESTION_DTOS); - - List listFinalQuestionDTO = new LinkedList<>(); - int queIndex = 0; - for (QaQuestionDTO questionDTO : questionDTOs) { - - String questionText = questionDTO.getQuestion(); - String displayOrder = questionDTO.getDisplayOrder(); - - if (questionText != null && !questionText.equals("") && (!displayOrder.equals(questionIndexToDelete))) { - - ++queIndex; - questionDTO.setDisplayOrder(new Integer(queIndex).toString()); - listFinalQuestionDTO.add(questionDTO); - } - if ((questionText != null) && (!questionText.isEmpty()) && displayOrder.equals(questionIndexToDelete)) { - List deletedQuestionDTOs = (List) sessionMap - .get(LIST_DELETED_QUESTION_DTOS); - ; - deletedQuestionDTOs.add(questionDTO); - sessionMap.put(LIST_DELETED_QUESTION_DTOS, deletedQuestionDTOs); - questionToDelete = questionDTO; - } - } - request.setAttribute(QaAppConstants.LIST_QUESTION_DTOS, listFinalQuestionDTO); - sessionMap.put(QaAppConstants.LIST_QUESTION_DTOS, listFinalQuestionDTO); - request.setAttribute(QaAppConstants.TOTAL_QUESTION_COUNT, new Integer(listFinalQuestionDTO.size())); - - SortedSet conditions = (SortedSet) sessionMap.get(QaAppConstants.ATTR_CONDITION_SET); - Iterator conditionIter = conditions.iterator(); - while (conditionIter.hasNext()) { - QaCondition condition = conditionIter.next(); - Iterator dtoIter = condition.temporaryQuestionDTOSet.iterator(); - while (dtoIter.hasNext()) { - if (dtoIter.next() == questionToDelete) { - dtoIter.remove(); - } - } - if (condition.temporaryQuestionDTOSet.isEmpty()) { - conditionIter.remove(); - } - } - - String contentFolderID = WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID); - newQuestionForm.setContentFolderID(contentFolderID); - String richTextTitle = request.getParameter(QaAppConstants.TITLE); - String richTextInstructions = request.getParameter(QaAppConstants.INSTRUCTIONS); - sessionMap.put(QaAppConstants.ACTIVITY_TITLE_KEY, richTextTitle); - sessionMap.put(QaAppConstants.ACTIVITY_INSTRUCTIONS_KEY, richTextInstructions); - String strToolContentID = request.getParameter(AttributeNames.PARAM_TOOL_CONTENT_ID); - newQuestionForm.setTitle(richTextTitle); - newQuestionForm.setInstructions(richTextInstructions); - request.getSession().setAttribute(httpSessionID, sessionMap); - QaUtils.setFormProperties(request, newQuestionForm, strToolContentID, httpSessionID); - newQuestionForm.setToolContentID(strToolContentID); - newQuestionForm.setHttpSessionID(httpSessionID); - newQuestionForm.setCurrentTab("1"); - request.setAttribute("authoringForm", newQuestionForm); - - return "authoring/AuthoringTabsHolder"; - } - - /** - * moves a question down in the list - */ - @RequestMapping("/moveQuestionDown") - public String moveQuestionDown(@ModelAttribute("newQuestionForm") QaAuthoringForm newQuestionForm, - HttpServletRequest request) throws IOException, ServletException { - - String httpSessionID = newQuestionForm.getHttpSessionID(); - SessionMap sessionMap = (SessionMap) request.getSession() - .getAttribute(httpSessionID); - - String questionIndex = request.getParameter("questionIndex"); - - List questionDTOs = (List) sessionMap.get(QaAppConstants.LIST_QUESTION_DTOS); - - SortedSet conditionSet = (SortedSet) sessionMap - .get(QaAppConstants.ATTR_CONDITION_SET); - - questionDTOs = QaAuthoringController.swapQuestions(questionDTOs, questionIndex, "down", conditionSet); - - questionDTOs = QaAuthoringController.reorderQuestionDTOs(questionDTOs); - - sessionMap.put(QaAppConstants.LIST_QUESTION_DTOS, questionDTOs); - - String contentFolderID = WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID); - newQuestionForm.setContentFolderID(contentFolderID); - - String richTextTitle = request.getParameter(QaAppConstants.TITLE); - - String richTextInstructions = request.getParameter(QaAppConstants.INSTRUCTIONS); - - sessionMap.put(QaAppConstants.ACTIVITY_TITLE_KEY, richTextTitle); - sessionMap.put(QaAppConstants.ACTIVITY_INSTRUCTIONS_KEY, richTextInstructions); - - String strToolContentID = request.getParameter(AttributeNames.PARAM_TOOL_CONTENT_ID); - - newQuestionForm.setTitle(richTextTitle); - newQuestionForm.setInstructions(richTextInstructions); - request.getSession().setAttribute(httpSessionID, sessionMap); - - QaUtils.setFormProperties(request, newQuestionForm, strToolContentID, httpSessionID); - - newQuestionForm.setToolContentID(strToolContentID); - newQuestionForm.setHttpSessionID(httpSessionID); - newQuestionForm.setCurrentTab("1"); - - request.setAttribute(QaAppConstants.LIST_QUESTION_DTOS, questionDTOs); - - request.setAttribute(QaAppConstants.TOTAL_QUESTION_COUNT, new Integer(questionDTOs.size())); - request.setAttribute("authoringForm", newQuestionForm); - return "authoring/AuthoringTabsHolder"; - } - - /** - * moves a question up in the list - */ - @RequestMapping("/moveQuestionUp") - public String moveQuestionUp(@ModelAttribute("newQuestionForm") QaAuthoringForm newQuestionForm, - HttpServletRequest request) throws IOException, ServletException { - - String httpSessionID = newQuestionForm.getHttpSessionID(); - - SessionMap sessionMap = (SessionMap) request.getSession() - .getAttribute(httpSessionID); - - String questionIndex = request.getParameter("questionIndex"); - - List questionDTOs = (List) sessionMap.get(QaAppConstants.LIST_QUESTION_DTOS); - - SortedSet conditionSet = (SortedSet) sessionMap - .get(QaAppConstants.ATTR_CONDITION_SET); - questionDTOs = QaAuthoringController.swapQuestions(questionDTOs, questionIndex, "up", conditionSet); - - questionDTOs = QaAuthoringController.reorderQuestionDTOs(questionDTOs); - - sessionMap.put(QaAppConstants.LIST_QUESTION_DTOS, questionDTOs); - - String contentFolderID = WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID); - - newQuestionForm.setContentFolderID(contentFolderID); - - String richTextTitle = request.getParameter(QaAppConstants.TITLE); - - String richTextInstructions = request.getParameter(QaAppConstants.INSTRUCTIONS); - - sessionMap.put(QaAppConstants.ACTIVITY_TITLE_KEY, richTextTitle); - sessionMap.put(QaAppConstants.ACTIVITY_INSTRUCTIONS_KEY, richTextInstructions); - - String strToolContentID = request.getParameter(AttributeNames.PARAM_TOOL_CONTENT_ID); - - newQuestionForm.setTitle(richTextTitle); - newQuestionForm.setInstructions(richTextInstructions); - - request.getSession().setAttribute(httpSessionID, sessionMap); - - QaUtils.setFormProperties(request, newQuestionForm, strToolContentID, httpSessionID); - - newQuestionForm.setToolContentID(strToolContentID); - newQuestionForm.setHttpSessionID(httpSessionID); - newQuestionForm.setCurrentTab("1"); - - request.setAttribute(QaAppConstants.LIST_QUESTION_DTOS, questionDTOs); - - request.setAttribute(QaAppConstants.TOTAL_QUESTION_COUNT, new Integer(questionDTOs.size())); - request.setAttribute("authoringForm", newQuestionForm); - return "authoring/AuthoringTabsHolder"; - } - - private static List swapQuestions(List questionDTOs, String questionIndex, - String direction, Set conditions) { - - int intQuestionIndex = new Integer(questionIndex).intValue(); - int intOriginalQuestionIndex = intQuestionIndex; - - int replacedQuestionIndex = 0; - if (direction.equals("down")) { - // direction down - replacedQuestionIndex = ++intQuestionIndex; - } else { - // direction up - replacedQuestionIndex = --intQuestionIndex; - } - - QaQuestionDTO mainQuestion = QaAuthoringController.getQuestionAtDisplayOrder(questionDTOs, - intOriginalQuestionIndex); - - QaQuestionDTO replacedQuestion = QaAuthoringController.getQuestionAtDisplayOrder(questionDTOs, - replacedQuestionIndex); - - List newQuestionDtos = new LinkedList<>(); - - Iterator iter = questionDTOs.iterator(); - while (iter.hasNext()) { - QaQuestionDTO questionDTO = iter.next(); - QaQuestionDTO tempQuestion = null; - - if (!questionDTO.getDisplayOrder().equals(new Integer(intOriginalQuestionIndex).toString()) - && !questionDTO.getDisplayOrder().equals(new Integer(replacedQuestionIndex).toString())) { - // normal copy - tempQuestion = questionDTO; - - } else if (questionDTO.getDisplayOrder().equals(new Integer(intOriginalQuestionIndex).toString())) { - // move type 1 - tempQuestion = replacedQuestion; - - } else if (questionDTO.getDisplayOrder().equals(new Integer(replacedQuestionIndex).toString())) { - // move type 1 - tempQuestion = mainQuestion; - } - - newQuestionDtos.add(tempQuestion); - } - - // references in conditions also need to be changed - if (conditions != null) { - for (QaCondition condition : conditions) { - SortedSet newQuestionDTOSet = new TreeSet<>(new QaQuestionContentDTOComparator()); - for (QaQuestionDTO dto : newQuestionDtos) { - if (condition.temporaryQuestionDTOSet.contains(dto)) { - newQuestionDTOSet.add(dto); - } - } - condition.temporaryQuestionDTOSet = newQuestionDTOSet; - } - } - - return newQuestionDtos; - } - - private static QaQuestionDTO getQuestionAtDisplayOrder(List questionDTOs, - int intOriginalQuestionIndex) { - - Iterator iter = questionDTOs.iterator(); - while (iter.hasNext()) { - QaQuestionDTO qaQuestionDTO = iter.next(); - if (new Integer(intOriginalQuestionIndex).toString().equals(qaQuestionDTO.getDisplayOrder())) { - return qaQuestionDTO; - } - } - return null; - } - - private static List reorderQuestionDTOs(List questionDTOs) { - List listFinalQuestionDTO = new LinkedList<>(); - - int queIndex = 0; - Iterator iter = questionDTOs.iterator(); - while (iter.hasNext()) { - QaQuestionDTO qaQuestionDTO = iter.next(); - - String question = qaQuestionDTO.getQuestion(); - String feedback = qaQuestionDTO.getFeedback(); - boolean required = qaQuestionDTO.isRequired(); - int minWordsLimit = qaQuestionDTO.getMinWordsLimit(); - - if (question != null && !question.equals("")) { - ++queIndex; - - qaQuestionDTO.setQuestion(question); - qaQuestionDTO.setDisplayOrder(new Integer(queIndex).toString()); - qaQuestionDTO.setFeedback(feedback); - qaQuestionDTO.setRequired(required); - qaQuestionDTO.setMinWordsLimit(minWordsLimit); - - listFinalQuestionDTO.add(qaQuestionDTO); - } - } - return listFinalQuestionDTO; - } - - /** - * Get the deleted condition list, which could be persisted or non-persisted - * items. - * - * @param request - * @return - */ - private List getDeletedQaConditionList(SessionMap sessionMap) { - List list = (List) sessionMap.get(QaAppConstants.ATTR_DELETED_CONDITION_LIST); - if (list == null) { - list = new ArrayList<>(); - sessionMap.put(QaAppConstants.ATTR_DELETED_CONDITION_LIST, list); - } - return list; - } -} +/**************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * License Information: http://lamsfoundation.org/licensing/lams/2.0/ + * + * This program 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. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * http://www.gnu.org/licenses/gpl.txt + * **************************************************************** + */ + +package org.lamsfoundation.lams.tool.qa.web.controller; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.apache.log4j.Logger; +import org.lamsfoundation.lams.learningdesign.TextSearchConditionComparator; +import org.lamsfoundation.lams.qb.model.QbQuestion; +import org.lamsfoundation.lams.qb.service.IQbService; +import org.lamsfoundation.lams.rating.model.RatingCriteria; +import org.lamsfoundation.lams.tool.ToolAccessMode; +import org.lamsfoundation.lams.tool.qa.QaAppConstants; +import org.lamsfoundation.lams.tool.qa.dto.QaQuestionDTO; +import org.lamsfoundation.lams.tool.qa.model.QaCondition; +import org.lamsfoundation.lams.tool.qa.model.QaContent; +import org.lamsfoundation.lams.tool.qa.model.QaQueContent; +import org.lamsfoundation.lams.tool.qa.service.IQaService; +import org.lamsfoundation.lams.tool.qa.util.AuthoringUtil; +import org.lamsfoundation.lams.tool.qa.util.QaApplicationException; +import org.lamsfoundation.lams.tool.qa.util.QaQueContentComparator; +import org.lamsfoundation.lams.tool.qa.util.QaQuestionContentDTOComparator; +import org.lamsfoundation.lams.tool.qa.util.QaUtils; +import org.lamsfoundation.lams.tool.qa.web.form.QaAuthoringForm; +import org.lamsfoundation.lams.usermanagement.dto.UserDTO; +import org.lamsfoundation.lams.util.CommonConstants; +import org.lamsfoundation.lams.util.MessageService; +import org.lamsfoundation.lams.util.WebUtil; +import org.lamsfoundation.lams.web.session.SessionManager; +import org.lamsfoundation.lams.web.util.AttributeNames; +import org.lamsfoundation.lams.web.util.SessionMap; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Controller; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; + +/** + * Q&A Tool's authoring methods. Additionally, there is one more method that initializes authoring and it's located in + * QaStarterAction.java. + * + * @author Ozgur Demirtas + */ +@Controller +@RequestMapping("/authoring") +public class QaAuthoringController implements QaAppConstants { + private static Logger logger = Logger.getLogger(QaAuthoringController.class.getName()); + + @Autowired + private IQaService qaService; + + @Autowired + private IQbService qbService; + + @Autowired + @Qualifier("qaMessageService") + private MessageService messageService; + + @RequestMapping("") + public String unspecified() { + return "authoring/AuthoringTabsHolder"; + } + + @RequestMapping("/authoring") + public String execute(@ModelAttribute("authoringForm") QaAuthoringForm authoringForm, HttpServletRequest request) + throws IOException, ServletException, QaApplicationException { + + QaUtils.cleanUpSessionAbsolute(request); + + String contentFolderID = WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID); + authoringForm.setContentFolderID(contentFolderID); + + authoringForm.resetRadioBoxes(); + + validateDefaultContent(request, authoringForm); + + String strToolContentID = request.getParameter(AttributeNames.PARAM_TOOL_CONTENT_ID); + authoringForm.setToolContentID(strToolContentID); + + SessionMap sessionMap = new SessionMap<>(); + sessionMap.put(QaAppConstants.ACTIVITY_TITLE_KEY, ""); + sessionMap.put(QaAppConstants.ACTIVITY_INSTRUCTIONS_KEY, ""); + sessionMap.put(AttributeNames.PARAM_CONTENT_FOLDER_ID, contentFolderID); + sessionMap.put(AttributeNames.PARAM_TOOL_CONTENT_ID, strToolContentID); + authoringForm.setHttpSessionID(sessionMap.getSessionID()); + + if (strToolContentID == null || strToolContentID.equals("")) { + QaUtils.cleanUpSessionAbsolute(request); + throw new ServletException("No Tool Content ID found"); + } + + QaContent qaContent = qaService.getQaContent(new Long(strToolContentID).longValue()); + if (qaContent == null) { + /* fetch default content */ + long defaultContentID = qaService.getToolDefaultContentIdBySignature(QaAppConstants.MY_SIGNATURE); + qaContent = qaService.getQaContent(defaultContentID); + qaContent = QaContent.newInstance(qaContent, new Long(strToolContentID)); + } + + prepareDTOandForm(request, authoringForm, qaContent, qaService, sessionMap); + + ToolAccessMode mode = WebUtil.readToolAccessModeAuthorDefaulted(request); + // request is from monitoring module + if (mode.isTeacher()) { + qaService.setDefineLater(strToolContentID, true); + } + request.setAttribute(AttributeNames.ATTR_MODE, mode.toString()); + + SortedSet conditionList = getQaConditionList(sessionMap); + conditionList.clear(); + conditionList.addAll(qaContent.getConditions()); + + authoringForm.setAllowRichEditor(qaContent.isAllowRichEditor()); + authoringForm.setUseSelectLeaderToolOuput(qaContent.isUseSelectLeaderToolOuput()); + + sessionMap.put(QaAppConstants.ATTR_QA_AUTHORING_FORM, authoringForm); + request.getSession().setAttribute(sessionMap.getSessionID(), sessionMap); + + // get rating criterias from DB + List ratingCriterias = qaService.getRatingCriterias(qaContent.getQaContentId()); + sessionMap.put(AttributeNames.ATTR_RATING_CRITERIAS, ratingCriterias); + + return "authoring/AuthoringTabsHolder"; + } + + /** + * retrives the existing content information from the db and prepares the data for presentation purposes. + * + * @param request + * @param mapping + * @param authoringForm + * @param mapQuestionContent + * @param toolContentID + * @return ActionForward + */ + protected QaContent prepareDTOandForm(HttpServletRequest request, + @ModelAttribute("authoringForm") QaAuthoringForm authoringForm, QaContent qaContent, IQaService qaService, + SessionMap sessionMap) { + + authoringForm.setUsernameVisible(qaContent.isUsernameVisible() ? "1" : "0"); + authoringForm.setAllowRateAnswers(qaContent.isAllowRateAnswers() ? "1" : "0"); + authoringForm.setNotifyTeachersOnResponseSubmit(qaContent.isNotifyTeachersOnResponseSubmit() ? "1" : "0"); + authoringForm.setShowOtherAnswers(qaContent.isShowOtherAnswers() ? "1" : "0"); + authoringForm.setQuestionsSequenced(qaContent.isQuestionsSequenced() ? "1" : "0"); + authoringForm.setLockWhenFinished(qaContent.isLockWhenFinished() ? "1" : "0"); + authoringForm.setNoReeditAllowed(qaContent.isNoReeditAllowed() ? "1" : "0"); + authoringForm.setMaximumRates(qaContent.getMaximumRates()); + authoringForm.setMinimumRates(qaContent.getMinimumRates()); + authoringForm.setReflect(qaContent.isReflect() ? "1" : "0"); + authoringForm.setReflectionSubject(qaContent.getReflectionSubject()); + authoringForm.setTitle(qaContent.getTitle()); + authoringForm.setInstructions(qaContent.getInstructions()); + authoringForm.setUseSelectLeaderToolOuput(qaContent.isUseSelectLeaderToolOuput()); + authoringForm.setAllowRichEditor(qaContent.isAllowRichEditor()); + sessionMap.put(QaAppConstants.ACTIVITY_TITLE_KEY, qaContent.getTitle()); + sessionMap.put(QaAppConstants.ACTIVITY_INSTRUCTIONS_KEY, qaContent.getInstructions()); + + List questionDTOs = new LinkedList<>(); + + /* + * get the existing question content + */ + Iterator queIterator = qaContent.getQaQueContents().iterator(); + while (queIterator.hasNext()) { + + QaQueContent qaQuestion = (QaQueContent) queIterator.next(); + if (qaQuestion != null) { + QaQuestionDTO qaQuestionDTO = new QaQuestionDTO(qaQuestion); + questionDTOs.add(qaQuestionDTO); + } + } + + request.setAttribute(QaAppConstants.TOTAL_QUESTION_COUNT, new Integer(questionDTOs.size())); + request.setAttribute(QaAppConstants.LIST_QUESTION_DTOS, questionDTOs); + sessionMap.put(QaAppConstants.LIST_QUESTION_DTOS, questionDTOs); + + SortedSet conditionSet = new TreeSet<>(new TextSearchConditionComparator()); + for (QaCondition condition : qaContent.getConditions()) { + conditionSet.add(condition); + for (QaQuestionDTO dto : questionDTOs) { + for (QaQueContent question : condition.getQuestions()) { + if (dto.getDisplayOrder().equals(String.valueOf(question.getDisplayOrder()))) { + condition.temporaryQuestionDTOSet.add(dto); + } + } + } + } + sessionMap.put(QaAppConstants.ATTR_CONDITION_SET, conditionSet); + + List listDeletedQuestionDTOs = new ArrayList<>(); + sessionMap.put(QaAppConstants.LIST_DELETED_QUESTION_DTOS, listDeletedQuestionDTOs); + + authoringForm.resetUserAction(); + + return qaContent; + } + + /** + * each tool has a signature. QA tool's signature is stored in MY_SIGNATURE. + * The default tool content id and other depending content ids are obtained + * in this method. if all the default content has been setup properly the + * method persists DEFAULT_CONTENT_ID in the session. + * + * @param request + * @param mapping + * @return ActionForward + */ + public boolean validateDefaultContent(HttpServletRequest request, + @ModelAttribute("authoringForm") QaAuthoringForm authoringForm) { + + /* + * retrieve the default content id based on tool signature + */ + long defaultContentID = 0; + try { + defaultContentID = qaService.getToolDefaultContentIdBySignature(QaAppConstants.MY_SIGNATURE); + if (defaultContentID == 0) { + QaAuthoringController.logger.debug("default content id has not been setup"); + return false; + } + } catch (Exception e) { + QaAuthoringController.logger.error("error getting the default content id: " + e.getMessage()); + persistError(request, "error.defaultContent.notSetup"); + return false; + } + + /* + * retrieve uid of the content based on default content id determined above + */ + try { + //retrieve uid of the content based on default content id determined above + QaContent qaContent = qaService.getQaContent(defaultContentID); + if (qaContent == null) { + QaAuthoringController.logger.error("Exception occured: No default content"); + persistError(request, "error.defaultContent.notSetup"); + return false; + } + + } catch (Exception e) { + QaAuthoringController.logger.error("Exception occured: No default question content"); + persistError(request, "error.defaultContent.notSetup"); + return false; + } + + return true; + } + + /** + * persists error messages to request scope + * + * @param request + * @param message + */ + public void persistError(HttpServletRequest request, String message) { + MultiValueMap errorMap = new LinkedMultiValueMap<>(); + errorMap.add("GLOBAL", messageService.getMessage(message)); + request.setAttribute("errorMap", errorMap); + } + + private SortedSet getQaConditionList(SessionMap sessionMap) { + SortedSet list = (SortedSet) sessionMap.get(QaAppConstants.ATTR_CONDITION_SET); + if (list == null) { + list = new TreeSet<>(new TextSearchConditionComparator()); + sessionMap.put(QaAppConstants.ATTR_CONDITION_SET, list); + } + return list; + } + + /** + * submits content into the tool database + */ + @RequestMapping("/submitAllContent") + public String submitAllContent(@ModelAttribute("authoringForm") QaAuthoringForm authoringForm, + HttpServletRequest request) throws IOException, ServletException { + + String httpSessionID = authoringForm.getHttpSessionID(); + SessionMap sessionMap = (SessionMap) request.getSession() + .getAttribute(httpSessionID); + + String contentFolderID = WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID); + authoringForm.setContentFolderID(contentFolderID); + + String strToolContentID = request.getParameter(AttributeNames.PARAM_TOOL_CONTENT_ID); + Long toolContentID = new Long(strToolContentID); + + List questionDTOs = (List) sessionMap.get(QaAppConstants.LIST_QUESTION_DTOS); + + MultiValueMap errorMap = new LinkedMultiValueMap<>(); + if (questionDTOs.size() == 0) { + errorMap.add("GLOBAL", messageService.getMessage("questions.none.submitted")); + } + + String richTextTitle = request.getParameter(QaAppConstants.TITLE); + String richTextInstructions = request.getParameter(QaAppConstants.INSTRUCTIONS); + + authoringForm.setTitle(richTextTitle); + authoringForm.setInstructions(richTextInstructions); + + sessionMap.put(QaAppConstants.ACTIVITY_TITLE_KEY, richTextTitle); + sessionMap.put(QaAppConstants.ACTIVITY_INSTRUCTIONS_KEY, richTextInstructions); + + if (!errorMap.isEmpty()) { + request.setAttribute("errorMap", errorMap); + QaAuthoringController.logger.debug("errors saved: " + errorMap); + } + + QaContent qaContent = qaService.getQaContent(toolContentID); + if (errorMap.isEmpty()) { + ToolAccessMode mode = WebUtil.readToolAccessModeAuthorDefaulted(request); + request.setAttribute(AttributeNames.ATTR_MODE, mode.toString()); + + List deletedQuestionDTOs = (List) sessionMap.get(LIST_DELETED_QUESTION_DTOS); + + // in case request is from monitoring module - recalculate User Answers + if (mode.isTeacher()) { + Set oldQuestions = qaContent.getQaQueContents(); + qaService.removeQuestionsFromCache(qaContent); + qaService.setDefineLater(strToolContentID, false); + + // audit log the teacher has started editing activity in monitor + qaService.auditLogStartEditingActivityInMonitor(toolContentID); + + // recalculate User Answers + qaService.recalculateUserAnswers(qaContent, oldQuestions, questionDTOs, deletedQuestionDTOs); + } + + // remove deleted questions + for (QaQuestionDTO deletedQuestionDTO : deletedQuestionDTOs) { + QaQueContent removeableQuestion = qaService.getQuestionByUid(deletedQuestionDTO.getUid()); + if (removeableQuestion != null) { + qaContent.getQaQueContents().remove(removeableQuestion); + qaService.removeQuestion(removeableQuestion); + } + } + + // store content + SortedSet conditionSet = (SortedSet) sessionMap + .get(QaAppConstants.ATTR_CONDITION_SET); + qaContent = saveOrUpdateQaContent(questionDTOs, request, qaContent, toolContentID, conditionSet); + + //reOrganizeDisplayOrder + List sortedQuestions = qaService.getAllQuestionEntriesSorted(qaContent.getUid().longValue()); + Iterator iter = sortedQuestions.iterator(); + int displayOrder = 1; + while (iter.hasNext()) { + QaQueContent question = iter.next(); + + QaQueContent existingQaQueContent = qaService.getQuestionByUid(question.getUid()); + existingQaQueContent.setDisplayOrder(displayOrder); + qaService.saveOrUpdate(existingQaQueContent); + displayOrder++; + } + + // ************************* Handle rating criterias ******************* + List oldCriterias = (List) sessionMap + .get(AttributeNames.ATTR_RATING_CRITERIAS); + qaService.saveRatingCriterias(request, oldCriterias, toolContentID); + + QaUtils.setFormProperties(request, authoringForm, strToolContentID, httpSessionID); + + request.setAttribute(CommonConstants.LAMS_AUTHORING_SUCCESS_FLAG, Boolean.TRUE); + + } else { + if (qaContent != null) { + QaUtils.setFormProperties(request, authoringForm, strToolContentID, httpSessionID); + } + } + + List delConditionList = getDeletedQaConditionList(sessionMap); + Iterator iter = delConditionList.iterator(); + while (iter.hasNext()) { + QaCondition condition = iter.next(); + iter.remove(); + qaService.deleteCondition(condition); + } + + authoringForm.resetUserAction(); + authoringForm.setToolContentID(strToolContentID); + authoringForm.setHttpSessionID(httpSessionID); + authoringForm.setCurrentTab("1"); + + request.setAttribute(QaAppConstants.LIST_QUESTION_DTOS, questionDTOs); + request.getSession().setAttribute(httpSessionID, sessionMap); + request.setAttribute(QaAppConstants.TOTAL_QUESTION_COUNT, new Integer(questionDTOs.size())); + sessionMap.put(QaAppConstants.LIST_QUESTION_DTOS, questionDTOs); + + return "authoring/AuthoringTabsHolder"; + } + + private QaContent saveOrUpdateQaContent(List questionDTOs, HttpServletRequest request, + QaContent qaContent, Long toolContentId, Set conditions) { + UserDTO toolUser = (UserDTO) SessionManager.getSession().getAttribute(AttributeNames.USER); + + String richTextTitle = request.getParameter(QaAppConstants.TITLE); + String richTextInstructions = request.getParameter(QaAppConstants.INSTRUCTIONS); + String usernameVisible = request.getParameter(QaAppConstants.USERNAME_VISIBLE); + String allowRateQuestions = request.getParameter(QaAppConstants.ALLOW_RATE_ANSWERS); + String notifyTeachersOnResponseSubmit = request.getParameter(QaAppConstants.NOTIFY_TEACHERS_ON_RESPONSE_SUBMIT); + String showOtherAnswers = request.getParameter("showOtherAnswers"); + String questionsSequenced = request.getParameter(QaAppConstants.QUESTIONS_SEQUENCED); + String lockWhenFinished = request.getParameter("lockWhenFinished"); + String noReeditAllowed = request.getParameter("noReeditAllowed"); + String allowRichEditor = request.getParameter("allowRichEditor"); + String useSelectLeaderToolOuput = request.getParameter("useSelectLeaderToolOuput"); + String reflect = request.getParameter(QaAppConstants.REFLECT); + String reflectionSubject = request.getParameter(QaAppConstants.REFLECTION_SUBJECT); + int minimumRates = WebUtil.readIntParam(request, "minimumRates"); + int maximumRates = WebUtil.readIntParam(request, "maximumRates"); + + boolean questionsSequencedBoolean = false; + boolean lockWhenFinishedBoolean = false; + boolean noReeditAllowedBoolean = false; + boolean usernameVisibleBoolean = false; + boolean allowRateQuestionsBoolean = false; + boolean notifyTeachersOnResponseSubmitBoolean = false; + boolean showOtherAnswersBoolean = false; + boolean reflectBoolean = false; + boolean allowRichEditorBoolean = false; + boolean useSelectLeaderToolOuputBoolean = false; + + if (questionsSequenced != null && questionsSequenced.equalsIgnoreCase("1")) { + questionsSequencedBoolean = true; + } + + if (lockWhenFinished != null && lockWhenFinished.equalsIgnoreCase("1")) { + lockWhenFinishedBoolean = true; + } + + if (noReeditAllowed != null && noReeditAllowed.equalsIgnoreCase("1")) { + noReeditAllowedBoolean = true; + lockWhenFinishedBoolean = true; + } + + if (usernameVisible != null && usernameVisible.equalsIgnoreCase("1")) { + usernameVisibleBoolean = true; + } + + if (showOtherAnswers != null && showOtherAnswers.equalsIgnoreCase("1")) { + showOtherAnswersBoolean = true; + } + + if (allowRateQuestions != null && allowRateQuestions.equalsIgnoreCase("1") && showOtherAnswersBoolean) { + allowRateQuestionsBoolean = true; + } + + if (notifyTeachersOnResponseSubmit != null && notifyTeachersOnResponseSubmit.equalsIgnoreCase("1")) { + notifyTeachersOnResponseSubmitBoolean = true; + } + + if (allowRichEditor != null && allowRichEditor.equalsIgnoreCase("true")) { + allowRichEditorBoolean = true; + } + + if (useSelectLeaderToolOuput != null && useSelectLeaderToolOuput.equalsIgnoreCase("true")) { + useSelectLeaderToolOuputBoolean = true; + } + + if (reflect != null && reflect.equalsIgnoreCase("1")) { + reflectBoolean = true; + } + long userId = 0; + if (toolUser != null) { + userId = toolUser.getUserID().longValue(); + } else { + HttpSession ss = SessionManager.getSession(); + UserDTO user = (UserDTO) ss.getAttribute(AttributeNames.USER); + if (user != null) { + userId = user.getUserID().longValue(); + } else { + userId = 0; + } + } + + boolean newContent = false; + if (qaContent == null) { + qaContent = new QaContent(); + newContent = true; + } + + qaContent.setQaContentId(toolContentId); + qaContent.setTitle(richTextTitle); + qaContent.setInstructions(richTextInstructions); + qaContent.setUpdateDate(new Date(System.currentTimeMillis())); + /** keep updating this one */ + qaContent.setCreatedBy(userId); + /** make sure we are setting the userId from the User object above */ + + qaContent.setUsernameVisible(usernameVisibleBoolean); + qaContent.setAllowRateAnswers(allowRateQuestionsBoolean); + qaContent.setNotifyTeachersOnResponseSubmit(notifyTeachersOnResponseSubmitBoolean); + qaContent.setShowOtherAnswers(showOtherAnswersBoolean); + qaContent.setQuestionsSequenced(questionsSequencedBoolean); + qaContent.setLockWhenFinished(lockWhenFinishedBoolean); + qaContent.setNoReeditAllowed(noReeditAllowedBoolean); + qaContent.setReflect(reflectBoolean); + qaContent.setReflectionSubject(reflectionSubject); + qaContent.setAllowRichEditor(allowRichEditorBoolean); + qaContent.setUseSelectLeaderToolOuput(useSelectLeaderToolOuputBoolean); + qaContent.setMinimumRates(minimumRates); + qaContent.setMaximumRates(maximumRates); + + qaContent.setConditions(new TreeSet(new TextSearchConditionComparator())); + if (newContent) { + qaService.createQaContent(qaContent); + } else { + qaService.updateQaContent(qaContent); + } + + qaContent = qaService.getQaContent(toolContentId); + + // persist questions + int displayOrder = 0; + for (QaQuestionDTO questionDTO : questionDTOs) { + + String questionText = questionDTO.getQuestion(); + + // skip empty questions + if (questionText.isEmpty()) { + continue; + } + + ++displayOrder; + + QaQueContent question = qaService.getQuestionByUid(questionDTO.getUid()); + + // in case question doesn't exist + if (question == null) { + QbQuestion qbQuestion = new QbQuestion(); + qbQuestion.setType(QbQuestion.TYPE_ESSAY); + qbQuestion.setQuestionId(qbService.generateNextQuestionId()); + qbQuestion.setVersion(1); + + qbQuestion.setName(questionText); + qbQuestion.setFeedback(questionDTO.getFeedback()); + qbQuestion.setAnswerRequired(questionDTO.isRequired()); + qbQuestion.setMinWordsLimit(questionDTO.getMinWordsLimit()); + + qaService.saveOrUpdate(qbQuestion); + + question = new QaQueContent(qbQuestion, displayOrder, qaContent); + qaContent.getQaQueContents().add(question); + question.setQaContent(qaContent); + + // in case question exists already + } else { + QbQuestion qbQuestion = question.getQbQuestion(); + qbQuestion.setName(questionText); + qbQuestion.setFeedback(questionDTO.getFeedback()); + qbQuestion.setAnswerRequired(questionDTO.isRequired()); + qbQuestion.setMinWordsLimit(questionDTO.getMinWordsLimit()); + } + + qaService.saveOrUpdate(question); + } + + for (QaCondition condition : conditions) { + condition.setQuestions(new TreeSet<>(new QaQueContentComparator())); + for (QaQuestionDTO dto : condition.temporaryQuestionDTOSet) { + for (QaQueContent queContent : qaContent.getQaQueContents()) { + if (dto.getDisplayOrder().equals(String.valueOf(queContent.getDisplayOrder()))) { + condition.getQuestions().add(queContent); + } + } + } + } + qaContent.setConditions(conditions); + qaService.updateQaContent(qaContent); + + return qaContent; + } + + /** + * Adds QbQuestion, selected in the question bank, to the current question list. + */ + @SuppressWarnings("unchecked") + @RequestMapping(value = "/importQbQuestion", method = RequestMethod.POST) + private String importQbQuestion(@ModelAttribute("newQuestionForm") QaAuthoringForm authoringForm, + HttpServletRequest request, @RequestParam String httpSessionID, @RequestParam Long qbQuestionUid) { + SessionMap sessionMap = (SessionMap) request.getSession() + .getAttribute(httpSessionID); + + //get QbQuestion from DB + QbQuestion qbQuestion = qbService.getQuestionByUid(qbQuestionUid); + + List questionDTOs = (List) sessionMap.get(QaAppConstants.LIST_QUESTION_DTOS); + boolean duplicates = AuthoringUtil.checkDuplicateQuestions(questionDTOs, qbQuestion.getName()); + if (!duplicates) { + String displayOrder = String.valueOf(questionDTOs.size() + 1); + boolean requiredBoolean = false; + int minWordsLimit = 0; + QaQuestionDTO qaQuestionDTO = new QaQuestionDTO(qbQuestion.getName(), displayOrder, + qbQuestion.getFeedback(), requiredBoolean, minWordsLimit); + questionDTOs.add(qaQuestionDTO); + } else { + //entry duplicate, not adding + } + + request.setAttribute(QaAppConstants.LIST_QUESTION_DTOS, questionDTOs); + sessionMap.put(QaAppConstants.LIST_QUESTION_DTOS, questionDTOs); + + String contentFolderID = (String) sessionMap.get(AttributeNames.PARAM_CONTENT_FOLDER_ID); + String toolContentID = (String) sessionMap.get(AttributeNames.PARAM_TOOL_CONTENT_ID); + authoringForm.setContentFolderID(contentFolderID); + authoringForm.setHttpSessionID(httpSessionID); + authoringForm.setToolContentID(toolContentID); + request.setAttribute("authoringForm", authoringForm); + return "authoring/itemlist"; + } + + /** + * saveSingleQuestion + */ + @RequestMapping("/saveSingleQuestion") + public String saveSingleQuestion(@ModelAttribute("newQuestionForm") QaAuthoringForm newQuestionForm, + HttpServletRequest request) throws IOException, ServletException { + + String httpSessionID = newQuestionForm.getHttpSessionID(); + + SessionMap sessionMap = (SessionMap) request.getSession() + .getAttribute(httpSessionID); + + String contentFolderID = WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID); + newQuestionForm.setContentFolderID(contentFolderID); + + String strToolContentID = request.getParameter(AttributeNames.PARAM_TOOL_CONTENT_ID); + + String editQuestionBoxRequest = request.getParameter("editQuestionBoxRequest"); + + List questionDTOs = (List) sessionMap.get(QaAppConstants.LIST_QUESTION_DTOS); + + String newQuestion = request.getParameter("newQuestion"); + + String feedback = request.getParameter("feedback"); + + String editableQuestionIndex = request.getParameter("editableQuestionIndex"); + + boolean requiredBoolean = newQuestionForm.isRequired(); + + int minWordsLimit = WebUtil.readIntParam(request, "minWordsLimit"); + + if (newQuestion != null && newQuestion.length() > 0) { + if (editQuestionBoxRequest != null && editQuestionBoxRequest.equals("false")) { + //request for add and save + boolean duplicates = AuthoringUtil.checkDuplicateQuestions(questionDTOs, newQuestion); + + if (!duplicates) { + QaQuestionDTO qaQuestionDTO = null; + Iterator iter = questionDTOs.iterator(); + while (iter.hasNext()) { + qaQuestionDTO = iter.next(); + + String displayOrder = qaQuestionDTO.getDisplayOrder(); + if (displayOrder != null && !displayOrder.equals("")) { + if (displayOrder.equals(editableQuestionIndex)) { + break; + } + + } + } + + qaQuestionDTO.setQuestion(newQuestion); + qaQuestionDTO.setFeedback(feedback); + qaQuestionDTO.setDisplayOrder(editableQuestionIndex); + qaQuestionDTO.setRequired(requiredBoolean); + qaQuestionDTO.setMinWordsLimit(minWordsLimit); + + questionDTOs = AuthoringUtil.reorderUpdateQuestionDTOs(questionDTOs, qaQuestionDTO, + editableQuestionIndex); + } else { + //duplicate question entry, not adding + } + } else { + //request for edit and save + QaQuestionDTO qaQuestionDTO = null; + Iterator iter = questionDTOs.iterator(); + while (iter.hasNext()) { + qaQuestionDTO = iter.next(); + + String displayOrder = qaQuestionDTO.getDisplayOrder(); + + if (displayOrder != null && !displayOrder.equals("")) { + if (displayOrder.equals(editableQuestionIndex)) { + break; + } + + } + } + + qaQuestionDTO.setQuestion(newQuestion); + qaQuestionDTO.setFeedback(feedback); + qaQuestionDTO.setDisplayOrder(editableQuestionIndex); + qaQuestionDTO.setRequired(requiredBoolean); + qaQuestionDTO.setMinWordsLimit(minWordsLimit); + + questionDTOs = AuthoringUtil.reorderUpdateQuestionDTOs(questionDTOs, qaQuestionDTO, + editableQuestionIndex); + } + } else { + //entry blank, not adding + } + + request.setAttribute(QaAppConstants.LIST_QUESTION_DTOS, questionDTOs); + sessionMap.put(QaAppConstants.LIST_QUESTION_DTOS, questionDTOs); + + String richTextTitle = request.getParameter(QaAppConstants.TITLE); + String richTextInstructions = request.getParameter(QaAppConstants.INSTRUCTIONS); + + newQuestionForm.setTitle(richTextTitle); + newQuestionForm.setInstructions(richTextInstructions); + + sessionMap.put(QaAppConstants.ACTIVITY_TITLE_KEY, richTextTitle); + sessionMap.put(QaAppConstants.ACTIVITY_INSTRUCTIONS_KEY, richTextInstructions); + + request.getSession().setAttribute(httpSessionID, sessionMap); + + QaUtils.setFormProperties(request, newQuestionForm, strToolContentID, httpSessionID); + + newQuestionForm.setToolContentID(strToolContentID); + newQuestionForm.setHttpSessionID(httpSessionID); + newQuestionForm.setCurrentTab("1"); + + request.getSession().setAttribute(httpSessionID, sessionMap); + request.setAttribute(QaAppConstants.TOTAL_QUESTION_COUNT, new Integer(questionDTOs.size())); + request.setAttribute("authoringForm", newQuestionForm); + + return "authoring/AuthoringTabsHolder"; + } + + /** + * addSingleQuestion + */ + @RequestMapping("/addSingleQuestion") + public String addSingleQuestion(@ModelAttribute("newQuestionForm") QaAuthoringForm newQuestionForm, + HttpServletRequest request) throws IOException, ServletException { + + String httpSessionID = newQuestionForm.getHttpSessionID(); + + SessionMap sessionMap = (SessionMap) request.getSession() + .getAttribute(httpSessionID); + + String contentFolderID = WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID); + newQuestionForm.setContentFolderID(contentFolderID); + + String strToolContentID = request.getParameter(AttributeNames.PARAM_TOOL_CONTENT_ID); + + List questionDTOs = (List) sessionMap.get(QaAppConstants.LIST_QUESTION_DTOS); + + String newQuestion = request.getParameter("newQuestion"); + String feedback = request.getParameter("feedback"); + boolean requiredBoolean = newQuestionForm.isRequired(); + int minWordsLimit = WebUtil.readIntParam(request, "minWordsLimit"); + + int listSize = questionDTOs.size(); + + if (newQuestion != null && newQuestion.length() > 0) { + boolean duplicates = AuthoringUtil.checkDuplicateQuestions(questionDTOs, newQuestion); + + if (!duplicates) { + QaQuestionDTO qaQuestionDTO = new QaQuestionDTO(newQuestion, new Long(listSize + 1).toString(), + feedback, requiredBoolean, minWordsLimit); + questionDTOs.add(qaQuestionDTO); + } else { + //entry duplicate, not adding + } + } else { + //entry blank, not adding + } + + request.setAttribute(QaAppConstants.LIST_QUESTION_DTOS, questionDTOs); + sessionMap.put(QaAppConstants.LIST_QUESTION_DTOS, questionDTOs); + + String richTextTitle = request.getParameter(QaAppConstants.TITLE); + String richTextInstructions = request.getParameter(QaAppConstants.INSTRUCTIONS); + + newQuestionForm.setTitle(richTextTitle); + newQuestionForm.setInstructions(richTextInstructions); + + sessionMap.put(QaAppConstants.ACTIVITY_TITLE_KEY, richTextTitle); + sessionMap.put(QaAppConstants.ACTIVITY_INSTRUCTIONS_KEY, richTextInstructions); + + request.getSession().setAttribute(httpSessionID, sessionMap); + + QaUtils.setFormProperties(request, newQuestionForm, strToolContentID, httpSessionID); + + newQuestionForm.setToolContentID(strToolContentID); + newQuestionForm.setHttpSessionID(httpSessionID); + newQuestionForm.setCurrentTab("1"); + + request.getSession().setAttribute(httpSessionID, sessionMap); + request.setAttribute(QaAppConstants.TOTAL_QUESTION_COUNT, new Integer(questionDTOs.size())); + request.setAttribute("authoringForm", newQuestionForm); + return "authoring/AuthoringTabsHolder"; + } + + /** + * opens up an new screen within the current page for adding a new question + */ + @RequestMapping("/newQuestionBox") + public String newQuestionBox(@ModelAttribute("newQuestionForm") QaAuthoringForm newQuestionForm, + HttpServletRequest request) throws IOException, ServletException { + + String httpSessionID = newQuestionForm.getHttpSessionID(); + + SessionMap sessionMap = (SessionMap) request.getSession() + .getAttribute(httpSessionID); + + String contentFolderID = WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID); + + newQuestionForm.setContentFolderID(contentFolderID); + + String strToolContentID = request.getParameter(AttributeNames.PARAM_TOOL_CONTENT_ID); + + String richTextTitle = request.getParameter(QaAppConstants.TITLE); + + String richTextInstructions = request.getParameter(QaAppConstants.INSTRUCTIONS); + + newQuestionForm.setTitle(richTextTitle); + newQuestionForm.setInstructions(richTextInstructions); + + QaUtils.setFormProperties(request, newQuestionForm, strToolContentID, httpSessionID); + + Collection questionDTOs = (Collection) sessionMap + .get(QaAppConstants.LIST_QUESTION_DTOS); + request.setAttribute(QaAppConstants.TOTAL_QUESTION_COUNT, new Integer(questionDTOs.size())); + request.setAttribute("authoringForm", newQuestionForm); + + return "authoring/newQuestionBox"; + } + + /** + * opens up an new screen within the current page for editing a question + */ + @RequestMapping("/newEditableQuestionBox") + public String newEditableQuestionBox(@ModelAttribute("newQuestionForm") QaAuthoringForm newQuestionForm, + HttpServletRequest request) throws IOException, ServletException { + + String httpSessionID = newQuestionForm.getHttpSessionID(); + + SessionMap sessionMap = (SessionMap) request.getSession() + .getAttribute(httpSessionID); + + String questionIndex = request.getParameter("questionIndex"); + + newQuestionForm.setEditableQuestionIndex(questionIndex); + + List questionDTOs = (List) sessionMap.get(QaAppConstants.LIST_QUESTION_DTOS); + + String editableQuestion = ""; + String editableFeedback = ""; + boolean requiredBoolean = false; + int minWordsLimit = 0; + Iterator iter = questionDTOs.iterator(); + while (iter.hasNext()) { + QaQuestionDTO qaQuestionDTO = iter.next(); + String displayOrder = qaQuestionDTO.getDisplayOrder(); + + if (displayOrder != null && !displayOrder.equals("")) { + if (displayOrder.equals(questionIndex)) { + editableFeedback = qaQuestionDTO.getFeedback(); + editableQuestion = qaQuestionDTO.getQuestion(); + requiredBoolean = qaQuestionDTO.isRequired(); + minWordsLimit = qaQuestionDTO.getMinWordsLimit(); + break; + } + + } + } + + String contentFolderID = WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID); + newQuestionForm.setContentFolderID(contentFolderID); + + String strToolContentID = request.getParameter(AttributeNames.PARAM_TOOL_CONTENT_ID); + + String richTextTitle = request.getParameter(QaAppConstants.TITLE); + String richTextInstructions = request.getParameter(QaAppConstants.INSTRUCTIONS); + + newQuestionForm.setTitle(richTextTitle); + newQuestionForm.setInstructions(richTextInstructions); + + QaUtils.setFormProperties(request, newQuestionForm, strToolContentID, httpSessionID); + + newQuestionForm.setRequired(requiredBoolean); + newQuestionForm.setMinWordsLimit(minWordsLimit); + newQuestionForm.setEditableQuestionText(editableQuestion); + newQuestionForm.setFeedback(editableFeedback); + + request.setAttribute(QaAppConstants.TOTAL_QUESTION_COUNT, new Integer(questionDTOs.size())); + request.setAttribute("authoringForm", newQuestionForm); + + return "authoring/newQuestionBox"; + } + + /** + * removes a question from the questions map + */ + @RequestMapping("/removeQuestion") + public String removeQuestion(@ModelAttribute("newQuestionForm") QaAuthoringForm newQuestionForm, + HttpServletRequest request) throws IOException, ServletException { + + String httpSessionID = newQuestionForm.getHttpSessionID(); + SessionMap sessionMap = (SessionMap) request.getSession() + .getAttribute(httpSessionID); + + String questionIndexToDelete = request.getParameter("questionIndex"); + QaQuestionDTO questionToDelete = null; + List questionDTOs = (List) sessionMap.get(QaAppConstants.LIST_QUESTION_DTOS); + + List listFinalQuestionDTO = new LinkedList<>(); + int queIndex = 0; + for (QaQuestionDTO questionDTO : questionDTOs) { + + String questionText = questionDTO.getQuestion(); + String displayOrder = questionDTO.getDisplayOrder(); + + if (questionText != null && !questionText.equals("") && (!displayOrder.equals(questionIndexToDelete))) { + + ++queIndex; + questionDTO.setDisplayOrder(new Integer(queIndex).toString()); + listFinalQuestionDTO.add(questionDTO); + } + if ((questionText != null) && (!questionText.isEmpty()) && displayOrder.equals(questionIndexToDelete)) { + List deletedQuestionDTOs = (List) sessionMap + .get(LIST_DELETED_QUESTION_DTOS); + ; + deletedQuestionDTOs.add(questionDTO); + sessionMap.put(LIST_DELETED_QUESTION_DTOS, deletedQuestionDTOs); + questionToDelete = questionDTO; + } + } + request.setAttribute(QaAppConstants.LIST_QUESTION_DTOS, listFinalQuestionDTO); + sessionMap.put(QaAppConstants.LIST_QUESTION_DTOS, listFinalQuestionDTO); + request.setAttribute(QaAppConstants.TOTAL_QUESTION_COUNT, new Integer(listFinalQuestionDTO.size())); + + SortedSet conditions = (SortedSet) sessionMap.get(QaAppConstants.ATTR_CONDITION_SET); + Iterator conditionIter = conditions.iterator(); + while (conditionIter.hasNext()) { + QaCondition condition = conditionIter.next(); + Iterator dtoIter = condition.temporaryQuestionDTOSet.iterator(); + while (dtoIter.hasNext()) { + if (dtoIter.next() == questionToDelete) { + dtoIter.remove(); + } + } + if (condition.temporaryQuestionDTOSet.isEmpty()) { + conditionIter.remove(); + } + } + + String contentFolderID = WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID); + newQuestionForm.setContentFolderID(contentFolderID); + String richTextTitle = request.getParameter(QaAppConstants.TITLE); + String richTextInstructions = request.getParameter(QaAppConstants.INSTRUCTIONS); + sessionMap.put(QaAppConstants.ACTIVITY_TITLE_KEY, richTextTitle); + sessionMap.put(QaAppConstants.ACTIVITY_INSTRUCTIONS_KEY, richTextInstructions); + String strToolContentID = request.getParameter(AttributeNames.PARAM_TOOL_CONTENT_ID); + newQuestionForm.setTitle(richTextTitle); + newQuestionForm.setInstructions(richTextInstructions); + request.getSession().setAttribute(httpSessionID, sessionMap); + QaUtils.setFormProperties(request, newQuestionForm, strToolContentID, httpSessionID); + newQuestionForm.setToolContentID(strToolContentID); + newQuestionForm.setHttpSessionID(httpSessionID); + newQuestionForm.setCurrentTab("1"); + request.setAttribute("authoringForm", newQuestionForm); + + return "authoring/AuthoringTabsHolder"; + } + + /** + * moves a question down in the list + */ + @RequestMapping("/moveQuestionDown") + public String moveQuestionDown(@ModelAttribute("newQuestionForm") QaAuthoringForm newQuestionForm, + HttpServletRequest request) throws IOException, ServletException { + + String httpSessionID = newQuestionForm.getHttpSessionID(); + SessionMap sessionMap = (SessionMap) request.getSession() + .getAttribute(httpSessionID); + + String questionIndex = request.getParameter("questionIndex"); + + List questionDTOs = (List) sessionMap.get(QaAppConstants.LIST_QUESTION_DTOS); + + SortedSet conditionSet = (SortedSet) sessionMap + .get(QaAppConstants.ATTR_CONDITION_SET); + + questionDTOs = QaAuthoringController.swapQuestions(questionDTOs, questionIndex, "down", conditionSet); + + questionDTOs = QaAuthoringController.reorderQuestionDTOs(questionDTOs); + + sessionMap.put(QaAppConstants.LIST_QUESTION_DTOS, questionDTOs); + + String contentFolderID = WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID); + newQuestionForm.setContentFolderID(contentFolderID); + + String richTextTitle = request.getParameter(QaAppConstants.TITLE); + + String richTextInstructions = request.getParameter(QaAppConstants.INSTRUCTIONS); + + sessionMap.put(QaAppConstants.ACTIVITY_TITLE_KEY, richTextTitle); + sessionMap.put(QaAppConstants.ACTIVITY_INSTRUCTIONS_KEY, richTextInstructions); + + String strToolContentID = request.getParameter(AttributeNames.PARAM_TOOL_CONTENT_ID); + + newQuestionForm.setTitle(richTextTitle); + newQuestionForm.setInstructions(richTextInstructions); + request.getSession().setAttribute(httpSessionID, sessionMap); + + QaUtils.setFormProperties(request, newQuestionForm, strToolContentID, httpSessionID); + + newQuestionForm.setToolContentID(strToolContentID); + newQuestionForm.setHttpSessionID(httpSessionID); + newQuestionForm.setCurrentTab("1"); + + request.setAttribute(QaAppConstants.LIST_QUESTION_DTOS, questionDTOs); + + request.setAttribute(QaAppConstants.TOTAL_QUESTION_COUNT, new Integer(questionDTOs.size())); + request.setAttribute("authoringForm", newQuestionForm); + return "authoring/AuthoringTabsHolder"; + } + + /** + * moves a question up in the list + */ + @RequestMapping("/moveQuestionUp") + public String moveQuestionUp(@ModelAttribute("newQuestionForm") QaAuthoringForm newQuestionForm, + HttpServletRequest request) throws IOException, ServletException { + + String httpSessionID = newQuestionForm.getHttpSessionID(); + + SessionMap sessionMap = (SessionMap) request.getSession() + .getAttribute(httpSessionID); + + String questionIndex = request.getParameter("questionIndex"); + + List questionDTOs = (List) sessionMap.get(QaAppConstants.LIST_QUESTION_DTOS); + + SortedSet conditionSet = (SortedSet) sessionMap + .get(QaAppConstants.ATTR_CONDITION_SET); + questionDTOs = QaAuthoringController.swapQuestions(questionDTOs, questionIndex, "up", conditionSet); + + questionDTOs = QaAuthoringController.reorderQuestionDTOs(questionDTOs); + + sessionMap.put(QaAppConstants.LIST_QUESTION_DTOS, questionDTOs); + + String contentFolderID = WebUtil.readStrParam(request, AttributeNames.PARAM_CONTENT_FOLDER_ID); + + newQuestionForm.setContentFolderID(contentFolderID); + + String richTextTitle = request.getParameter(QaAppConstants.TITLE); + + String richTextInstructions = request.getParameter(QaAppConstants.INSTRUCTIONS); + + sessionMap.put(QaAppConstants.ACTIVITY_TITLE_KEY, richTextTitle); + sessionMap.put(QaAppConstants.ACTIVITY_INSTRUCTIONS_KEY, richTextInstructions); + + String strToolContentID = request.getParameter(AttributeNames.PARAM_TOOL_CONTENT_ID); + + newQuestionForm.setTitle(richTextTitle); + newQuestionForm.setInstructions(richTextInstructions); + + request.getSession().setAttribute(httpSessionID, sessionMap); + + QaUtils.setFormProperties(request, newQuestionForm, strToolContentID, httpSessionID); + + newQuestionForm.setToolContentID(strToolContentID); + newQuestionForm.setHttpSessionID(httpSessionID); + newQuestionForm.setCurrentTab("1"); + + request.setAttribute(QaAppConstants.LIST_QUESTION_DTOS, questionDTOs); + + request.setAttribute(QaAppConstants.TOTAL_QUESTION_COUNT, new Integer(questionDTOs.size())); + request.setAttribute("authoringForm", newQuestionForm); + return "authoring/AuthoringTabsHolder"; + } + + private static List swapQuestions(List questionDTOs, String questionIndex, + String direction, Set conditions) { + + int intQuestionIndex = new Integer(questionIndex).intValue(); + int intOriginalQuestionIndex = intQuestionIndex; + + int replacedQuestionIndex = 0; + if (direction.equals("down")) { + // direction down + replacedQuestionIndex = ++intQuestionIndex; + } else { + // direction up + replacedQuestionIndex = --intQuestionIndex; + } + + QaQuestionDTO mainQuestion = QaAuthoringController.getQuestionAtDisplayOrder(questionDTOs, + intOriginalQuestionIndex); + + QaQuestionDTO replacedQuestion = QaAuthoringController.getQuestionAtDisplayOrder(questionDTOs, + replacedQuestionIndex); + + List newQuestionDtos = new LinkedList<>(); + + Iterator iter = questionDTOs.iterator(); + while (iter.hasNext()) { + QaQuestionDTO questionDTO = iter.next(); + QaQuestionDTO tempQuestion = null; + + if (!questionDTO.getDisplayOrder().equals(new Integer(intOriginalQuestionIndex).toString()) + && !questionDTO.getDisplayOrder().equals(new Integer(replacedQuestionIndex).toString())) { + // normal copy + tempQuestion = questionDTO; + + } else if (questionDTO.getDisplayOrder().equals(new Integer(intOriginalQuestionIndex).toString())) { + // move type 1 + tempQuestion = replacedQuestion; + + } else if (questionDTO.getDisplayOrder().equals(new Integer(replacedQuestionIndex).toString())) { + // move type 1 + tempQuestion = mainQuestion; + } + + newQuestionDtos.add(tempQuestion); + } + + // references in conditions also need to be changed + if (conditions != null) { + for (QaCondition condition : conditions) { + SortedSet newQuestionDTOSet = new TreeSet<>(new QaQuestionContentDTOComparator()); + for (QaQuestionDTO dto : newQuestionDtos) { + if (condition.temporaryQuestionDTOSet.contains(dto)) { + newQuestionDTOSet.add(dto); + } + } + condition.temporaryQuestionDTOSet = newQuestionDTOSet; + } + } + + return newQuestionDtos; + } + + private static QaQuestionDTO getQuestionAtDisplayOrder(List questionDTOs, + int intOriginalQuestionIndex) { + + Iterator iter = questionDTOs.iterator(); + while (iter.hasNext()) { + QaQuestionDTO qaQuestionDTO = iter.next(); + if (new Integer(intOriginalQuestionIndex).toString().equals(qaQuestionDTO.getDisplayOrder())) { + return qaQuestionDTO; + } + } + return null; + } + + private static List reorderQuestionDTOs(List questionDTOs) { + List listFinalQuestionDTO = new LinkedList<>(); + + int queIndex = 0; + Iterator iter = questionDTOs.iterator(); + while (iter.hasNext()) { + QaQuestionDTO qaQuestionDTO = iter.next(); + + String question = qaQuestionDTO.getQuestion(); + String feedback = qaQuestionDTO.getFeedback(); + boolean required = qaQuestionDTO.isRequired(); + int minWordsLimit = qaQuestionDTO.getMinWordsLimit(); + + if (question != null && !question.equals("")) { + ++queIndex; + + qaQuestionDTO.setQuestion(question); + qaQuestionDTO.setDisplayOrder(new Integer(queIndex).toString()); + qaQuestionDTO.setFeedback(feedback); + qaQuestionDTO.setRequired(required); + qaQuestionDTO.setMinWordsLimit(minWordsLimit); + + listFinalQuestionDTO.add(qaQuestionDTO); + } + } + return listFinalQuestionDTO; + } + + /** + * Get the deleted condition list, which could be persisted or non-persisted + * items. + * + * @param request + * @return + */ + private List getDeletedQaConditionList(SessionMap sessionMap) { + List list = (List) sessionMap.get(QaAppConstants.ATTR_DELETED_CONDITION_LIST); + if (list == null) { + list = new ArrayList<>(); + sessionMap.put(QaAppConstants.ATTR_DELETED_CONDITION_LIST, list); + } + return list; + } +} Index: lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/web/controller/QaLearningController.java =================================================================== diff -u -r3bb7e0141ae1cc15ccd737c95d90b5762a34ad61 -rf49dd9f6b076828f464fc954bb9c3dc0c87e8b37 --- lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/web/controller/QaLearningController.java (.../QaLearningController.java) (revision 3bb7e0141ae1cc15ccd737c95d90b5762a34ad61) +++ lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/web/controller/QaLearningController.java (.../QaLearningController.java) (revision f49dd9f6b076828f464fc954bb9c3dc0c87e8b37) @@ -40,7 +40,6 @@ import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; -import org.lamsfoundation.lams.learningdesign.dto.ActivityPositionDTO; import org.lamsfoundation.lams.notebook.model.NotebookEntry; import org.lamsfoundation.lams.notebook.service.CoreNotebookConstants; import org.lamsfoundation.lams.rating.dto.ItemRatingCriteriaDTO; @@ -254,7 +253,7 @@ QaQuestionDTO questionDTO = new QaQuestionDTO(qaQuestion); mapQuestions.put(displayOrder, questionDTO); - mapQuestionStrings.put(new Integer(displayOrder).toString(), qaQuestion.getQuestion()); + mapQuestionStrings.put(new Integer(displayOrder).toString(), qaQuestion.getQbQuestion().getName()); } } @@ -624,12 +623,13 @@ } else { String currentQuestionIndex = qaLearningForm.getCurrentQuestionIndex(); String newAnswer = qaLearningForm.getAnswer(); - QaQueContent currentQuestion = qaService.getQuestionByContentAndDisplayOrder(new Integer(currentQuestionIndex), - qaContent.getUid()); + QaQueContent currentQuestion = qaService + .getQuestionByContentAndDisplayOrder(new Integer(currentQuestionIndex), qaContent.getUid()); - boolean isRequiredQuestionMissed = currentQuestion.isRequired() && isEmpty(newAnswer); + boolean isRequiredQuestionMissed = currentQuestion.getQbQuestion().isAnswerRequired() && isEmpty(newAnswer); if (!isRequiredQuestionMissed) { - qaService.updateResponseWithNewAnswer(newAnswer, toolSessionID, new Integer(currentQuestionIndex), true); + qaService.updateResponseWithNewAnswer(newAnswer, toolSessionID, new Integer(currentQuestionIndex), + true); } } } @@ -1240,7 +1240,7 @@ // create itemIds list List itemIds = new LinkedList<>(); for (QaUsrResp responseIter : userResponses) { - itemIds.add(responseIter.getResponseId()); + itemIds.add(responseIter.getUid()); } List itemRatingDtos = qaService.getRatingCriteriaDtos(qaContent.getQaContentId(), @@ -1258,7 +1258,7 @@ //find corresponding itemRatingDto ItemRatingDTO itemRatingDto = null; for (ItemRatingDTO itemRatingDtoIter : itemRatingDtos) { - if (itemRatingDtoIter.getItemId().equals(response.getResponseId())) { + if (itemRatingDtoIter.getItemId().equals(response.getUid())) { itemRatingDto = itemRatingDtoIter; break; } @@ -1359,7 +1359,7 @@ //create itemIds list List itemIds = new LinkedList<>(); for (QaUsrResp response : responses) { - itemIds.add(response.getResponseId()); + itemIds.add(response.getUid()); } //all comments required only for monitoring @@ -1392,7 +1392,7 @@ */ ObjectNode responseRow = JsonNodeFactory.instance.objectNode(); - responseRow.put("responseUid", response.getResponseId().toString()); + responseRow.put("responseUid", response.getUid().toString()); responseRow.put("answer", response.getAnswer()); responseRow.put("userName", StringEscapeUtils.escapeCsv(user.getFullname())); responseRow.put("visible", new Boolean(response.isVisible()).toString()); @@ -1411,7 +1411,7 @@ //find corresponding itemRatingDto ItemRatingDTO itemRatingDto = null; for (ItemRatingDTO itemRatingDtoIter : itemRatingDtos) { - if (response.getResponseId().equals(itemRatingDtoIter.getItemId())) { + if (response.getUid().equals(itemRatingDtoIter.getItemId())) { itemRatingDto = itemRatingDtoIter; break; } Index: lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/web/controller/QaMonitoringController.java =================================================================== diff -u -r69092337b728f903f824a74377bd0ebf9391120c -rf49dd9f6b076828f464fc954bb9c3dc0c87e8b37 --- lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/web/controller/QaMonitoringController.java (.../QaMonitoringController.java) (revision 69092337b728f903f824a74377bd0ebf9391120c) +++ lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/web/controller/QaMonitoringController.java (.../QaMonitoringController.java) (revision f49dd9f6b076828f464fc954bb9c3dc0c87e8b37) @@ -404,7 +404,7 @@ //create itemIds list List itemIds = new LinkedList<>(); for (QaUsrResp usrResponse : responses) { - itemIds.add(usrResponse.getResponseId()); + itemIds.add(usrResponse.getUid()); } List itemRatingDtos = qaService.getRatingCriteriaDtos(qaContent.getQaContentId(), toolSessionID, itemIds, true, allUserIdValue); Index: lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/web/controller/QaPedagogicalPlannerController.java =================================================================== diff -u -r69092337b728f903f824a74377bd0ebf9391120c -rf49dd9f6b076828f464fc954bb9c3dc0c87e8b37 --- lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/web/controller/QaPedagogicalPlannerController.java (.../QaPedagogicalPlannerController.java) (revision 69092337b728f903f824a74377bd0ebf9391120c) +++ lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/web/controller/QaPedagogicalPlannerController.java (.../QaPedagogicalPlannerController.java) (revision f49dd9f6b076828f464fc954bb9c3dc0c87e8b37) @@ -29,6 +29,7 @@ import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.StringUtils; +import org.lamsfoundation.lams.qb.model.QbQuestion; import org.lamsfoundation.lams.tool.qa.model.QaContent; import org.lamsfoundation.lams.tool.qa.model.QaQueContent; import org.lamsfoundation.lams.tool.qa.service.IQaService; @@ -83,18 +84,23 @@ pedagogicalPlannerForm.removeQuestion(questionIndex); } else { if (questionIndex < qaContent.getQaQueContents().size()) { - QaQueContent qaQuestion = qaService - .getQuestionByContentAndDisplayOrder(questionIndex + 1, qaContent.getUid()); - qaQuestion.setQuestion(question); - qaService.saveOrUpdateQuestion(qaQuestion); + QaQueContent qaQuestion = qaService.getQuestionByContentAndDisplayOrder(questionIndex + 1, + qaContent.getUid()); + qaQuestion.getQbQuestion().setName(question); + qaService.saveOrUpdate(qaQuestion.getQbQuestion()); } else { QaQueContent qaQuestion = new QaQueContent(); qaQuestion.setDisplayOrder(questionIndex + 1); - qaQuestion.setRequired(false); qaQuestion.setQaContent(qaContent); - qaQuestion.setQuestion(question); - qaService.saveOrUpdateQuestion(qaQuestion); + + QbQuestion qbQuestion = new QbQuestion(); + qbQuestion.setAnswerRequired(false); + qbQuestion.setName(question); + qaService.saveOrUpdate(qbQuestion); + + qaQuestion.setQbQuestion(qbQuestion); + qaService.saveOrUpdate(qaQuestion); } questionIndex++; } Index: lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/web/form/QaPedagogicalPlannerForm.java =================================================================== diff -u -r69092337b728f903f824a74377bd0ebf9391120c -rf49dd9f6b076828f464fc954bb9c3dc0c87e8b37 --- lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/web/form/QaPedagogicalPlannerForm.java (.../QaPedagogicalPlannerForm.java) (revision 69092337b728f903f824a74377bd0ebf9391120c) +++ lams_tool_laqa/src/java/org/lamsfoundation/lams/tool/qa/web/form/QaPedagogicalPlannerForm.java (.../QaPedagogicalPlannerForm.java) (revision f49dd9f6b076828f464fc954bb9c3dc0c87e8b37) @@ -84,7 +84,7 @@ if (questions != null) { int topicIndex = 0; for (QaQueContent message : (Set) questions) { - setQuestion(topicIndex++, message.getQuestion()); + setQuestion(topicIndex++, message.getQbQuestion().getName()); } } }