Index: lams_tool_assessment/conf/xdoclet/struts-actions.xml =================================================================== RCS file: /usr/local/cvsroot/lams_tool_assessment/conf/xdoclet/struts-actions.xml,v diff -u -r1.14 -r1.15 --- lams_tool_assessment/conf/xdoclet/struts-actions.xml 18 May 2011 18:48:24 -0000 1.14 +++ lams_tool_assessment/conf/xdoclet/struts-actions.xml 3 Oct 2011 13:51:48 -0000 1.15 @@ -116,16 +116,46 @@ parameter="removeQuestion"> - + + + parameter="addQuestionReference"> - + parameter="removeQuestionReference"> + + + + + + + + + + + + + + + + + Index: lams_tool_assessment/db/sql/create_lams_tool_assessment.sql =================================================================== RCS file: /usr/local/cvsroot/lams_tool_assessment/db/sql/create_lams_tool_assessment.sql,v diff -u -r1.19 -r1.20 --- lams_tool_assessment/db/sql/create_lams_tool_assessment.sql 2 Jun 2011 04:18:30 -0000 1.19 +++ lams_tool_assessment/db/sql/create_lams_tool_assessment.sql 3 Oct 2011 13:51:48 -0000 1.20 @@ -72,6 +72,17 @@ session_uid bigint, primary key (uid) )type=innodb; +create table tl_laasse10_question_reference ( + uid bigint not null auto_increment, + question_uid bigint, + question_type smallint, + title varchar(255), + sequence_id integer, + default_grade integer DEFAULT 1, + random_question tinyint DEFAULT 0, + assessment_uid bigint, + primary key (uid) +)type=innodb; create table tl_laasse10_question_option ( uid bigint not null unique auto_increment, question_uid bigint, @@ -158,6 +169,8 @@ alter table tl_laasse10_assessment_question add index FK_NEW_1720029621_F52D1F93758092FB (create_by), add constraint FK_NEW_1720029621_F52D1F93758092FB foreign key (create_by) references tl_laasse10_user (uid); alter table tl_laasse10_assessment_question add index FK_NEW_1720029621_F52D1F9330E79035 (assessment_uid), add constraint FK_NEW_1720029621_F52D1F9330E79035 foreign key (assessment_uid) references tl_laasse10_assessment (uid); alter table tl_laasse10_assessment_question add index FK_NEW_1720029621_F52D1F93EC0D3147 (session_uid), add constraint FK_NEW_1720029621_F52D1F93EC0D3147 foreign key (session_uid) references tl_laasse10_session (uid); +alter table tl_laasse10_question_reference add index FK_tl_laasse10_question_reference_1 (question_uid), add constraint FK_tl_laasse10_question_reference_1 foreign key (question_uid) references tl_laasse10_assessment_question (uid); +alter table tl_laasse10_question_reference add index FK_tl_laasse10_question_reference_2 (assessment_uid), add constraint FK_tl_laasse10_question_reference_2 foreign key (assessment_uid) references tl_laasse10_assessment (uid); alter table tl_laasse10_question_option add index FK_tl_laasse10_question_option_1 (question_uid), add constraint FK_tl_laasse10_question_option_1 foreign key (question_uid) references tl_laasse10_assessment_question (uid); alter table tl_laasse10_assessment_overall_feedback add index FK_tl_laasse10_assessment_overall_feedback_1 (assessment_uid), add constraint FK_tl_laasse10_assessment_overall_feedback_1 foreign key (assessment_uid) references tl_laasse10_assessment (uid); alter table tl_laasse10_assessment_unit add index FK_tl_laasse10_assessment_unit_1 (question_uid), add constraint FK_tl_laasse10_assessment_unit_1 foreign key (question_uid) references tl_laasse10_assessment_question (uid); Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/AssessmentConstants.java =================================================================== RCS file: /usr/local/cvsroot/lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/AssessmentConstants.java,v diff -u -r1.18 -r1.19 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/AssessmentConstants.java 18 May 2011 18:48:24 -0000 1.18 +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/AssessmentConstants.java 3 Oct 2011 13:51:48 -0000 1.19 @@ -37,6 +37,8 @@ public static final int INITIAL_UNITS_NUMBER = 2; public static final int INITIAL_OVERALL_FEEDBACK_NUMBER = 3; + + public static final String EXPORT_QUESTIONS_FILENAME = "questions.xml"; // question type; public static final short QUESTION_TYPE_MULTIPLE_CHOICE = 1; @@ -70,6 +72,8 @@ public static final String PARAM_FILE_UUID = "fileUuid"; public static final String PARAM_QUESTION_INDEX = "questionIndex"; + + public static final String PARAM_QUESTION_REFERENCE_INDEX = "questionReferenceIndex"; public static final String PARAM_QUESTION_UID = "questionUid"; @@ -117,17 +121,25 @@ public static final String ATTR_QUESTION_TYPE = "questionType"; public static final String ATTR_QUESTION_LIST = "questionList"; + + public static final String ATTR_QUESTION_REFERENCES = "questionReferences"; + + public static final String ATTR_AVAILABLE_QUESTIONS = "availableQuestions"; public static final String ATT_ATTACHMENT_LIST = "instructionAttachmentList"; public static final String ATTR_DELETED_QUESTION_LIST = "deleteAssessmentList"; + + public static final String ATTR_DELETED_QUESTION_REFERENCES = "deleteQuestionReferences"; public static final String ATTR_DELETED_ATTACHMENT_LIST = "deletedAttachmmentList"; public static final String ATTR_DELETED_QUESTION_ATTACHMENT_LIST = "deletedQuestionAttachmmentList"; public static final String ATTR_UNIT_LIST = "unitList"; + public static final String ATTR_QUESTION_REFERENCES_GRADES = "referenceGrades"; + public static final String ATTR_UNIT_COUNT = "unitCount"; public static final String ATTR_UNIT_UNIT_PREFIX = "unitUnit"; Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dbupdates/patch20110413_updateTo236.sql =================================================================== RCS file: /usr/local/cvsroot/lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dbupdates/patch20110413_updateTo236.sql,v diff -u -r1.3 -r1.4 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dbupdates/patch20110413_updateTo236.sql 2 Jun 2011 04:18:30 -0000 1.3 +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dbupdates/patch20110413_updateTo236.sql 3 Oct 2011 13:51:48 -0000 1.4 @@ -9,9 +9,21 @@ ALTER TABLE tl_laasse10_assessment ADD COLUMN submission_deadline DATETIME DEFAULT null; -- LDEV-2684 Option for not displaying answers summary - ALTER TABLE tl_laasse10_assessment ADD COLUMN display_summary tinyint DEFAULT false; +-- LDEV-2714 Pool of questions for assessment tool +create table tl_laasse10_question_reference ( + uid bigint not null auto_increment, + question_uid bigint, + question_type smallint, + title varchar(255), + sequence_id integer, + default_grade integer DEFAULT 1, + random_question tinyint DEFAULT 0, + assessment_uid bigint, + primary key (uid) +)type=innodb; + ----------------------Put all sql statements above here------------------------- -- If there were no errors, commit and restore autocommit to on Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/Assessment.hbm.xml =================================================================== RCS file: /usr/local/cvsroot/lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/Attic/Assessment.hbm.xml,v diff -u -r1.6 -r1.7 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/Assessment.hbm.xml 18 May 2011 18:48:24 -0000 1.6 +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/Assessment.hbm.xml 3 Oct 2011 13:51:47 -0000 1.7 @@ -148,6 +148,26 @@ + + + + + + + + + + + questionReferences = toContent.getQuestionReferences(); + for (QuestionReference questionReference : questionReferences) { + if (questionReference.getQuestion() != null) { + questionReference.getQuestion().setCreateBy(toContent.getCreatedBy()); + } + } } return toContent; } @@ -157,9 +167,11 @@ try { assessment = (Assessment) super.clone(); assessment.setUid(null); + + // clone questions if (questions != null) { Iterator iter = questions.iterator(); - Set set = new TreeSet(new SequencableComparator()); + TreeSet set = new TreeSet(new SequencableComparator()); while (iter.hasNext()) { AssessmentQuestion question = (AssessmentQuestion) iter.next(); AssessmentQuestion newQuestion = (AssessmentQuestion) question.clone(); @@ -168,6 +180,30 @@ } assessment.questions = set; } + + // clone questionReferences + if (questionReferences != null) { + Iterator iter = questionReferences.iterator(); + Set set = new TreeSet(new SequencableComparator()); + while (iter.hasNext()) { + QuestionReference questionReference = (QuestionReference) iter.next(); + QuestionReference newQuestionReference = (QuestionReference) questionReference.clone(); + + // update questionReferences with new cloned question + if (newQuestionReference.getQuestion() != null) { + for (AssessmentQuestion newQuestion : (Set) assessment.questions) { + if (newQuestion.getSequenceId() == newQuestionReference.getQuestion().getSequenceId()) { + newQuestionReference.setQuestion(newQuestion); + break; + } + } + } + + set.add(newQuestionReference); + } + assessment.questionReferences = set; + } + // clone OverallFeedbacks if (overallFeedbacks != null) { Iterator iter = overallFeedbacks.iterator(); @@ -469,12 +505,28 @@ return questions; } - public void setQuestions(Set assessmentQuestions) { - this.questions = assessmentQuestions; + public void setQuestions(Set questions) { + this.questions = questions; } /** * + * @hibernate.set lazy="true" inverse="false" cascade="all" order-by="sequence_id asc" + * @hibernate.collection-key column="assessment_uid" + * @hibernate.collection-one-to-many class="org.lamsfoundation.lams.tool.assessment.model.QuestionReference" + * + * @return + */ + public Set getQuestionReferences() { + return questionReferences; + } + + public void setQuestionReferences(Set questionReferences) { + this.questionReferences = questionReferences; + } + + /** + * * @hibernate.set cascade="all" order-by="sequence_id asc" * @hibernate.collection-key column="assessment_uid" * @hibernate.collection-one-to-many class="org.lamsfoundation.lams.tool.assessment.model.AssessmentOverallFeedback" Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentQuestion.java =================================================================== RCS file: /usr/local/cvsroot/lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentQuestion.java,v diff -u -r1.12 -r1.13 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentQuestion.java 15 Dec 2009 13:58:57 -0000 1.12 +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentQuestion.java 3 Oct 2011 13:51:47 -0000 1.13 @@ -29,6 +29,9 @@ import java.util.Set; import java.util.TreeSet; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.log4j.Logger; import org.lamsfoundation.lams.tool.assessment.util.SequencableComparator; @@ -40,7 +43,7 @@ * @hibernate.class table="tl_laasse10_assessment_question" * */ -public class AssessmentQuestion implements Cloneable, Sequencable { +public class AssessmentQuestion implements Cloneable, Sequencable, Comparable { private static final Logger log = Logger.getLogger(AssessmentQuestion.class); private Long uid; @@ -139,17 +142,45 @@ obj.units = set; } - // clone AssessmentUser as well - if (this.createBy != null) { - ((AssessmentQuestion) obj).setCreateBy((AssessmentUser) this.createBy.clone()); - } } catch (CloneNotSupportedException e) { log.error("When clone " + AssessmentQuestion.class + " failed"); } return obj; } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (!(o instanceof AssessmentQuestion)) + return false; + final AssessmentQuestion genericEntity = (AssessmentQuestion) o; + + return new EqualsBuilder().append(this.getUid(), genericEntity.getUid()).append(this.getSequenceId(), genericEntity.getSequenceId()).isEquals(); + } + + @Override + public int compareTo(Object o) { + if ((o != null) && o instanceof AssessmentQuestion) { + AssessmentQuestion anotherQuestion = (AssessmentQuestion) o; + return (int) (sequenceId - anotherQuestion.getSequenceId()); + } else { + return 1; + } + } + + @Override + public String toString() { + return new ToStringBuilder(this).append("uid", getUid()).toString(); + } + + @Override + public int hashCode() { + return new HashCodeBuilder().append(getUid()).append(getSequenceId()).toHashCode(); + } + // ********************************************************** // Get/Set methods // ********************************************************** Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentQuestionOption.java =================================================================== RCS file: /usr/local/cvsroot/lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentQuestionOption.java,v diff -u -r1.1 -r1.2 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentQuestionOption.java 25 Feb 2009 22:16:33 -0000 1.1 +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentQuestionOption.java 3 Oct 2011 13:51:47 -0000 1.2 @@ -68,7 +68,7 @@ return uid; } - private void setUid(Long uuid) { + public void setUid(Long uuid) { uid = uuid; } Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentUnit.java =================================================================== RCS file: /usr/local/cvsroot/lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentUnit.java,v diff -u -r1.4 -r1.5 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentUnit.java 11 Mar 2009 16:08:56 -0000 1.4 +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/AssessmentUnit.java 3 Oct 2011 13:51:47 -0000 1.5 @@ -55,7 +55,7 @@ return uid; } - private void setUid(Long uuid) { + public void setUid(Long uuid) { uid = uuid; } Fisheye: Tag 1.1 refers to a dead (removed) revision in file `lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/QuestionReference.hbm.xml'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/model/QuestionReference.java'. Fisheye: No comparison available. Pass `N' to diff? Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java =================================================================== RCS file: /usr/local/cvsroot/lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java,v diff -u -r1.22 -r1.23 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java 13 Feb 2011 20:39:27 -0000 1.22 +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java 3 Oct 2011 13:51:48 -0000 1.23 @@ -87,6 +87,7 @@ import org.lamsfoundation.lams.tool.assessment.model.AssessmentSession; import org.lamsfoundation.lams.tool.assessment.model.AssessmentUnit; import org.lamsfoundation.lams.tool.assessment.model.AssessmentUser; +import org.lamsfoundation.lams.tool.assessment.model.QuestionReference; import org.lamsfoundation.lams.tool.assessment.util.AssessmentQuestionResultComparator; import org.lamsfoundation.lams.tool.assessment.util.AssessmentSessionComparator; import org.lamsfoundation.lams.tool.assessment.util.AssessmentToolContentHandler; @@ -212,7 +213,7 @@ public Assessment getAssessmentByContentId(Long contentId) { Assessment rs = assessmentDao.getByContentId(contentId); if (rs == null) { - AssessmentServiceImpl.log.error("Could not find the content by given ID:" + contentId); + AssessmentServiceImpl.log.debug("Could not find the content by given ID:" + contentId); } return rs; } @@ -293,6 +294,10 @@ public void deleteAssessmentQuestion(Long uid) { assessmentQuestionDao.removeObject(AssessmentQuestion.class, uid); } + + public void deleteQuestionReference(Long uid) { + assessmentQuestionDao.removeObject(QuestionReference.class, uid); + } public List getAssessmentQuestionsBySessionId(Long sessionId) { AssessmentSession session = assessmentSessionDao.getSessionBySessionId(sessionId); @@ -408,7 +413,7 @@ pattern = Pattern.compile(optionString, java.util.regex.Pattern.CASE_INSENSITIVE | java.util.regex.Pattern.UNICODE_CASE); } - boolean isAnswerCorrect = question.getAnswerString() != null ? pattern.matcher( + boolean isAnswerCorrect = (question.getAnswerString() != null) ? pattern.matcher( question.getAnswerString()).matches() : false; if (isAnswerCorrect) { @@ -424,8 +429,8 @@ boolean isAnswerCorrect = false; try { float answerFloat = Float.valueOf(question.getAnswerString()); - isAnswerCorrect = answerFloat >= option.getOptionFloat() - option.getAcceptedError() - && answerFloat <= option.getOptionFloat() + option.getAcceptedError(); + isAnswerCorrect = ((answerFloat >= (option.getOptionFloat() - option.getAcceptedError())) && (answerFloat <= (option + .getOptionFloat() + option.getAcceptedError()))); } catch (Exception e) { } @@ -440,9 +445,9 @@ try { float answerFloat = Float.valueOf(answerFloatStr); answerFloat = answerFloat / unit.getMultiplier(); - isAnswerCorrect = answerFloat >= option.getOptionFloat() - - option.getAcceptedError() - && answerFloat <= option.getOptionFloat() + option.getAcceptedError(); + isAnswerCorrect = ((answerFloat >= (option.getOptionFloat() - option + .getAcceptedError())) && (answerFloat <= (option.getOptionFloat() + option + .getAcceptedError()))); if (isAnswerCorrect) { break; } @@ -609,10 +614,15 @@ break; } } - } - userSummaryItem.setQuestionResults(questionResultsForSummary); - userSummaryItems.add(userSummaryItem); + + //skip questions without answers + if (questionResultsForSummary.isEmpty()) { + continue; + } else { + userSummaryItem.setQuestionResults(questionResultsForSummary); + userSummaryItems.add(userSummaryItem); + } } userSummary.setUserSummaryItems(userSummaryItems); @@ -649,6 +659,9 @@ break; } } + if (questionResult == null) { + continue; + } } questionResult.setUser(user); sessionQuestionResults.add(questionResult); @@ -667,7 +680,7 @@ } } } - float averageMark = count == 0 ? 0 : total / count; + float averageMark = (count == 0) ? 0 : total / count; questionSummary.setAverageMark(averageMark); escapeQuotes(questionSummary); Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/IAssessmentService.java =================================================================== RCS file: /usr/local/cvsroot/lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/IAssessmentService.java,v diff -u -r1.13 -r1.14 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/IAssessmentService.java 15 Feb 2011 21:36:22 -0000 1.13 +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/IAssessmentService.java 3 Oct 2011 13:51:47 -0000 1.14 @@ -134,6 +134,8 @@ * @param uid */ void deleteAssessmentQuestion(Long uid); + + void deleteQuestionReference(Long uid); /** * Return all reource questions within the given toolSessionID. Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/action/AuthoringAction.java =================================================================== RCS file: /usr/local/cvsroot/lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/action/AuthoringAction.java,v diff -u -r1.21 -r1.22 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/action/AuthoringAction.java 9 Jun 2011 12:13:59 -0000 1.21 +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/action/AuthoringAction.java 3 Oct 2011 13:51:48 -0000 1.22 @@ -23,6 +23,10 @@ /* $Id$ */ package org.lamsfoundation.lams.tool.assessment.web.action; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.sql.Timestamp; @@ -44,6 +48,9 @@ import javax.servlet.http.HttpSession; import org.apache.commons.beanutils.PropertyUtils; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.fileupload.DiskFileUpload; +import org.apache.commons.fileupload.FileItem; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.math.NumberUtils; import org.apache.log4j.Logger; @@ -55,6 +62,7 @@ import org.apache.struts.upload.FormFile; import org.lamsfoundation.lams.authoring.web.AuthoringConstants; import org.lamsfoundation.lams.contentrepository.client.IToolContentHandler; +import org.lamsfoundation.lams.learningdesign.service.ExportToolContentException; import org.lamsfoundation.lams.tool.ToolAccessMode; import org.lamsfoundation.lams.tool.assessment.AssessmentConstants; import org.lamsfoundation.lams.tool.assessment.model.Assessment; @@ -64,13 +72,15 @@ import org.lamsfoundation.lams.tool.assessment.model.AssessmentQuestionOption; import org.lamsfoundation.lams.tool.assessment.model.AssessmentUnit; import org.lamsfoundation.lams.tool.assessment.model.AssessmentUser; +import org.lamsfoundation.lams.tool.assessment.model.QuestionReference; import org.lamsfoundation.lams.tool.assessment.service.AssessmentApplicationException; import org.lamsfoundation.lams.tool.assessment.service.IAssessmentService; import org.lamsfoundation.lams.tool.assessment.service.UploadAssessmentFileException; import org.lamsfoundation.lams.tool.assessment.util.SequencableComparator; import org.lamsfoundation.lams.tool.assessment.web.form.AssessmentForm; import org.lamsfoundation.lams.tool.assessment.web.form.AssessmentQuestionForm; import org.lamsfoundation.lams.usermanagement.dto.UserDTO; +import org.lamsfoundation.lams.util.FileUtil; import org.lamsfoundation.lams.util.FileValidatorUtil; import org.lamsfoundation.lams.util.WebUtil; import org.lamsfoundation.lams.web.session.SessionManager; @@ -79,6 +89,8 @@ import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; +import com.thoughtworks.xstream.XStream; + /** * @author Andrey Balan */ @@ -143,12 +155,29 @@ if (param.equals("removeQuestion")) { return removeQuestion(mapping, form, request, response); } - if (param.equals("upQuestion")) { - return upQuestion(mapping, form, request, response); + // ----------------------- Question Reference functions --------------------------- + if (param.equals("addQuestionReference")) { + return addQuestionReference(mapping, form, request, response); } - if (param.equals("downQuestion")) { - return downQuestion(mapping, form, request, response); + if (param.equals("removeQuestionReference")) { + return removeQuestionReference(mapping, form, request, response); + } + if (param.equals("upQuestionReference")) { + return upQuestionReference(mapping, form, request, response); + } + if (param.equals("downQuestionReference")) { + return downQuestionReference(mapping, form, request, response); } + // ----------------------- Import/Export Questions functions --------------------------- + if (param.equals("importInit")) { + return importInit(mapping, form, request, response); + } + if (param.equals("importQuestions")) { + return importQuestions(mapping, form, request, response); + } + if (param.equals("exportQuestions")) { + return exportQuestions(mapping, form, request, response); + } // -----------------------Assessment Answer Option functions --------------------------- if (param.equals("addOption")) { return addOption(mapping, form, request, response); @@ -176,7 +205,7 @@ return mapping.findForward(AssessmentConstants.ERROR); } - + /** * Read assessment data from database and put them into HttpSession. It will redirect to init.do directly after this * method run successfully. @@ -255,10 +284,20 @@ questionList.clear(); questionList.addAll(questions); + // init question references + SortedSet references = getQuestionReferences(sessionMap); + references.clear(); + if (assessment.getQuestionReferences() != null) { + references.addAll(assessment.getQuestionReferences()); + } + + // init available questions + reinitializeAvailableQuestions(sessionMap); + sessionMap.put(AssessmentConstants.ATTR_ASSESSMENT_FORM, assessmentForm); return mapping.findForward(AssessmentConstants.SUCCESS); } - + /** * Display same entire authoring page content from HttpSession variable. * @@ -382,7 +421,7 @@ assessmentPO.setAttachments(attPOSet); // ************************* Handle assessment questions ******************* // Handle assessment questions - Set questionList = new LinkedHashSet(); + Set questions = new LinkedHashSet(); SortedSet topics = getQuestionList(sessionMap); iter = topics.iterator(); while (iter.hasNext()) { @@ -391,11 +430,22 @@ // This flushs user UID info to message if this user is a new user. question.setCreateBy(assessmentUser); removeNewLineCharacters(question); - questionList.add(question); + questions.add(question); } } - assessmentPO.setQuestions(questionList); - // delete instructino file from database. + assessmentPO.setQuestions(questions); + + // delete References from database. + List deletedReferences = getDeletedQuestionReferences(sessionMap); + iter = deletedReferences.iterator(); + while (iter.hasNext()) { + QuestionReference reference = (QuestionReference) iter.next(); + iter.remove(); + if (reference.getUid() != null) + service.deleteQuestionReference(reference.getUid()); + } + + // delete Questions from database. List deletedQuestionList = getDeletedQuestionList(sessionMap); iter = deletedQuestionList.iterator(); while (iter.hasNext()) { @@ -404,6 +454,11 @@ if (question.getUid() != null) service.deleteAssessmentQuestion(question.getUid()); } + + // Handle question references + Set questionReferences = updateQuestionReferencesGrades(request, sessionMap, true); + assessmentPO.setQuestionReferences(questionReferences); + // handle assessment question attachment file: List delQuestionAttList = getDeletedQuestionAttachmentList(sessionMap); iter = delQuestionAttList.iterator(); @@ -482,6 +537,7 @@ AssessmentForm assessmentForm = (AssessmentForm) form; // get back sessionMAP SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(assessmentForm.getSessionMapID()); + updateQuestionReferencesGrades(request, sessionMap, true); FormFile file; if (StringUtils.equals(IToolContentHandler.TYPE_OFFLINE, type)) @@ -606,6 +662,7 @@ HttpServletResponse response) { String sessionMapID = WebUtil.readStrParam(request, AssessmentConstants.ATTR_SESSION_MAP_ID); SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + updateQuestionReferencesGrades(request, sessionMap, false); String contentFolderID = (String) sessionMap.get(AttributeNames.PARAM_CONTENT_FOLDER_ID); AssessmentQuestionForm questionForm = (AssessmentQuestionForm) form; questionForm.setSessionMapID(sessionMapID); @@ -656,6 +713,7 @@ // get back sessionMAP String sessionMapID = WebUtil.readStrParam(request, AssessmentConstants.ATTR_SESSION_MAP_ID); SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + updateQuestionReferencesGrades(request, sessionMap, false); String contentFolderID = (String) sessionMap.get(AttributeNames.PARAM_CONTENT_FOLDER_ID); int questionIdx = NumberUtils.stringToInt(request.getParameter(AssessmentConstants.PARAM_QUESTION_INDEX), -1); @@ -693,6 +751,9 @@ AssessmentQuestionForm questionForm = (AssessmentQuestionForm) form; extractFormToAssessmentQuestion(request, questionForm); + + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(questionForm.getSessionMapID()); + reinitializeAvailableQuestions(sessionMap); // set session map ID so that questionlist.jsp can get sessionMAP request.setAttribute(AssessmentConstants.ATTR_SESSION_MAP_ID, questionForm.getSessionMapID()); @@ -715,6 +776,7 @@ // get back sessionMAP String sessionMapID = WebUtil.readStrParam(request, AssessmentConstants.ATTR_SESSION_MAP_ID); SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + updateQuestionReferencesGrades(request, sessionMap, false); int questionIdx = NumberUtils.stringToInt(request.getParameter(AssessmentConstants.PARAM_QUESTION_INDEX), -1); if (questionIdx != -1) { @@ -726,70 +788,342 @@ // add to delList List delList = getDeletedQuestionList(sessionMap); delList.add(question); + + //remove according questionReference, if exists + SortedSet questionReferences = getQuestionReferences(sessionMap); + QuestionReference questionReferenceToDelete = null; + for (QuestionReference questionReference: questionReferences) { + if ((questionReference.getQuestion() != null) + && (questionReference.getQuestion().getSequenceId() == question.getSequenceId())) { + questionReferenceToDelete = questionReference; + } + } + if (questionReferenceToDelete != null) { + List rRefList = new ArrayList(questionReferences); + rRefList.remove(questionReferenceToDelete.getSequenceId() - 1); + questionReferences.clear(); + questionReferences.addAll(rRefList); + // add to delList + List delReferencesList = getDeletedQuestionReferences(sessionMap); + delReferencesList.add(questionReferenceToDelete); + } + } + + reinitializeAvailableQuestions(sessionMap); request.setAttribute(AssessmentConstants.ATTR_SESSION_MAP_ID, sessionMapID); return mapping.findForward(AssessmentConstants.SUCCESS); } /** - * Move up current question. - * - * @param mapping - * @param form - * @param request - * @param response - * @return - */ - private ActionForward upQuestion(ActionMapping mapping, ActionForm form, HttpServletRequest request, + * Remove assessment question from HttpSession list and update page display. As authoring rule, all persist only happen + * when user submit whole page. So this remove is just impact HttpSession values. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + */ + private ActionForward addQuestionReference(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { - return switchQuestion(mapping, request, true); - } + // get back sessionMAP + String sessionMapID = WebUtil.readStrParam(request, AssessmentConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + updateQuestionReferencesGrades(request, sessionMap, false); + + SortedSet references = getQuestionReferences(sessionMap); + int questionIdx = NumberUtils.stringToInt(request.getParameter(AssessmentConstants.PARAM_QUESTION_INDEX), -1); + + //set SequenceId + QuestionReference reference = new QuestionReference(); + int maxSeq = 1; + if (references != null && references.size() > 0) { + QuestionReference last = references.last(); + maxSeq = last.getSequenceId() + 1; + } + reference.setSequenceId(maxSeq); + + //set isRandomQuestion + boolean isRandomQuestion = (questionIdx == -1); + reference.setRandomQuestion(isRandomQuestion); + + if (isRandomQuestion) { + reference.setDefaultGrade(1); + } else { + SortedSet questionList = getQuestionList(sessionMap); + AssessmentQuestion question = null; + for (AssessmentQuestion questionFromList : questionList) { + if (questionFromList.getSequenceId() == questionIdx) { + question = questionFromList; + break; + } + } + reference.setQuestion(question); + + reference.setDefaultGrade(question.getDefaultGrade()); + } + references.add(reference); + + reinitializeAvailableQuestions(sessionMap); + request.setAttribute(AssessmentConstants.ATTR_SESSION_MAP_ID, sessionMapID); + return mapping.findForward(AssessmentConstants.SUCCESS); + } + + /** + * Remove assessment question from HttpSession list and update page display. As authoring rule, all persist only happen + * when user submit whole page. So this remove is just impact HttpSession values. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + */ + private ActionForward removeQuestionReference(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + + // get back sessionMAP + String sessionMapID = WebUtil.readStrParam(request, AssessmentConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + updateQuestionReferencesGrades(request, sessionMap, false); + + int questionReferenceIdx = NumberUtils.stringToInt(request.getParameter(AssessmentConstants.PARAM_QUESTION_REFERENCE_INDEX), -1); + if (questionReferenceIdx != -1) { + SortedSet questionReferences = getQuestionReferences(sessionMap); + List rList = new ArrayList(questionReferences); + QuestionReference questionReference = rList.remove(questionReferenceIdx); + questionReferences.clear(); + questionReferences.addAll(rList); + // add to delList + List delList = getDeletedQuestionReferences(sessionMap); + delList.add(questionReference); + } + + reinitializeAvailableQuestions(sessionMap); + + request.setAttribute(AssessmentConstants.ATTR_SESSION_MAP_ID, sessionMapID); + return mapping.findForward(AssessmentConstants.SUCCESS); + } + + /** + * Move up current question reference. + * + * @param mapping + * @param form + * @param request + * @param response + * @return + */ + private ActionForward upQuestionReference(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + return switchQuestionReferences(mapping, request, true); + } + /** - * Move down current question. + * Move down current question reference. * * @param mapping * @param form * @param request * @param response * @return */ - private ActionForward downQuestion(ActionMapping mapping, ActionForm form, HttpServletRequest request, + private ActionForward downQuestionReference(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { - return switchQuestion(mapping, request, false); + return switchQuestionReferences(mapping, request, false); } - private ActionForward switchQuestion(ActionMapping mapping, HttpServletRequest request, boolean up) { + private ActionForward switchQuestionReferences(ActionMapping mapping, HttpServletRequest request, boolean up) { // get back sessionMAP String sessionMapID = WebUtil.readStrParam(request, AssessmentConstants.ATTR_SESSION_MAP_ID); SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + updateQuestionReferencesGrades(request, sessionMap, false); - int questionIdx = NumberUtils.stringToInt(request.getParameter(AssessmentConstants.PARAM_QUESTION_INDEX), -1); - if (questionIdx != -1) { - SortedSet questionList = getQuestionList(sessionMap); - List rList = new ArrayList(questionList); + int questionReferenceIdx = NumberUtils.stringToInt(request.getParameter(AssessmentConstants.PARAM_QUESTION_REFERENCE_INDEX), -1); + if (questionReferenceIdx != -1) { + SortedSet references = getQuestionReferences(sessionMap); + List rList = new ArrayList(references); // get current and the target item, and switch their sequnece - AssessmentQuestion question = rList.get(questionIdx); - AssessmentQuestion repQuestion; + QuestionReference reference = rList.get(questionReferenceIdx); + QuestionReference repReference; if (up) - repQuestion = rList.get(--questionIdx); + repReference = rList.get(--questionReferenceIdx); else - repQuestion = rList.get(++questionIdx); - int upSeqId = repQuestion.getSequenceId(); - repQuestion.setSequenceId(question.getSequenceId()); - question.setSequenceId(upSeqId); + repReference = rList.get(++questionReferenceIdx); + int upSeqId = repReference.getSequenceId(); + repReference.setSequenceId(reference.getSequenceId()); + reference.setSequenceId(upSeqId); // put back list, it will be sorted again - questionList.clear(); - questionList.addAll(rList); + references.clear(); + references.addAll(rList); } request.setAttribute(AssessmentConstants.ATTR_SESSION_MAP_ID, sessionMapID); return mapping.findForward(AssessmentConstants.SUCCESS); } /** + * Initializes import questions page. + */ + private ActionForward importInit(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws ServletException { + String sessionMapID = WebUtil.readStrParam(request, AssessmentConstants.ATTR_SESSION_MAP_ID); + request.setAttribute(AssessmentConstants.ATTR_SESSION_MAP_ID, sessionMapID); + + return mapping.findForward(AssessmentConstants.SUCCESS); + } + + /** + * Imports questions into question bank from uploaded xml file. + */ + private ActionForward importQuestions(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) throws ServletException { + String sessionMapID = WebUtil.readStrParam(request, AssessmentConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + request.setAttribute(AssessmentConstants.ATTR_SESSION_MAP_ID, sessionMapID); + AssessmentForm assessmentForm = (AssessmentForm) sessionMap.get(AssessmentConstants.ATTR_ASSESSMENT_FORM); + SortedSet oldQuestions = getQuestionList(sessionMap); + + List ldErrorMsgs = new ArrayList(); + List toolsErrorMsgs = new ArrayList(); + try { + File designFile = null; + Map params = new HashMap(); + String filename = null; + + String uploadPath = FileUtil.createTempDirectory("_uploaded_2questions_xml"); + + DiskFileUpload fu = new DiskFileUpload(); + // maximum size that will be stored in memory + fu.setSizeThreshold(4096); + // the location for saving data that is larger than getSizeThreshold() + // fu.setRepositoryPath(uploadPath); + + List fileItems = fu.parseRequest(request); + Iterator iter = fileItems.iterator(); + while (iter.hasNext()) { + FileItem fi = (FileItem) iter.next(); + // UPLOAD_FILE is input field from HTML page + if (!fi.getFieldName().equalsIgnoreCase("UPLOAD_FILE")) + params.put(fi.getFieldName(), fi.getString()); + else { + // filename on the client + filename = FileUtil.getFileName(fi.getName()); + designFile = new File(uploadPath + filename); + fi.write(designFile); + } + } + + String filename2 = designFile.getName(); + String fileExtension = filename2 != null && filename2.length() >= 4 ? filename2 + .substring(filename2.length() - 4) : ""; + if (! fileExtension.equalsIgnoreCase(".xml")) { + throw new RuntimeException("Wrong file extension. Xml is expected"); + } + //String learningDesignPath = ZipFileUtil.expandZip(new FileInputStream(designFile), filename2); + + // import learning design + String fullFilePath = designFile.getAbsolutePath();//FileUtil.getFullPath(learningDesignPath, ExportToolContentService.LEARNING_DESIGN_FILE_NAME); + List questions = (List) FileUtil.getObjectFromXML(null, fullFilePath); + if (questions != null) { + for (AssessmentQuestion question : questions) { + question.setCreateDate(new Timestamp(new Date().getTime())); + int maxSeq = 1; + if (oldQuestions != null && oldQuestions.size() > 0) { + AssessmentQuestion last = oldQuestions.last(); + maxSeq = last.getSequenceId() + 1; + } + question.setSequenceId(maxSeq); + oldQuestions.add(question); + } + } + + } catch (Exception e) { + log.error("Error occured during import", e); + toolsErrorMsgs.add(e.getClass().getName() + " " + e.getMessage()); + } + + if (toolsErrorMsgs.size() > 0) { + request.setAttribute("toolsErrorMessages", toolsErrorMsgs); + } + + reinitializeAvailableQuestions(sessionMap); + return mapping.findForward(AssessmentConstants.SUCCESS); + } + + /** + * Exports xml format questions from question bank. + */ + private ActionForward exportQuestions(ActionMapping mapping, ActionForm form, HttpServletRequest request, + HttpServletResponse response) { + String sessionMapID = request.getParameter(AssessmentConstants.ATTR_SESSION_MAP_ID); + SessionMap sessionMap = (SessionMap) request.getSession().getAttribute(sessionMapID); + + AssessmentForm assessmentForm = (AssessmentForm) sessionMap.get(AssessmentConstants.ATTR_ASSESSMENT_FORM); + Assessment assessment = assessmentForm.getAssessment(); + + String errors = null; + if (assessment != null) { + try { + ArrayList questionsToExport = new ArrayList(); + + for (AssessmentQuestion question : getQuestionList(sessionMap)) { + AssessmentQuestion clonedQuestion = (AssessmentQuestion) question.clone(); + clonedQuestion.setCreateBy(null); + questionsToExport.add(clonedQuestion); + } + // exporting XML + XStream designXml = new XStream(); + String resultedXml = designXml.toXML(questionsToExport); + + response.setContentType("application/x-download"); + response.setHeader("Content-Disposition", "attachment;filename=" + AssessmentConstants.EXPORT_QUESTIONS_FILENAME); + log.debug("Exporting assessment questions to an xml: " + assessment.getContentId()); + + OutputStream out = null; + try { + out = response.getOutputStream(); + out.write(resultedXml.getBytes()); + int count = resultedXml.getBytes().length; + log.debug("Wrote out " + count + " bytes"); + response.setContentLength(count); + out.flush(); + } catch (Exception e) { + log.error("Exception occured writing out file:" + e.getMessage()); + throw new ExportToolContentException(e); + } finally { + try { + if (out != null) { + out.close(); + } + } catch (Exception e) { + log.error("Error Closing file. File already written out - no exception being thrown.", e); + } + } + + } catch (Exception e) { + errors = "Unable to export tool content: " + e.toString(); + log.error(errors); + } + + } + if (errors != null) { + try { + PrintWriter out = response.getWriter(); + out.write(errors); + out.flush(); + } catch (IOException e) { + } + } + return null; + } + + + /** * Ajax call, will add one more input line for new resource item instruction. * * @param mapping @@ -998,6 +1332,26 @@ // Private method // ************************************************************************************* /** + * refreshes set of all available questions for adding to question list + * + * @param sessionMap + */ + private void reinitializeAvailableQuestions(SessionMap sessionMap) { + SortedSet bankQuestions = getQuestionList(sessionMap); + SortedSet references = getQuestionReferences(sessionMap); + Set questionsFromList = new LinkedHashSet(); + for (QuestionReference reference : references) { + questionsFromList.add(reference.getQuestion()); + } + + Set availableQuestions = new TreeSet(new SequencableComparator()); + availableQuestions.addAll(CollectionUtils.subtract(bankQuestions, questionsFromList)); + + sessionMap.put(AssessmentConstants.ATTR_AVAILABLE_QUESTIONS, availableQuestions); + } + + + /** * Return AssessmentService bean. */ private IAssessmentService getAssessmentService() { @@ -1037,6 +1391,22 @@ } return list; } + + /** + * List save current question references. + * + * @param request + * @return + */ + private SortedSet getQuestionReferences(SessionMap sessionMap) { + SortedSet list = (SortedSet) sessionMap + .get(AssessmentConstants.ATTR_QUESTION_REFERENCES); + if (list == null) { + list = new TreeSet(new SequencableComparator()); + sessionMap.put(AssessmentConstants.ATTR_QUESTION_REFERENCES, list); + } + return list; + } /** * List save deleted assessment questions, which could be persisted or non-persisted questions. @@ -1047,6 +1417,16 @@ private List getDeletedQuestionList(SessionMap sessionMap) { return getListFromSession(sessionMap, AssessmentConstants.ATTR_DELETED_QUESTION_LIST); } + + /** + * List save deleted assessment questions, which could be persisted or non-persisted questions. + * + * @param request + * @return + */ + private List getDeletedQuestionReferences(SessionMap sessionMap) { + return getListFromSession(sessionMap, AssessmentConstants.ATTR_DELETED_QUESTION_REFERENCES); + } /** * If a assessment question has attahment file, and the user edit this question and change the attachment to new file, then @@ -1273,6 +1653,29 @@ return mode; } + private Set updateQuestionReferencesGrades(HttpServletRequest request, SessionMap sessionMap, boolean isFormSubmit) { + Map paramMap = splitRequestParameter(request, AssessmentConstants.ATTR_QUESTION_REFERENCES_GRADES); + + SortedSet questionReferences = getQuestionReferences(sessionMap); + for (QuestionReference questionReference : questionReferences) { + try { + int grade; + if (isFormSubmit) { + grade = WebUtil.readIntParam(request, AssessmentConstants.PARAM_GRADE + questionReference.getSequenceId()); + } else { + String gradeStr = paramMap.get(AssessmentConstants.PARAM_GRADE + questionReference.getSequenceId()); + grade = new Integer(gradeStr); + } + + questionReference.setDefaultGrade(grade); + } catch (Exception e) { + log.debug(e.getMessage()); + } + } + + return questionReferences; + } + /** * Get answer options from HttpRequest * @@ -1459,6 +1862,10 @@ */ private Map splitRequestParameter(HttpServletRequest request, String parameterName) { String list = request.getParameter(parameterName); + if (list == null) { + return null; + } + String[] params = list.split("&"); Map paramMap = new HashMap(); String[] pair; Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/action/LearningAction.java =================================================================== RCS file: /usr/local/cvsroot/lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/action/LearningAction.java,v diff -u -r1.19 -r1.20 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/action/LearningAction.java 18 May 2011 18:48:24 -0000 1.19 +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/web/action/LearningAction.java 3 Oct 2011 13:51:48 -0000 1.20 @@ -26,10 +26,14 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.Date; +import java.util.HashMap; import java.util.LinkedHashSet; +import java.util.LinkedList; import java.util.List; +import java.util.Random; import java.util.Set; import java.util.TimeZone; import java.util.TreeSet; @@ -39,6 +43,7 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.math.NumberUtils; import org.apache.log4j.Logger; @@ -58,6 +63,7 @@ import org.lamsfoundation.lams.tool.assessment.model.AssessmentResult; import org.lamsfoundation.lams.tool.assessment.model.AssessmentSession; import org.lamsfoundation.lams.tool.assessment.model.AssessmentUser; +import org.lamsfoundation.lams.tool.assessment.model.QuestionReference; import org.lamsfoundation.lams.tool.assessment.service.AssessmentApplicationException; import org.lamsfoundation.lams.tool.assessment.service.IAssessmentService; import org.lamsfoundation.lams.tool.assessment.util.SequencableComparator; @@ -145,8 +151,34 @@ assessmentUser = getCurrentUser(service, toolSessionId); } - List questionsFromDB = service.getAssessmentQuestionsBySessionId(toolSessionId); Assessment assessment = service.getAssessmentBySessionId(toolSessionId); + Set questionReferences = new TreeSet(new SequencableComparator()); + questionReferences.addAll(assessment.getQuestionReferences()); + HashMap questionToReferenceMap = new HashMap(); + ArrayList takenQuestion = new ArrayList(); + + //add non-random questions + for (QuestionReference questionReference : questionReferences) { + if (!questionReference.isRandomQuestion()) { + AssessmentQuestion question = questionReference.getQuestion(); + takenQuestion.add(question); + questionToReferenceMap.put(questionReference.getUid(), question); + } + } + + Set allQuestions = assessment.getQuestions(); + Collection availableQuestions = CollectionUtils.subtract(allQuestions, takenQuestion); + //add random questions (actually replacing them with real ones) + for (QuestionReference questionReference : questionReferences) { + if (questionReference.isRandomQuestion()) { + //pick a random element + Random rand = new Random(System.currentTimeMillis()); + AssessmentQuestion question = (AssessmentQuestion) availableQuestions.toArray()[rand.nextInt(availableQuestions.size())]; + takenQuestion.add(question); + questionToReferenceMap.put(questionReference.getUid(), question); + availableQuestions.remove(question); + } + } int dbResultCount = service.getAssessmentResultCount(assessment.getUid(), assessmentUser.getUserId()); int attemptsAllowed = assessment.getAttemptsAllowed(); @@ -200,24 +232,22 @@ } } - Set questionList = new TreeSet(new SequencableComparator()); - if (questionsFromDB != null) { - // remove hidden questions. - for (AssessmentQuestion question : questionsFromDB) { - // becuase in webpage will use this login name. Here is just - // initialize it to avoid session close error in proxy object. - if (question.getCreateBy() != null) { - question.getCreateBy().getLoginName(); - } - questionList.add(question); + //sort questions + LinkedList questionList = new LinkedList(); + for (QuestionReference questionReference : questionReferences) { + AssessmentQuestion question = questionToReferenceMap.get(questionReference.getUid()); + // becuase in webpage will use this login name. Here is just initialize it to avoid session close error in proxy object. + if (question.getCreateBy() != null) { + question.getCreateBy().getLoginName(); } + questionList.add(question); } // shuffling if (assessment.isShuffled()) { ArrayList shuffledList = new ArrayList(questionList); Collections.shuffle(shuffledList); - questionList = new LinkedHashSet(shuffledList); + questionList = new LinkedList(shuffledList); } for (AssessmentQuestion question : questionList) { if (question.isShuffle() || (question.getType() == AssessmentConstants.QUESTION_TYPE_ORDERING)) { Index: lams_tool_assessment/web/WEB-INF/web.xml =================================================================== RCS file: /usr/local/cvsroot/lams_tool_assessment/web/WEB-INF/web.xml,v diff -u -r1.6 -r1.7 --- lams_tool_assessment/web/WEB-INF/web.xml 6 Oct 2010 10:16:37 -0000 1.6 +++ lams_tool_assessment/web/WEB-INF/web.xml 3 Oct 2011 13:51:48 -0000 1.7 @@ -147,7 +147,7 @@ Connector - /ckeditor/filemanager/browser/default/connectors/jsp/connector + /editor/filemanager/browser/default/connectors/jsp/connector @@ -199,6 +199,13 @@ tags-xml /WEB-INF/tlds/jstl/x.tld + + + + + fck-editor + /WEB-INF/tlds/fckeditor/FCKeditor.tld + Index: lams_tool_assessment/web/WEB-INF/tags/AuthoringButton.tag =================================================================== RCS file: /usr/local/cvsroot/lams_tool_assessment/web/WEB-INF/tags/AuthoringButton.tag,v diff -u -r1.6 -r1.7 --- lams_tool_assessment/web/WEB-INF/tags/AuthoringButton.tag 6 Sep 2011 01:15:07 -0000 1.6 +++ lams_tool_assessment/web/WEB-INF/tags/AuthoringButton.tag 3 Oct 2011 13:51:48 -0000 1.7 @@ -65,13 +65,25 @@ + + Index: lams_tool_assessment/web/pages/monitoring/summary.jsp =================================================================== RCS file: /usr/local/cvsroot/lams_tool_assessment/web/pages/monitoring/summary.jsp,v diff -u -r1.14 -r1.15 --- lams_tool_assessment/web/pages/monitoring/summary.jsp 1 Jun 2011 10:15:49 -0000 1.14 +++ lams_tool_assessment/web/pages/monitoring/summary.jsp 3 Oct 2011 13:51:48 -0000 1.15 @@ -20,19 +20,13 @@ 'userId', 'sessionId', "", - - "${question.title}", - ""], colModel:[ {name:'id',index:'id', width:20, sorttype:"int"}, {name:'userId',index:'userId', width:0}, {name:'sessionId',index:'sessionId', width:0}, - {name:'userName',index:'userName', width:100}, - - {name:'${question.uid}', index:'${question.uid}', width:80, align:"right", sorttype:"float"}, - + {name:'userName',index:'userName', width:200}, {name:'total',index:'total', width:50,align:"right",sorttype:"float", formatter:'number', formatoptions:{decimalPlaces: 2}} ], @@ -71,23 +65,11 @@ userId:"${assessmentResult.user.userId}", sessionId:"${assessmentResult.user.session.sessionId}", userName:"${assessmentResult.user.lastName}, ${assessmentResult.user.firstName}", - - - - ${questionResult.assessmentQuestion.uid}:"", - - - - - ${question.uid}:"-", - - - - total:"" }); + var oldValue = 0; jQuery("#userSummary${summary.sessionId}").jqGrid({ datatype: "local", gridstate:"hidden", @@ -114,16 +96,16 @@ cellurl: '', cellEdit: true, + afterEditCell: function (rowid,name,val,iRow,iCol){ + oldValue = eval(val); + }, afterSaveCell : function (rowid,name,val,iRow,iCol){ - //var questionResultUid = jQuery("#session${session.sessionId}").getCell(rowid, 'questionResultUid'); || (questionResultUid=="") if (isNaN(val)) { jQuery("#userSummary${summary.sessionId}").restoreCell(iRow,iCol); } else { var parentSelectedRowId = jQuery("#list${summary.sessionId}").getGridParam("selrow"); - var previousValue = eval(jQuery("#list${summary.sessionId}").getCell(parentSelectedRowId, eval(rowid)+3)); var previousTotal = eval(jQuery("#list${summary.sessionId}").getCell(parentSelectedRowId, 'total')); - jQuery("#list${summary.sessionId}").setCell(parentSelectedRowId, eval(rowid)+3, val, {}, {}); - jQuery("#list${summary.sessionId}").setCell(parentSelectedRowId, 'total', previousTotal - previousValue + eval(val), {}, {}); + jQuery("#list${summary.sessionId}").setCell(parentSelectedRowId, 'total', previousTotal - oldValue + eval(val), {}, {}); } }, beforeSubmitCell : function (rowid,name,val,iRow,iCol){