Index: lams_common/src/java/org/lamsfoundation/lams/learningdesign/dao/IActivityDAO.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r122ff0d8419be3fac72ddb842cbbce1cea01e542 --- lams_common/src/java/org/lamsfoundation/lams/learningdesign/dao/IActivityDAO.java (.../IActivityDAO.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_common/src/java/org/lamsfoundation/lams/learningdesign/dao/IActivityDAO.java (.../IActivityDAO.java) (revision 122ff0d8419be3fac72ddb842cbbce1cea01e542) @@ -99,7 +99,7 @@ * The id of the learningDesign * @return List of all the activities */ - public List getActivitiesByLearningDesignId(Long learningDesignId); + public List getActivitiesByLearningDesignId(Long learningDesignId); /** * Get all the grouping activities for this learning design. Index: lams_common/src/java/org/lamsfoundation/lams/learningdesign/dao/hibernate/ActivityDAO.java =================================================================== diff -u -rb3b03858efeef1c37e36993757f56374a9f2b9f3 -r122ff0d8419be3fac72ddb842cbbce1cea01e542 --- lams_common/src/java/org/lamsfoundation/lams/learningdesign/dao/hibernate/ActivityDAO.java (.../ActivityDAO.java) (revision b3b03858efeef1c37e36993757f56374a9f2b9f3) +++ lams_common/src/java/org/lamsfoundation/lams/learningdesign/dao/hibernate/ActivityDAO.java (.../ActivityDAO.java) (revision 122ff0d8419be3fac72ddb842cbbce1cea01e542) @@ -165,13 +165,9 @@ return super.findAll(Activity.class); } - /* - * @see - * org.lamsfoundation.lams.learningdesign.dao.interfaces.IActivityDAO#getActivitiesByLearningDesignId(java.lang. - * Long) - */ + @SuppressWarnings("unchecked") @Override - public List getActivitiesByLearningDesignId(Long learningDesignId) { + public List getActivitiesByLearningDesignId(Long learningDesignId) { return this.doFind(ActivityDAO.FIND_BY_LEARNING_DESIGN_ID, learningDesignId); } Index: lams_common/src/java/org/lamsfoundation/lams/tool/service/ICommonScratchieService.java =================================================================== diff -u --- lams_common/src/java/org/lamsfoundation/lams/tool/service/ICommonScratchieService.java (revision 0) +++ lams_common/src/java/org/lamsfoundation/lams/tool/service/ICommonScratchieService.java (revision 122ff0d8419be3fac72ddb842cbbce1cea01e542) @@ -0,0 +1,10 @@ +package org.lamsfoundation.lams.tool.service; + +public interface ICommonScratchieService { + + /** + * + */ + void recalculateScratchieMarksForVsaQuestion(Long qbQuestionUid); + +} Index: lams_common/src/java/org/lamsfoundation/lams/tool/service/ILamsToolService.java =================================================================== diff -u -re8a7110708b15579af2c6b31ac52a6da427fef6d -r122ff0d8419be3fac72ddb842cbbce1cea01e542 --- lams_common/src/java/org/lamsfoundation/lams/tool/service/ILamsToolService.java (.../ILamsToolService.java) (revision e8a7110708b15579af2c6b31ac52a6da427fef6d) +++ lams_common/src/java/org/lamsfoundation/lams/tool/service/ILamsToolService.java (.../ILamsToolService.java) (revision 122ff0d8419be3fac72ddb842cbbce1cea01e542) @@ -224,6 +224,13 @@ */ Collection getVsaAnswersFromAssessment(Integer activityUiidProvidingVsaAnswers, Integer requestorUserId, Long requestorToolSessionId); + + /** + * Recalculate marks for all Scratchie activities that use specified QbQuestion. + * + * @param qbQuestionUid + */ + void recalculateScratchieMarksForVsaQuestion(Long qbQuestionUid); /** * Get a count of all the users that would be returned by getUsersForActivity(Long toolSessionId); Index: lams_common/src/java/org/lamsfoundation/lams/tool/service/LamsCoreToolService.java =================================================================== diff -u -re8a7110708b15579af2c6b31ac52a6da427fef6d -r122ff0d8419be3fac72ddb842cbbce1cea01e542 --- lams_common/src/java/org/lamsfoundation/lams/tool/service/LamsCoreToolService.java (.../LamsCoreToolService.java) (revision e8a7110708b15579af2c6b31ac52a6da427fef6d) +++ lams_common/src/java/org/lamsfoundation/lams/tool/service/LamsCoreToolService.java (.../LamsCoreToolService.java) (revision 122ff0d8419be3fac72ddb842cbbce1cea01e542) @@ -347,7 +347,6 @@ return isActivityReadOnlyFlag(activity); } - @SuppressWarnings("unchecked") private boolean isActivityReadOnlyFlag(Activity activity) { if (activity.isComplexActivity()) { for (Activity childActivity : (Set) ((ComplexActivity) systemToolDAO.find(ComplexActivity.class, Index: lams_common/src/java/org/lamsfoundation/lams/tool/service/LamsToolService.java =================================================================== diff -u -re8a7110708b15579af2c6b31ac52a6da427fef6d -r122ff0d8419be3fac72ddb842cbbce1cea01e542 --- lams_common/src/java/org/lamsfoundation/lams/tool/service/LamsToolService.java (.../LamsToolService.java) (revision e8a7110708b15579af2c6b31ac52a6da427fef6d) +++ lams_common/src/java/org/lamsfoundation/lams/tool/service/LamsToolService.java (.../LamsToolService.java) (revision 122ff0d8419be3fac72ddb842cbbce1cea01e542) @@ -33,6 +33,7 @@ import java.util.TreeSet; import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; import org.hibernate.Hibernate; import org.hibernate.proxy.HibernateProxy; import org.lamsfoundation.lams.confidencelevel.ConfidenceLevelDTO; @@ -61,9 +62,10 @@ import org.lamsfoundation.lams.tool.exception.ToolException; import org.lamsfoundation.lams.usermanagement.User; import org.lamsfoundation.lams.usermanagement.service.IUserManagementService; +import org.lamsfoundation.lams.util.CommonConstants; import org.lamsfoundation.lams.util.FileUtil; import org.lamsfoundation.lams.util.FileUtilException; -import org.lamsfoundation.lams.web.util.AttributeNames; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; /** * @author Jacky Fang @@ -72,6 +74,7 @@ * @author Ozgur Demirtas 24/06/2005 */ public class LamsToolService implements ILamsToolService { + private static final Logger log = Logger.getLogger(LamsToolService.class); // Leader selection tool Constants private static final String LEADER_SELECTION_TOOL_OUTPUT_NAME_LEADER_USERID = "leader.user.id"; @@ -502,6 +505,14 @@ ToolSession assessmentSession = toolSessionDAO.getToolSessionByLearner(user, activityProvidingVsaAnswers); return lamsCoreToolService.getVsaAnswersByToolSession(assessmentSession); } + + @Override + public void recalculateScratchieMarksForVsaQuestion(Long qbQuestionUid) { + Tool scratchieTool = toolDAO.getToolBySignature(CommonConstants.TOOL_SIGNATURE_SCRATCHIE); + ICommonScratchieService sessionManager = (ICommonScratchieService) lamsCoreToolService + .findToolService(scratchieTool); + sessionManager.recalculateScratchieMarksForVsaQuestion(qbQuestionUid); + } @Override public Integer getCountUsersForActivity(Long toolSessionId) { Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dao/AssessmentResultDAO.java =================================================================== diff -u -r67d7232f087b9f5c72ff41f7bbebe29cff81e099 -r122ff0d8419be3fac72ddb842cbbce1cea01e542 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dao/AssessmentResultDAO.java (.../AssessmentResultDAO.java) (revision 67d7232f087b9f5c72ff41f7bbebe29cff81e099) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dao/AssessmentResultDAO.java (.../AssessmentResultDAO.java) (revision 122ff0d8419be3fac72ddb842cbbce1cea01e542) @@ -32,6 +32,8 @@ public interface AssessmentResultDAO extends DAO { List getAssessmentResults(Long assessmentUid, Long userId); + + List getAssessmentResultsByQbQuestion(Long qbQuestionUid); List getAssessmentResultsBySession(Long sessionId, Long userId); Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dao/hibernate/AssessmentResultDAOHibernate.java =================================================================== diff -u -r67d7232f087b9f5c72ff41f7bbebe29cff81e099 -r122ff0d8419be3fac72ddb842cbbce1cea01e542 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dao/hibernate/AssessmentResultDAOHibernate.java (.../AssessmentResultDAOHibernate.java) (revision 67d7232f087b9f5c72ff41f7bbebe29cff81e099) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dao/hibernate/AssessmentResultDAOHibernate.java (.../AssessmentResultDAOHibernate.java) (revision 122ff0d8419be3fac72ddb842cbbce1cea01e542) @@ -31,6 +31,7 @@ import org.lamsfoundation.lams.tool.assessment.dao.AssessmentResultDAO; import org.lamsfoundation.lams.tool.assessment.dto.AssessmentUserDTO; import org.lamsfoundation.lams.tool.assessment.model.Assessment; +import org.lamsfoundation.lams.tool.assessment.model.AssessmentQuestionResult; import org.lamsfoundation.lams.tool.assessment.model.AssessmentResult; import org.lamsfoundation.lams.tool.assessment.model.AssessmentUser; import org.lamsfoundation.lams.usermanagement.User; @@ -109,6 +110,18 @@ return (List) doFind(FIND_BY_ASSESSMENT_AND_USER_AND_FINISHED, new Object[] { userId, assessmentUid }); } + + @Override + public List getAssessmentResultsByQbQuestion(Long qbQuestionUid) { + final String FIND_BY_QBQUESTION_AND_FINISHED = "SELECT r FROM " + AssessmentQuestionResult.class.getName() + + " AS q, " + AssessmentResult.class.getName() + " AS r " + + " WHERE q.assessmentResult.uid = r.uid AND q.qbToolQuestion.qbQuestion.uid =:qbQuestionUid AND (r.finishDate != null) ORDER BY r.startDate ASC"; + + Query q = getSession().createQuery(FIND_BY_QBQUESTION_AND_FINISHED, AssessmentResult.class); + q.setParameter("qbQuestionUid", qbQuestionUid); +// q.addEntity("bq", AssessmentResult.class); + return q.list(); + } @Override public List getFinishedAssessmentResultsByUser(Long sessionId, Long userId) { Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java =================================================================== diff -u -re8a7110708b15579af2c6b31ac52a6da427fef6d -r122ff0d8419be3fac72ddb842cbbce1cea01e542 --- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java (.../AssessmentServiceImpl.java) (revision e8a7110708b15579af2c6b31ac52a6da427fef6d) +++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java (.../AssessmentServiceImpl.java) (revision 122ff0d8419be3fac72ddb842cbbce1cea01e542) @@ -751,32 +751,37 @@ questionResult.setQbOption(null); for (OptionDTO optionDto : questionDto.getOptionDtos()) { + String[] optionAnswers = optionDto.getName().strip().split("\\r\\n"); + boolean isAnswerMatchedCurrentOption = false; + for (String optionAnswer : optionAnswers) { + optionAnswer = optionAnswer.strip(); - //prepare regex which takes into account only * special character - String regexWithOnlyAsteriskSymbolActive = "\\Q"; - String name = optionDto.getName().trim(); - for (int i = 0; i < name.length(); i++) { - //everything in between \\Q and \\E are taken literally no matter which characters it contains - if (name.charAt(i) == '*') { - regexWithOnlyAsteriskSymbolActive += "\\E.*\\Q"; + //prepare regex which takes into account only * special character + String regexWithOnlyAsteriskSymbolActive = "\\Q"; + for (int i = 0; i < optionAnswer.length(); i++) { + //everything in between \\Q and \\E are taken literally no matter which characters it contains + if (optionAnswer.charAt(i) == '*') { + regexWithOnlyAsteriskSymbolActive += "\\E.*\\Q"; + } else { + regexWithOnlyAsteriskSymbolActive += optionAnswer.charAt(i); + } + } + regexWithOnlyAsteriskSymbolActive += "\\E"; + + //check whether answer matches regex + Pattern pattern; + if (questionDto.isCaseSensitive()) { + pattern = Pattern.compile(regexWithOnlyAsteriskSymbolActive); } else { - regexWithOnlyAsteriskSymbolActive += name.charAt(i); + pattern = Pattern.compile(regexWithOnlyAsteriskSymbolActive, + java.util.regex.Pattern.CASE_INSENSITIVE | java.util.regex.Pattern.UNICODE_CASE); } + if (questionDto.getAnswer() != null && pattern.matcher(questionDto.getAnswer().strip()).matches()) { + isAnswerMatchedCurrentOption = true; + break; + } } - regexWithOnlyAsteriskSymbolActive += "\\E"; - //check whether answer matches regex - Pattern pattern; - if (questionDto.isCaseSensitive()) { - pattern = Pattern.compile(regexWithOnlyAsteriskSymbolActive); - } else { - pattern = Pattern.compile(regexWithOnlyAsteriskSymbolActive, - java.util.regex.Pattern.CASE_INSENSITIVE | java.util.regex.Pattern.UNICODE_CASE); - } - boolean isAnswerMatchedCurrentOption = (questionDto.getAnswer() != null) - ? pattern.matcher(questionDto.getAnswer().trim()).matches() - : false; - if (isAnswerMatchedCurrentOption) { mark = optionDto.getMaxMark() * maxMark; QbOption qbOption = qbService.getOptionByUid(optionDto.getUid()); @@ -1359,10 +1364,10 @@ @Override public void allocateAnswerToOption(Long questionUid, Long targetOptionUid, Long previousOptionUid, Long questionResultUid) { - AssessmentQuestion question = assessmentQuestionDao.getByUid(questionUid); - QbQuestion qbQuestion = question.getQbQuestion(); - AssessmentQuestionResult questionResult = assessmentQuestionResultDao.getAssessmentQuestionResultByUid(questionResultUid); - String answer = questionResult.getAnswer(); + AssessmentQuestion assessmentQuestion = assessmentQuestionDao.getByUid(questionUid); + QbQuestion qbQuestion = assessmentQuestion.getQbQuestion(); + AssessmentQuestionResult questionRes = assessmentQuestionResultDao.getAssessmentQuestionResultByUid(questionResultUid); + String answer = questionRes.getAnswer(); //adding if (previousOptionUid.equals(-1L)) { @@ -1435,12 +1440,55 @@ } } } + assessmentResultDao.flush(); //recalculate marks for all lessons in all cases except for reshuffling inside the same container if (!targetOptionUid.equals(previousOptionUid)) { - //TODO - //recalculateUserAnswers(assessmentUid, toolContentId, oldQuestions, newQuestions, oldReferences, newReferences); + + // get all finished user results + List assessmentResults = assessmentResultDao + .getAssessmentResultsByQbQuestion(qbQuestion.getUid()); + //stores userId->lastFinishedAssessmentResult + Map lastFinishedAssessmentResults = new LinkedHashMap<>(); + for (AssessmentResult assessmentResult : assessmentResults) { + Long userId = assessmentResult.getUser().getUserId(); + lastFinishedAssessmentResults.put(userId, assessmentResult); + } + + for (AssessmentResult assessmentResult : assessmentResults) { + AssessmentUser user = assessmentResult.getUser(); + float assessmentMark = assessmentResult.getGrade(); + int assessmentMaxMark = assessmentResult.getMaximumGrade(); + + for (AssessmentQuestionResult questionResult : assessmentResult.getQuestionResults()) { + if (questionResult.getQbQuestion().getUid().equals(qbQuestion.getUid())) { + Float oldQuestionAnswerMark = questionResult.getMark(); + int oldResultMaxMark = questionResult.getMaxMark() == null ? 0 + : questionResult.getMaxMark().intValue(); + + //actually recalculate marks + QuestionDTO questionDto = new QuestionDTO(assessmentQuestion); + questionDto.setMaxMark(oldResultMaxMark); + loadupQuestionResultIntoQuestionDto(questionDto, questionResult); + calculateAnswerMark(assessmentResult.getAssessment().getUid(), user.getUserId(), questionResult, + questionDto); + assessmentQuestionResultDao.saveObject(questionResult); + + float newQuestionAnswerMark = questionResult.getMark(); + assessmentMark += newQuestionAnswerMark - oldQuestionAnswerMark; + break; + } + } + + // store new mark and maxMark if they were changed + AssessmentResult lastFinishedAssessmentResult = lastFinishedAssessmentResults.get(user.getUserId()); + storeAssessmentResultMarkAndMaxMark(assessmentResult, lastFinishedAssessmentResult, assessmentMark, + assessmentMaxMark, user); + } + + //recalculate marks in all Scratchie activities, that use modified QbQuestion + toolService.recalculateScratchieMarksForVsaQuestion(qbQuestion.getUid()); } } @@ -2396,7 +2444,7 @@ //update questionResult's qbQuestion with the new one questionResult.setQbToolQuestion(modifiedQuestion); - //update questionResult's qbOption + //update questionResult's qbOption - it seems to be redundant, as it's done in loadupQuestionResultIntoQuestionDto() // for (QbOption newOption : modifiedQuestion.getQbQuestion().getQbOptions()) { // if (questionResult.getQbOption().getDisplayOrder() == newOption.getDisplayOrder()) { // questionResult.setQbOption(newOption); @@ -2509,30 +2557,37 @@ } // store new mark and maxMark if they were changed - if ((assessmentResult.getGrade() != assessmentMark) - || (assessmentResult.getMaximumGrade() != assessmentMaxMark)) { + storeAssessmentResultMarkAndMaxMark(assessmentResult, lastFinishedAssessmentResult, assessmentMark, + assessmentMaxMark, user); + } + } + } + } + + /** + * Store new mark and maxMark if they were changed + */ + private void storeAssessmentResultMarkAndMaxMark(AssessmentResult assessmentResult, AssessmentResult lastFinishedAssessmentResult, + float newAssessmentMark, int newAssessmentMaxMark, AssessmentUser user) { + // store new mark and maxMark if they were changed + if ((assessmentResult.getGrade() != newAssessmentMark) + || (assessmentResult.getMaximumGrade() != newAssessmentMaxMark)) { - // marks can't be below zero - assessmentMark = (assessmentMark < 0) ? 0 : assessmentMark; - assessmentMaxMark = (assessmentMaxMark < 0) ? 0 : assessmentMaxMark; + // marks can't be below zero + newAssessmentMark = (newAssessmentMark < 0) ? 0 : newAssessmentMark; + newAssessmentMaxMark = (newAssessmentMaxMark < 0) ? 0 : newAssessmentMaxMark; - assessmentResult.setGrade(assessmentMark); - assessmentResult.setMaximumGrade(assessmentMaxMark); - assessmentResultDao.saveObject(assessmentResult); + assessmentResult.setGrade(newAssessmentMark); + assessmentResult.setMaximumGrade(newAssessmentMaxMark); + assessmentResultDao.saveObject(assessmentResult); - // if this is the last finished assessment result - propagade total mark to Gradebook - if (lastFinishedAssessmentResult != null - && lastFinishedAssessmentResult.getUid().equals(assessmentResult.getUid())) { - toolService.updateActivityMark(Double.valueOf(assessmentMark), null, - user.getUserId().intValue(), toolSessionId, false); - } - } - - } - + // if this is the last finished assessment result - propagade total mark to Gradebook + if (lastFinishedAssessmentResult != null + && lastFinishedAssessmentResult.getUid().equals(assessmentResult.getUid())) { + toolService.updateActivityMark(Double.valueOf(newAssessmentMark), null, user.getUserId().intValue(), + user.getSession().getSessionId(), false); } } - } @Override Index: lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/dao/ScratchieSessionDAO.java =================================================================== diff -u -r7475d08afc280b5e2e5ddf04e8bf35e3166aaf80 -r122ff0d8419be3fac72ddb842cbbce1cea01e542 --- lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/dao/ScratchieSessionDAO.java (.../ScratchieSessionDAO.java) (revision 7475d08afc280b5e2e5ddf04e8bf35e3166aaf80) +++ lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/dao/ScratchieSessionDAO.java (.../ScratchieSessionDAO.java) (revision 122ff0d8419be3fac72ddb842cbbce1cea01e542) @@ -44,8 +44,15 @@ void deleteBySessionId(Long toolSessionId); List getRawLeaderMarksByToolContentId(Long toolContentId); + Object[] getStatsMarksForLeaders(Long toolContentId); + /** + * Returns all session ids where specified qbQuestionUid is used. + * + * @param qbQuestionUid + * @return + */ + List getSessionIdsByQbQuestion(Long qbQuestionUid); - } Index: lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/dao/hibernate/ScratchieSessionDAOHibernate.java =================================================================== diff -u -r22ca3de0e9fe138e44fc36be1abc6fabbbdc4002 -r122ff0d8419be3fac72ddb842cbbce1cea01e542 --- lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/dao/hibernate/ScratchieSessionDAOHibernate.java (.../ScratchieSessionDAOHibernate.java) (revision 22ca3de0e9fe138e44fc36be1abc6fabbbdc4002) +++ lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/dao/hibernate/ScratchieSessionDAOHibernate.java (.../ScratchieSessionDAOHibernate.java) (revision 122ff0d8419be3fac72ddb842cbbce1cea01e542) @@ -29,10 +29,13 @@ import java.util.TreeSet; import org.hibernate.query.NativeQuery; +import org.hibernate.query.Query; import org.hibernate.type.FloatType; import org.hibernate.type.IntegerType; import org.lamsfoundation.lams.dao.hibernate.LAMSBaseDAO; import org.lamsfoundation.lams.tool.scratchie.dao.ScratchieSessionDAO; +import org.lamsfoundation.lams.tool.scratchie.model.Scratchie; +import org.lamsfoundation.lams.tool.scratchie.model.ScratchieItem; import org.lamsfoundation.lams.tool.scratchie.model.ScratchieSession; import org.lamsfoundation.lams.tool.scratchie.util.ScratchieSessionComparator; import org.springframework.stereotype.Repository; @@ -109,4 +112,15 @@ } } + @Override + public List getSessionIdsByQbQuestion(Long qbQuestionUid) { + final String FIND_BY_QBQUESTION_AND_FINISHED = "SELECT DISTINCT session.sessionId FROM " + Scratchie.class.getName() + + " AS scratchie, " + ScratchieItem.class.getName() + " AS item, " + ScratchieSession.class.getName() + + " AS session " + + " WHERE session.scratchie.uid = scratchie.uid AND scratchie.uid = item.scratchieUid AND item.qbQuestion.uid =:qbQuestionUid"; + + Query q = getSession().createQuery(FIND_BY_QBQUESTION_AND_FINISHED, Long.class); + q.setParameter("qbQuestionUid", qbQuestionUid); + return q.list(); + } } Index: lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/model/ScratchieItem.java =================================================================== diff -u -re8a7110708b15579af2c6b31ac52a6da427fef6d -r122ff0d8419be3fac72ddb842cbbce1cea01e542 --- lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/model/ScratchieItem.java (.../ScratchieItem.java) (revision e8a7110708b15579af2c6b31ac52a6da427fef6d) +++ lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/model/ScratchieItem.java (.../ScratchieItem.java) (revision 122ff0d8419be3fac72ddb842cbbce1cea01e542) @@ -27,6 +27,7 @@ import java.util.LinkedList; import java.util.List; +import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.Table; @@ -51,6 +52,9 @@ private static final long serialVersionUID = -2824051249870361117L; private static final Logger log = Logger.getLogger(ScratchieItem.class); + + @Column(name = "scratchie_uid") + private Long scratchieUid; // ************************ DTO fields *********************** @Transient Index: lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/model/ScratchieSession.java =================================================================== diff -u -rfba7287887f6dd83d3098100af6320cccf1f3e36 -r122ff0d8419be3fac72ddb842cbbce1cea01e542 --- lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/model/ScratchieSession.java (.../ScratchieSession.java) (revision fba7287887f6dd83d3098100af6320cccf1f3e36) +++ lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/model/ScratchieSession.java (.../ScratchieSession.java) (revision 122ff0d8419be3fac72ddb842cbbce1cea01e542) @@ -79,10 +79,6 @@ @Column private int status; - @OneToMany(cascade = CascadeType.ALL) - @JoinColumn(name = "session_uid") - private Set scratchieItems = new HashSet<>(); - @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "group_leader_uid") private ScratchieUser groupLeader; @@ -169,14 +165,6 @@ this.sessionName = sessionName; } - public Set getScratchieItems() { - return scratchieItems; - } - - public void setScratchieItems(Set scratchieItems) { - this.scratchieItems = scratchieItems; - } - public ScratchieUser getGroupLeader() { return this.groupLeader; } Index: lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/IScratchieService.java =================================================================== diff -u -re8a7110708b15579af2c6b31ac52a6da427fef6d -r122ff0d8419be3fac72ddb842cbbce1cea01e542 --- lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/IScratchieService.java (.../IScratchieService.java) (revision e8a7110708b15579af2c6b31ac52a6da427fef6d) +++ lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/IScratchieService.java (.../IScratchieService.java) (revision 122ff0d8419be3fac72ddb842cbbce1cea01e542) @@ -255,8 +255,6 @@ * @param scratchieItemList */ Collection getItemsWithIndicatedScratches(Long toolSessionId); - - boolean isItemUnraveledByAnswers(ScratchieItem item, List userAnswers); /** * Leader has scratched the specified answer. Will store this scratch for all users in his group. It will also Index: lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/ScratchieServiceImpl.java =================================================================== diff -u -re8a7110708b15579af2c6b31ac52a6da427fef6d -r122ff0d8419be3fac72ddb842cbbce1cea01e542 --- lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/ScratchieServiceImpl.java (.../ScratchieServiceImpl.java) (revision e8a7110708b15579af2c6b31ac52a6da427fef6d) +++ lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/ScratchieServiceImpl.java (.../ScratchieServiceImpl.java) (revision 122ff0d8419be3fac72ddb842cbbce1cea01e542) @@ -97,6 +97,7 @@ import org.lamsfoundation.lams.tool.scratchie.model.ScratchieSession; import org.lamsfoundation.lams.tool.scratchie.model.ScratchieUser; import org.lamsfoundation.lams.tool.scratchie.util.ScratchieItemComparator; +import org.lamsfoundation.lams.tool.service.ICommonScratchieService; import org.lamsfoundation.lams.tool.service.ILamsToolService; import org.lamsfoundation.lams.usermanagement.User; import org.lamsfoundation.lams.usermanagement.dto.UserDTO; @@ -113,7 +114,7 @@ * @author Andrey Balan */ public class ScratchieServiceImpl - implements IScratchieService, ToolContentManager, ToolSessionManager, ToolRestManager { + implements IScratchieService, ICommonScratchieService, ToolContentManager, ToolSessionManager, ToolRestManager { private static Logger log = Logger.getLogger(ScratchieServiceImpl.class.getName()); private static final ExcelCell[] EMPTY_ROW = new ExcelCell[4]; @@ -468,7 +469,7 @@ @Override public void recalculateMarkForSession(Long sessionId, boolean isPropagateToGradebook) { List userLogs = scratchieAnswerVisitDao.getLogsBySession(sessionId); - ScratchieSession session = this.getScratchieSessionBySessionId(sessionId); + ScratchieSession session = getScratchieSessionBySessionId(sessionId); Scratchie scratchie = session.getScratchie(); Set items = scratchie.getScratchieItems(); String[] presetMarks = getPresetMarks(scratchie); @@ -477,7 +478,7 @@ int mark = 0; if (!items.isEmpty()) { for (ScratchieItem item : items) { - mark += getUserMarkPerItem(scratchie, item, userLogs, presetMarks); + mark += ScratchieServiceImpl.getUserMarkPerItem(scratchie, item, userLogs, presetMarks); } } @@ -487,7 +488,7 @@ // propagade changes to Gradebook if (isPropagateToGradebook) { - List users = this.getUsersBySession(sessionId); + List users = getUsersBySession(sessionId); for (ScratchieUser user : users) { toolService.updateActivityMark(new Double(mark), null, user.getUserId().intValue(), user.getSession().getSessionId(), false); @@ -562,7 +563,15 @@ recalculateMarkForSession(toolSessionId, true); } } + } + @Override + public void recalculateScratchieMarksForVsaQuestion(Long qbQuestionUid) { + List sessionIds = scratchieSessionDao.getSessionIdsByQbQuestion(qbQuestionUid); + // recalculate marks if it's required + for (Long sessionId : sessionIds) { + recalculateMarkForSession(sessionId, true); + } } @Override @@ -781,7 +790,7 @@ optionDto.setScratched(isScratched); } - boolean isItemUnraveled = isItemUnraveled(item, userLogs); + boolean isItemUnraveled = ScratchieServiceImpl.isItemUnraveled(item, userLogs); item.setUnraveled(isItemUnraveled); } @@ -845,7 +854,7 @@ optionDto.setQbQuestionUid(itemQbQuestionUid); String answer = userLog.getAnswer(); optionDto.setAnswer(answer); - boolean isCorrect = isItemUnraveledByAnswers(item, List.of(answer)); + boolean isCorrect = ScratchieServiceImpl.isItemUnraveledByAnswers(item, List.of(answer)); optionDto.setCorrect(isCorrect); item.getOptionDtos().add(optionDto); } @@ -874,7 +883,7 @@ * uses logs from it (The main reason to have this parameter is to reduce number of queries to DB) * @return */ - private boolean isItemUnraveled(ScratchieItem item, List userLogs) { + private static boolean isItemUnraveled(ScratchieItem item, List userLogs) { boolean isItemUnraveled = false; if (QbQuestion.TYPE_MULTIPLE_CHOICE == item.getQbQuestion().getType()) { @@ -903,20 +912,19 @@ } } - isItemUnraveled = isItemUnraveledByAnswers(item, userAnswers); + isItemUnraveled = ScratchieServiceImpl.isItemUnraveledByAnswers(item, userAnswers); } return isItemUnraveled; } - @Override - public boolean isItemUnraveledByAnswers(ScratchieItem item, List userAnswers) { + public static boolean isItemUnraveledByAnswers(ScratchieItem item, List userAnswers) { QbQuestion qbQuestion = item.getQbQuestion(); QbOption correctAnswersGroup = qbQuestion.getQbOptions().get(0).getMaxMark() == 1 ? qbQuestion.getQbOptions().get(0) : qbQuestion.getQbOptions().get(1); - String[] correctAnswers = correctAnswersGroup.getName().split("\\r\\n"); + String[] correctAnswers = correctAnswersGroup.getName().strip().split("\\r\\n"); for (String correctAnswer : correctAnswers) { correctAnswer = correctAnswer.strip(); @@ -962,13 +970,13 @@ * presetMarks to reduce number of queries to DB * @return */ - private int getUserMarkPerItem(Scratchie scratchie, ScratchieItem item, List userLogs, + private static int getUserMarkPerItem(Scratchie scratchie, ScratchieItem item, List userLogs, String[] presetMarks) { int mark = 0; // add mark only if an item was unraveled - if (isItemUnraveled(item, userLogs)) { - int itemAttempts = getNumberAttemptsForItem(userLogs, item); + if (ScratchieServiceImpl.isItemUnraveled(item, userLogs)) { + int itemAttempts = ScratchieServiceImpl.getNumberAttemptsForItem(userLogs, item); String markStr = (itemAttempts <= presetMarks.length) ? presetMarks[itemAttempts - 1] : presetMarks[presetMarks.length - 1]; mark = Integer.parseInt(markStr); @@ -985,7 +993,7 @@ /** * Returns number of scraches user done for the specified item. */ - private int getNumberAttemptsForItem(List userLogs, ScratchieItem item) { + private static int getNumberAttemptsForItem(List userLogs, ScratchieItem item) { int itemAttempts = 0; for (ScratchieAnswerVisitLog userLog : userLogs) { if (userLog.getQbToolQuestion().getUid().equals(item.getUid())) { @@ -1929,9 +1937,9 @@ numberOfAttempts = itemLogs.size(); // for displaying purposes if there is no attemps we assign -1 which will be shown as "-" - mark = (numberOfAttempts == 0) ? -1 : getUserMarkPerItem(scratchie, item, logs, presetMarks); + mark = (numberOfAttempts == 0) ? -1 : ScratchieServiceImpl.getUserMarkPerItem(scratchie, item, logs, presetMarks); - isUnraveledOnFirstAttempt = (numberOfAttempts == 1) && isItemUnraveled(item, logs); + isUnraveledOnFirstAttempt = (numberOfAttempts == 1) && ScratchieServiceImpl.isItemUnraveled(item, logs); // find out options' sequential letters - A,B,C... for (ScratchieAnswerVisitLog itemAttempt : itemLogs) { Index: lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/controller/LearningController.java =================================================================== diff -u -re8a7110708b15579af2c6b31ac52a6da427fef6d -r122ff0d8419be3fac72ddb842cbbce1cea01e542 --- lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/controller/LearningController.java (.../LearningController.java) (revision e8a7110708b15579af2c6b31ac52a6da427fef6d) +++ lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/controller/LearningController.java (.../LearningController.java) (revision 122ff0d8419be3fac72ddb842cbbce1cea01e542) @@ -60,6 +60,7 @@ import org.lamsfoundation.lams.tool.scratchie.model.ScratchieUser; import org.lamsfoundation.lams.tool.scratchie.service.IScratchieService; import org.lamsfoundation.lams.tool.scratchie.service.ScratchieApplicationException; +import org.lamsfoundation.lams.tool.scratchie.service.ScratchieServiceImpl; import org.lamsfoundation.lams.tool.scratchie.web.form.ReflectionForm; import org.lamsfoundation.lams.usermanagement.User; import org.lamsfoundation.lams.usermanagement.dto.UserDTO; @@ -418,7 +419,7 @@ // Return whether option is correct or not ScratchieItem item = scratchieService.getScratchieItemByUid(itemUid); - boolean isAnswerCorrect = scratchieService.isItemUnraveledByAnswers(item, List.of(answer)); + boolean isAnswerCorrect = ScratchieServiceImpl.isItemUnraveledByAnswers(item, List.of(answer)); ObjectNode objectNode = JsonNodeFactory.instance.objectNode(); objectNode.put("isAnswerCorrect", isAnswerCorrect); Index: lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/controller/MonitoringController.java =================================================================== diff -u -re8a7110708b15579af2c6b31ac52a6da427fef6d -r122ff0d8419be3fac72ddb842cbbce1cea01e542 --- lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/controller/MonitoringController.java (.../MonitoringController.java) (revision e8a7110708b15579af2c6b31ac52a6da427fef6d) +++ lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/controller/MonitoringController.java (.../MonitoringController.java) (revision 122ff0d8419be3fac72ddb842cbbce1cea01e542) @@ -85,7 +85,6 @@ @RequestMapping("/summary") private String summary(HttpServletRequest request) { - // initialize Session Map SessionMap sessionMap = new SessionMap<>(); request.getSession().setAttribute(sessionMap.getSessionID(), sessionMap); @@ -138,7 +137,6 @@ @RequestMapping("/itemSummary") private String itemSummary(HttpServletRequest request) { - String sessionMapID = request.getParameter(ScratchieConstants.ATTR_SESSION_MAP_ID); SessionMap sessionMap = (SessionMap) request.getSession() .getAttribute(sessionMapID); @@ -171,7 +169,6 @@ @RequestMapping("/saveUserMark") private String saveUserMark(HttpServletRequest request) { - if ((request.getParameter(ScratchieConstants.PARAM_NOT_A_NUMBER) == null) && !StringUtils.isEmpty(request.getParameter(ScratchieConstants.ATTR_USER_ID)) && !StringUtils.isEmpty(request.getParameter(ScratchieConstants.PARAM_SESSION_ID))) {