Index: lams_common/src/java/org/lamsfoundation/lams/commonContext.xml =================================================================== diff -u -r3c3ff3f2bd9e05d38823db2f4932217953acf160 -rd9b3433f41c2b25011809144d241d33237d9b9d8 --- lams_common/src/java/org/lamsfoundation/lams/commonContext.xml (.../commonContext.xml) (revision 3c3ff3f2bd9e05d38823db2f4932217953acf160) +++ lams_common/src/java/org/lamsfoundation/lams/commonContext.xml (.../commonContext.xml) (revision d9b3433f41c2b25011809144d241d33237d9b9d8) @@ -30,6 +30,7 @@ org.lamsfoundation.lams.outcome org.lamsfoundation.lams.planner org.lamsfoundation.lams.policies + org.lamsfoundation.lams.qb org.lamsfoundation.lams.themes org.lamsfoundation.lams.timezone org.lamsfoundation.lams.tool Index: lams_common/src/java/org/lamsfoundation/lams/qb/QbQuestion.java =================================================================== diff -u --- lams_common/src/java/org/lamsfoundation/lams/qb/QbQuestion.java (revision 0) +++ lams_common/src/java/org/lamsfoundation/lams/qb/QbQuestion.java (revision d9b3433f41c2b25011809144d241d33237d9b9d8) @@ -0,0 +1,162 @@ +package org.lamsfoundation.lams.qb; + +import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.PostLoad; +import javax.persistence.Table; +import javax.persistence.Transient; + +import org.apache.commons.lang.StringUtils; + +/** + * A question in Question Bank. + * + * @author Marcin Cieslak + */ +@Entity +@Table(name = "lams_qb_question") +public class QbQuestion implements Serializable, Cloneable { + private static final long serialVersionUID = -6287273838239262151L; + + // questions can be of different type + // not all tools can produce/consume all question types + public static final int TYPE_MULTIPLE_CHOICE_SINGLE_ANSWER = 1; + + // primary key + // another candidate is questionId + version, but single uid can fe searched faster + @Id + @Column + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long uid; + + // is the question searchable in Question Bank + // or rathe it is a tool's private data + @Column + private Boolean local = true; + + // one of question types + @Column + private Integer type; + + // "tracking ID" for a question + // multiple versions can share the same question ID so their stats are aggregated + @Column(name = "question_id") + private Integer questionId; + + // the same question can have multiple versions + @Column + private Integer version = 1; + + // text of the question + @Column + private String name; + + @Column + private Integer mark; + + @Column + private String feedback; + + // question state when it was loaded from DB + @Transient + private QbQuestion initialContent; + + // runs when the question gets loaded from DB + @PostLoad + private void setInitialContent() throws CloneNotSupportedException { + initialContent = this.clone(); + } + + // compares if current question state and the state when it was loaded from DB + // it detects if question is the same or should another question/version be created + public boolean isModified() { + return !equals(initialContent); + } + + // checks if important parts of another question are the same as current question's + @Override + public boolean equals(Object o) { + QbQuestion other = (QbQuestion) o; + return other != null && StringUtils.equals(other.name, name) && StringUtils.equals(other.feedback, feedback) + && (mark == null ? other.mark == null : mark.equals(other.mark)); + } + + @Override + public QbQuestion clone() { + QbQuestion clone = null; + try { + clone = (QbQuestion) super.clone(); + clone.uid = null; + } catch (Exception e) { + // this will never happen + e.printStackTrace(); + } + return clone; + + } + + public Long getUid() { + return uid; + } + + public Boolean getLocal() { + return local; + } + + public void setLocal(Boolean local) { + this.local = local; + } + + public Integer getType() { + return type; + } + + public void setType(Integer type) { + this.type = type; + } + + public Integer getQuestionId() { + return questionId; + } + + public void setQuestionId(Integer questionId) { + this.questionId = questionId; + } + + public Integer getVersion() { + return version; + } + + public void setVersion(Integer version) { + this.version = version; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name == null ? null : name.trim(); + } + + public Integer getMark() { + return mark; + } + + public void setMark(Integer mark) { + this.mark = mark; + } + + public String getFeedback() { + return feedback; + } + + public void setFeedback(String feedback) { + this.feedback = feedback == null ? null : feedback.trim(); + } +} \ No newline at end of file Index: lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/dao/IMcQueContentDAO.java =================================================================== diff -u -rd03a1456d2d0ee7a482273fe35412c67054f133d -rd9b3433f41c2b25011809144d241d33237d9b9d8 --- lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/dao/IMcQueContentDAO.java (.../IMcQueContentDAO.java) (revision d03a1456d2d0ee7a482273fe35412c67054f133d) +++ lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/dao/IMcQueContentDAO.java (.../IMcQueContentDAO.java) (revision d9b3433f41c2b25011809144d241d33237d9b9d8) @@ -24,14 +24,15 @@ import java.util.List; +import org.lamsfoundation.lams.dao.IBaseDAO; import org.lamsfoundation.lams.tool.mc.model.McQueContent; /** * Interface for the McQueContent DAO, defines methods needed to access/modify mc question content * * @author Ozgur Demirtas */ -public interface IMcQueContentDAO { +public interface IMcQueContentDAO extends IBaseDAO { /** *

@@ -91,4 +92,8 @@ List getAllQuestionEntriesSorted(final long qaContentId); void releaseQuestionFromCache(McQueContent question); + + // finds next question ID for Question Ban question + // it will be moved to a common service in the future + public int getMaxQbQuestionId(); } Index: lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/dao/hibernate/McQueContentDAO.java =================================================================== diff -u -rd03a1456d2d0ee7a482273fe35412c67054f133d -rd9b3433f41c2b25011809144d241d33237d9b9d8 --- lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/dao/hibernate/McQueContentDAO.java (.../McQueContentDAO.java) (revision d03a1456d2d0ee7a482273fe35412c67054f133d) +++ lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/dao/hibernate/McQueContentDAO.java (.../McQueContentDAO.java) (revision d9b3433f41c2b25011809144d241d33237d9b9d8) @@ -64,8 +64,8 @@ @Override @SuppressWarnings("unchecked") public List getQuestionsByContentUid(final long contentUid) { - List list = getSessionFactory().getCurrentSession().createQuery(LOAD_QUESTION_CONTENT_BY_CONTENT_ID) - .setParameter("mcContentId", contentUid).list(); + List list = getSessionFactory().getCurrentSession() + .createQuery(LOAD_QUESTION_CONTENT_BY_CONTENT_ID).setParameter("mcContentId", contentUid).list(); return list; } @@ -81,8 +81,7 @@ @Override public McQueContent getQuestionContentByDisplayOrder(final Integer displayOrder, final Long mcContentUid) { List list = getSessionFactory().getCurrentSession().createQuery(LOAD_QUESTION_CONTENT_BY_DISPLAY_ORDER) - .setParameter("displayOrder", displayOrder).setParameter("mcContentUid", mcContentUid) - .list(); + .setParameter("displayOrder", displayOrder).setParameter("mcContentUid", mcContentUid).list(); if (list != null && list.size() > 0) { McQueContent mcq = (McQueContent) list.get(0); @@ -115,4 +114,11 @@ public void releaseQuestionFromCache(McQueContent question) { getSession().evict(question); } + + @Override + public int getMaxQbQuestionId() { + Object result = this.getSession().createQuery("SELECT MAX(questionId) FROM QbQuestion").uniqueResult(); + Integer max = (Integer) result; + return max == null ? 1 : max + 1; + } } \ No newline at end of file Index: lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/dto/McQuestionDTO.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -rd9b3433f41c2b25011809144d241d33237d9b9d8 --- lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/dto/McQuestionDTO.java (.../McQuestionDTO.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/dto/McQuestionDTO.java (.../McQuestionDTO.java) (revision d9b3433f41c2b25011809144d241d33237d9b9d8) @@ -32,6 +32,7 @@ */ public class McQuestionDTO implements Comparable { private Long uid; + private Long qbQuestionUid; private String question; private Integer displayOrder; private String feedback; @@ -64,6 +65,14 @@ this.uid = uid; } + public Long getQbQuestionUid() { + return qbQuestionUid; + } + + public void setQbQuestionUid(Long qaQuestionId) { + this.qbQuestionUid = qaQuestionId; + } + /** * @return Returns the displayOrder. */ Index: lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/model/McQueContent.java =================================================================== diff -u -r1ee503e3d0e0228ea8a45025fddf15d9623c0377 -rd9b3433f41c2b25011809144d241d33237d9b9d8 --- lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/model/McQueContent.java (.../McQueContent.java) (revision 1ee503e3d0e0228ea8a45025fddf15d9623c0377) +++ lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/model/McQueContent.java (.../McQueContent.java) (revision d9b3433f41c2b25011809144d241d33237d9b9d8) @@ -42,6 +42,7 @@ import javax.persistence.Transient; import org.apache.commons.lang.builder.ToStringBuilder; +import org.lamsfoundation.lams.qb.QbQuestion; /** *

@@ -51,18 +52,22 @@ * * @author Ozgur Demirtas */ -@SuppressWarnings("serial") @Entity @Table(name = "tl_lamc11_que_content") public class McQueContent implements Serializable, Comparable { + private static final long serialVersionUID = 4022287106119453962L; @Id @Column @GeneratedValue(strategy = GenerationType.IDENTITY) private Long uid; - @Column - private String question; + // part of question's data is stored in Question Bank's DB tables + // getters and setters of this data (question, mark, feedback) are mapped to QbQuestion + @ManyToOne(optional = false, fetch = FetchType.EAGER, cascade = { CascadeType.DETACH, CascadeType.MERGE, + CascadeType.PERSIST, CascadeType.REFRESH }) + @JoinColumn(name = "qb_question_uid") + private QbQuestion qbQuestion = new QbQuestion(); /** * It stores sha1(question) value that allows us to search for the McQueContentc with the same question @@ -73,12 +78,6 @@ @Column(name = "display_order") private Integer displayOrder; - @Column - private Integer mark; - - @Column - private String feedback; - @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "mc_content_id") private org.lamsfoundation.lams.tool.mc.model.McContent mcContent; @@ -94,20 +93,18 @@ @Transient private String escapedQuestion; - public McQueContent(String question, String questionHash, Integer displayOrder, Integer mark, String feedback, - McContent mcContent, Set mcOptionsContents) { - this.question = question; + public McQueContent(QbQuestion qbQuestion, String questionHash, Integer displayOrder, McContent mcContent, + Set mcOptionsContents) { + this.qbQuestion = qbQuestion; this.questionHash = questionHash; this.displayOrder = displayOrder; - this.mark = mark; - this.feedback = feedback; this.mcContent = mcContent; - this.mcOptionsContents = mcOptionsContents != null ? mcOptionsContents : new HashSet(); + this.mcOptionsContents = mcOptionsContents != null ? mcOptionsContents : new HashSet<>(); } /** default constructor */ public McQueContent() { - this.mcOptionsContents = new HashSet(); + this.mcOptionsContents = new HashSet<>(); } /** @@ -120,15 +117,14 @@ * @return the new qa question content object */ public static McQueContent newInstance(McQueContent queContent, McContent newMcContent) { - McQueContent newQueContent = new McQueContent(queContent.getQuestion(), queContent.getQuestionHash(), - queContent.getDisplayOrder(), queContent.getMark(), queContent.getFeedback(), newMcContent, - new TreeSet()); + McQueContent newQueContent = new McQueContent(queContent.getQbQuestion(), queContent.getQuestionHash(), + queContent.getDisplayOrder(), newMcContent, new TreeSet()); newQueContent.setMcOptionsContents(queContent.deepCopyMcOptionsContent(newQueContent)); return newQueContent; } public Set deepCopyMcOptionsContent(McQueContent newQueContent) { - Set newMcOptionsContent = new TreeSet(); + Set newMcOptionsContent = new TreeSet<>(); for (McOptsContent mcOptsContent : this.getMcOptionsContents()) { McOptsContent mcNewOptsContent = McOptsContent.newInstance(mcOptsContent, newQueContent); newMcOptionsContent.add(mcNewOptsContent); @@ -144,12 +140,20 @@ this.uid = uid; } + public QbQuestion getQbQuestion() { + return qbQuestion; + } + + public void setQbQuestion(QbQuestion qbQuestion) { + this.qbQuestion = qbQuestion; + } + public String getQuestion() { - return this.question; + return this.qbQuestion.getName(); } public void setQuestion(String question) { - this.question = question; + this.qbQuestion.setName(question); } /** @@ -208,15 +212,15 @@ * @return Returns the feedback. */ public String getFeedback() { - return feedback; + return qbQuestion.getFeedback(); } /** * @param feedback * The feedback to set. */ public void setFeedback(String feedback) { - this.feedback = feedback; + qbQuestion.setFeedback(feedback); } @Override @@ -235,15 +239,15 @@ * @return Returns the mark. */ public Integer getMark() { - return mark; + return qbQuestion.getMark(); } /** * @param mark * The mark to set. */ public void setMark(Integer mark) { - this.mark = mark; + qbQuestion.setMark(mark); } public String getEscapedQuestion() { Index: lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/service/McService.java =================================================================== diff -u -r3bb7e0141ae1cc15ccd737c95d90b5762a34ad61 -rd9b3433f41c2b25011809144d241d33237d9b9d8 --- lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/service/McService.java (.../McService.java) (revision 3bb7e0141ae1cc15ccd737c95d90b5762a34ad61) +++ lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/service/McService.java (.../McService.java) (revision d9b3433f41c2b25011809144d241d33237d9b9d8) @@ -60,6 +60,7 @@ 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.QbQuestion; import org.lamsfoundation.lams.rest.RestTags; import org.lamsfoundation.lams.rest.ToolRestManager; import org.lamsfoundation.lams.tool.Tool; @@ -248,6 +249,8 @@ String newHash = mcQueContent.getQuestion() == null ? null : HashUtil.sha1(mcQueContent.getQuestion()); mcQueContent.setQuestionHash(newHash); + mcQueContentDAO.insertOrUpdate(mcQueContent.getQbQuestion()); + mcQueContentDAO.saveOrUpdateMcQueContent(mcQueContent); } @@ -273,29 +276,48 @@ McQueContent question = getQuestionByUid(questionDTO.getUid()); + // see if question already exists in QB + QbQuestion qbQuestion = (QbQuestion) mcQueContentDAO.find(QbQuestion.class, questionDTO.getQbQuestionUid()); + if (qbQuestion == null) { + // if it does not exist, create a new one + qbQuestion = new QbQuestion(); + qbQuestion.setType(QbQuestion.TYPE_MULTIPLE_CHOICE_SINGLE_ANSWER); + } else { + // if it exists, clone it so we do not change data on the existing entity, + // otherwise it gets saved on transaction end with modified data + qbQuestion = qbQuestion.clone(); + } + // set question's data to current values + qbQuestion.setName(currentQuestionText); + qbQuestion.setMark(Integer.valueOf(currentMark)); + qbQuestion.setFeedback(currentFeedback); + // if it is a new question, it is always considered modified + // if it is an existing question, it gets checked whether data changed + if (qbQuestion.isModified()) { + // if vital data changed, create a new question instead of modifying existing one + qbQuestion.setQuestionId(mcQueContentDAO.getMaxQbQuestionId()); + qbQuestion.setVersion(1); + question.setQbQuestion(qbQuestion); + } + // in case question doesn't exist if (question == null) { - question = new McQueContent(currentQuestionText, null, new Integer(displayOrder), - new Integer(currentMark), currentFeedback, content, null); + question = new McQueContent(qbQuestion, null, new Integer(displayOrder), content, null); // adding a new question to content content.getMcQueContents().add(question); question.setMcContent(content); // in case question exists already } else { - - question.setQuestion(currentQuestionText); - question.setFeedback(currentFeedback); question.setDisplayOrder(new Integer(displayOrder)); - question.setMark(new Integer(currentMark)); } // persist candidate answers List optionDTOs = questionDTO.getOptionDtos(); Set oldOptions = question.getMcOptionsContents(); - Set newOptions = new HashSet(); - Set wantedUids = new HashSet(); + Set newOptions = new HashSet<>(); + Set wantedUids = new HashSet<>(); int displayOrderOption = 1; for (McOptionDTO optionDTO : optionDTOs) { @@ -315,12 +337,12 @@ option.setCorrectOption(isCorrectOption); option.setMcQueOptionText(optionText); option.setMcQueContent(question); - + newOptions.add(option); displayOrderOption++; } question.setMcOptionsContents(newOptions); - + // updating the existing question content saveOrUpdateMcQueContent(question); @@ -330,7 +352,7 @@ @Override public void releaseQuestionsFromCache(McContent content) { - for (McQueContent question : (Set) content.getMcQueContents()) { + for (McQueContent question : content.getMcQueContents()) { mcQueContentDAO.releaseQuestionFromCache(question); } } @@ -468,19 +490,19 @@ @Override public List getAnswersFromDatabase(McContent mcContent, McQueUsr user) { - List answerDtos = new LinkedList(); + List answerDtos = new LinkedList<>(); List questions = this.getQuestionsByContentUid(mcContent.getUid()); for (McQueContent question : questions) { AnswerDTO answerDto = new AnswerDTO(); Set optionSet = question.getMcOptionsContents(); - List optionList = new LinkedList(optionSet); + List optionList = new LinkedList<>(optionSet); boolean randomize = mcContent.isRandomize(); if (randomize) { - ArrayList shuffledList = new ArrayList(optionList); + ArrayList shuffledList = new ArrayList<>(optionList); Collections.shuffle(shuffledList); - optionList = new LinkedList(shuffledList); + optionList = new LinkedList<>(shuffledList); } answerDto.setQuestion(question.getQuestion()); @@ -519,8 +541,8 @@ @Override public List buildGroupsMarkData(McContent mcContent, boolean isFullAttemptDetailsRequired) { - List listMonitoredMarksContainerDTO = new LinkedList(); - Set sessions = new TreeSet(new McSessionComparator()); + List listMonitoredMarksContainerDTO = new LinkedList<>(); + Set sessions = new TreeSet<>(new McSessionComparator()); sessions.addAll(mcContent.getMcSessions()); int numQuestions = mcContent.getMcQueContents().size(); @@ -583,8 +605,7 @@ // find out the answered option's sequential letter - A,B,C... String answeredOptionLetter = ""; int optionCount = 1; - for (McOptsContent option : (Set) attempt.getMcQueContent() - .getMcOptionsContents()) { + for (McOptsContent option : attempt.getMcQueContent().getMcOptionsContents()) { if (attempt.getMcOptionsContent().getUid().equals(option.getUid())) { answeredOptionLetter = String.valueOf((char) ((optionCount + 'A') - 1)); break; @@ -739,7 +760,7 @@ int oldTotalMark = mcUsrAttemptDAO.getUserTotalMark(userUid); int totalMark = (oldMark == null) ? oldTotalMark + newMark : (oldTotalMark - oldMark) + newMark; - List userAttempts = new ArrayList(); + List userAttempts = new ArrayList<>(); McQueUsr groupLeader = mcSession.getGroupLeader(); if (groupLeader != null) { if (groupLeader.equals(selectedUser)) { @@ -755,7 +776,7 @@ logger.warn(error); } } else { - userAttempts = new ArrayList(); + userAttempts = new ArrayList<>(); userAttempts.add(userAttemptToUpdate); } @@ -789,9 +810,9 @@ List questionDTOs, List deletedQuestions) { // create list of modified questions - List modifiedQuestions = new ArrayList(); + List modifiedQuestions = new ArrayList<>(); // create list of modified question marks - List modifiedQuestionsMarksOnly = new ArrayList(); + List modifiedQuestionsMarksOnly = new ArrayList<>(); for (McQueContent oldQuestion : oldQuestions) { for (McQuestionDTO questionDTO : questionDTOs) { if (oldQuestion.getUid().equals(questionDTO.getUid())) { @@ -928,7 +949,7 @@ } int totalNumberOfUsers = 0; - for (McSession session : (Set) mcContent.getMcSessions()) { + for (McSession session : mcContent.getMcSessions()) { totalNumberOfUsers += session.getMcQueUsers().size(); } @@ -974,7 +995,7 @@ rowCount++; int totalPercentage = 0; - for (McOptsContent option : (Set) question.getMcOptionsContents()) { + for (McOptsContent option : question.getMcOptionsContents()) { int optionAttemptCount = mcUsrAttemptDAO.getAttemptsCountPerOption(option.getUid()); cell = row.createCell(count++); int percentage = (optionAttemptCount * 100) / totalNumberOfUsers; @@ -1020,15 +1041,15 @@ row = sheet.createRow(rowCount++); count = 1; - ArrayList correctAnswers = new ArrayList(); + ArrayList correctAnswers = new ArrayList<>(); cell = row.createCell(count++); cell.setCellValue(messageService.getMessage("label.correct.answer")); for (McQueContent question : questions) { // find out the correct answer's sequential letter - A,B,C... String correctAnswerLetter = ""; int answerCount = 1; - for (McOptsContent option : (Set) question.getMcOptionsContents()) { + for (McOptsContent option : question.getMcOptionsContents()) { if (option.isCorrectOption()) { correctAnswerLetter = String.valueOf((char) ((answerCount + 'A') - 1)); break; @@ -1047,7 +1068,7 @@ cell = row.createCell(count++); cell.setCellValue(messageService.getMessage("label.learner")); - ArrayList totalPercentList = new ArrayList(); + ArrayList totalPercentList = new ArrayList<>(); int[] numberOfCorrectAnswersPerQuestion = new int[questions.size()]; for (McSessionMarkDTO sessionMarkDTO : sessionMarkDTOs) { Map usersMarksMap = sessionMarkDTO.getUserMarks(); @@ -1257,7 +1278,7 @@ return; } - for (McSession session : (Set) mcContent.getMcSessions()) { + for (McSession session : mcContent.getMcSessions()) { List entries = coreNotebookService.getEntry(session.getMcSessionId(), CoreNotebookConstants.NOTEBOOK_TOOL, McAppConstants.TOOL_SIGNATURE); for (NotebookEntry entry : entries) { @@ -1288,7 +1309,7 @@ McContent content = mcContentDAO.findMcContentById(toolContentId); if (content != null) { - for (McSession session : (Set) content.getMcSessions()) { + for (McSession session : content.getMcSessions()) { McQueUsr user = mcUserDAO.getMcUserBySession(userId.longValue(), session.getUid()); if (user != null) { mcUsrAttemptDAO.removeAllUserAttempts(user.getUid()); @@ -1379,7 +1400,7 @@ @Override public boolean isReadOnly(Long toolContentId) { McContent content = mcContentDAO.findMcContentById(toolContentId); - for (McSession session : (Set) content.getMcSessions()) { + for (McSession session : content.getMcSessions()) { if (!session.getMcQueUsers().isEmpty()) { return true; } @@ -1521,7 +1542,7 @@ @Override public List getConfidenceLevels(Long toolSessionId) { - List confidenceLevelDtos = new ArrayList(); + List confidenceLevelDtos = new ArrayList<>(); if (toolSessionId == null) { return confidenceLevelDtos; } @@ -1614,7 +1635,7 @@ public void auditLogStartEditingActivityInMonitor(long toolContentID) { toolService.auditLogStartEditingActivityInMonitor(toolContentID); } - + @Override public boolean isLastActivity(Long toolSessionId) { return toolService.isLastActivity(toolSessionId); @@ -1704,9 +1725,9 @@ @Override public List getReflectionList(McContent mcContent, Long userID) { - List reflectionsContainerDTO = new LinkedList(); - for (McSession mcSession : (Set) mcContent.getMcSessions()) { - for (McQueUsr user : (Set) mcSession.getMcQueUsers()) { + List reflectionsContainerDTO = new LinkedList<>(); + for (McSession mcSession : mcContent.getMcSessions()) { + for (McQueUsr user : mcSession.getMcQueUsers()) { // if all users mode or single user mode and found right user if (userID == null || user.getQueUsrId().equals(userID)) { NotebookEntry notebookEntry = this.getEntry(mcSession.getMcSessionId(), @@ -1847,11 +1868,11 @@ @SuppressWarnings("unchecked") @Override public List getSessionDtos(Long contentId, boolean includeStatistics) { - List sessionDtos = new ArrayList(); + List sessionDtos = new ArrayList<>(); McContent mcContent = getMcContent(contentId); if (mcContent != null) { - Set sessions = new TreeSet(new McSessionComparator()); + Set sessions = new TreeSet<>(new McSessionComparator()); sessions.addAll(mcContent.getMcSessions()); for (McSession session : sessions) { SessionDTO sessionDto = new SessionDTO(); @@ -1939,8 +1960,12 @@ // Questions ArrayNode questions = JsonUtil.optArray(toolContentJSON, RestTags.QUESTIONS); for (JsonNode questionData : questions) { - McQueContent question = new McQueContent(JsonUtil.optString(questionData, RestTags.QUESTION_TEXT), null, - JsonUtil.optInt(questionData, RestTags.DISPLAY_ORDER), 1, "", mcq, new HashSet()); + QbQuestion qbQuestion = new QbQuestion(); + qbQuestion.setType(QbQuestion.TYPE_MULTIPLE_CHOICE_SINGLE_ANSWER); + qbQuestion.setName(JsonUtil.optString(questionData, RestTags.QUESTION_TEXT)); + qbQuestion.setMark(1); + McQueContent question = new McQueContent(qbQuestion, null, + JsonUtil.optInt(questionData, RestTags.DISPLAY_ORDER), mcq, new HashSet()); ArrayNode optionsData = JsonUtil.optArray(questionData, RestTags.ANSWERS); for (JsonNode optionData : optionsData) { Index: lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/util/AuthoringUtil.java =================================================================== diff -u -rd03a1456d2d0ee7a482273fe35412c67054f133d -rd9b3433f41c2b25011809144d241d33237d9b9d8 --- lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/util/AuthoringUtil.java (.../AuthoringUtil.java) (revision d03a1456d2d0ee7a482273fe35412c67054f133d) +++ lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/util/AuthoringUtil.java (.../AuthoringUtil.java) (revision d9b3433f41c2b25011809144d241d33237d9b9d8) @@ -26,7 +26,6 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.List; -import java.util.Set; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; @@ -71,7 +70,7 @@ } /** - * persisting content. + * persisting content. */ public static McContent saveOrUpdateMcContent(IMcService mcService, HttpServletRequest request, McContent mcContent, String strToolContentID, List questionDTOs) { @@ -110,11 +109,11 @@ randomizeBoolean = true; } - if ( displayAnswersFeedback != null) { - if ( displayAnswersFeedback.equalsIgnoreCase("answers")) { + if (displayAnswersFeedback != null) { + if (displayAnswersFeedback.equalsIgnoreCase("answers")) { displayAnswersBoolean = true; displayFeedbackOnlyBoolean = false; - } else if ( displayAnswersFeedback.equalsIgnoreCase("feedback")) { + } else if (displayAnswersFeedback.equalsIgnoreCase("feedback")) { displayAnswersBoolean = false; displayFeedbackOnlyBoolean = true; } @@ -185,10 +184,10 @@ mcContent.setReflect(reflectBoolean); mcContent.setReflectionSubject(reflectionSubject); - + //calculate total mark int totalMark = 0; - for (McQuestionDTO questionDto: questionDTOs) { + for (McQuestionDTO questionDto : questionDTOs) { String mark = questionDto.getMark(); if (StringUtils.isNotBlank(mark)) { int intMark = new Integer(mark).intValue(); @@ -223,11 +222,11 @@ * generates a list for holding default questions and their candidate answers */ public static List buildDefaultQuestions(McContent mcContent) { - List questionDtos = new LinkedList(); + List questionDtos = new LinkedList<>(); Long mapIndex = new Long(1); - for (McQueContent question : (Set) mcContent.getMcQueContents()) { + for (McQueContent question : mcContent.getMcQueContents()) { McQuestionDTO questionDto = new McQuestionDTO(); String feedback = ""; @@ -238,14 +237,15 @@ String questionText = question.getQuestion(); questionDto.setUid(question.getUid()); + questionDto.setQbQuestionUid(question.getQbQuestion().getUid()); questionDto.setQuestion(questionText); questionDto.setDisplayOrder(question.getDisplayOrder()); questionDto.setFeedback(feedback); questionDto.setMark(question.getMark().toString()); // build candidate dtos - List optionDtos = new LinkedList(); - for (McOptsContent option : (Set) question.getMcOptionsContents()) { + List optionDtos = new LinkedList<>(); + for (McOptsContent option : question.getMcOptionsContents()) { McOptionDTO optionDTO = new McOptionDTO(option); optionDtos.add(optionDTO); } Index: lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/controller/McController.java =================================================================== diff -u -rd03a1456d2d0ee7a482273fe35412c67054f133d -rd9b3433f41c2b25011809144d241d33237d9b9d8 --- lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/controller/McController.java (.../McController.java) (revision d03a1456d2d0ee7a482273fe35412c67054f133d) +++ lams_tool_lamc/src/java/org/lamsfoundation/lams/tool/mc/web/controller/McController.java (.../McController.java) (revision d9b3433f41c2b25011809144d241d33237d9b9d8) @@ -448,6 +448,7 @@ String newQuestion = request.getParameter("newQuestion"); String feedback = request.getParameter("feedback"); Integer questionIndex = WebUtil.readIntParam(request, "questionIndex", true); + Long qbQuestionUid = WebUtil.readLongParam(request, "qbQuestionUid", true); mcAuthoringForm.setQuestionIndex(questionIndex); if ((newQuestion != null) && (newQuestion.length() > 0)) { @@ -465,6 +466,7 @@ McQuestionDTO questionDTO = new McQuestionDTO(); questionDTO.setQuestion(newQuestion); + questionDTO.setQbQuestionUid(qbQuestionUid); questionDTO.setFeedback(feedback); questionDTO.setDisplayOrder(maxDisplayOrder + 1); questionDTO.setOptionDtos(options); @@ -485,6 +487,7 @@ } questionDto.setQuestion(newQuestion); + questionDto.setQbQuestionUid(qbQuestionUid); questionDto.setFeedback(feedback); questionDto.setDisplayOrder(questionIndex); questionDto.setOptionDtos(options); Index: lams_tool_lamc/web/authoring/editQuestionBox.jsp =================================================================== diff -u -r5cc2f28c0fd508cf034496ad94d4892c373431f1 -rd9b3433f41c2b25011809144d241d33237d9b9d8 --- lams_tool_lamc/web/authoring/editQuestionBox.jsp (.../editQuestionBox.jsp) (revision 5cc2f28c0fd508cf034496ad94d4892c373431f1) +++ lams_tool_lamc/web/authoring/editQuestionBox.jsp (.../editQuestionBox.jsp) (revision d9b3433f41c2b25011809144d241d33237d9b9d8) @@ -148,6 +148,7 @@ +