Index: lams_central/conf/language/lams/ApplicationResources.properties
===================================================================
diff -u -rd578cfde655760533b6ede422e7cf675a8c4ca6d -rf0ff6bc30e8fa7e5d4201b7b9571194845ad3a83
--- lams_central/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision d578cfde655760533b6ede422e7cf675a8c4ca6d)
+++ lams_central/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision f0ff6bc30e8fa7e5d4201b7b9571194845ad3a83)
@@ -1001,6 +1001,7 @@
label.authoring.short.answer.yes.case.must.match = Yes, case must match
label.authoring.short.answer.case.sensitivity = Case sensitivity
label.authoring.short.answer.add.answer = Add another answer
+label.authoring.short.answer.exact.match = Learner answer must exactly match expected answer
label.authoring.true.false.question = True/False question
label.authoring.true.false.correct.answer = Correct answer
label.authoring.true.false.feedback.on.true = Feedback for the response 'True'.
Index: lams_central/src/java/org/lamsfoundation/lams/web/qb/EditQbQuestionController.java
===================================================================
diff -u -rd4ca48e53c792f5021279765d8263ebdbd516339 -rf0ff6bc30e8fa7e5d4201b7b9571194845ad3a83
--- lams_central/src/java/org/lamsfoundation/lams/web/qb/EditQbQuestionController.java (.../EditQbQuestionController.java) (revision d4ca48e53c792f5021279765d8263ebdbd516339)
+++ lams_central/src/java/org/lamsfoundation/lams/web/qb/EditQbQuestionController.java (.../EditQbQuestionController.java) (revision f0ff6bc30e8fa7e5d4201b7b9571194845ad3a83)
@@ -135,6 +135,7 @@
form.setShuffle(qbQuestion.isShuffle());
form.setPrefixAnswersWithLetters(qbQuestion.isPrefixAnswersWithLetters());
form.setCaseSensitive(qbQuestion.isCaseSensitive());
+ form.setExactMatch(qbQuestion.isExactMatch());
form.setCorrectAnswer(qbQuestion.getCorrectAnswer());
form.setAllowRichEditor(qbQuestion.isAllowRichEditor());
form.setMaxWordsLimit(qbQuestion.getMaxWordsLimit());
Index: lams_central/web/qb/authoring/addVsa.jsp
===================================================================
diff -u -re2a265f5d454af5c8e05cc4d0fc0b635a8cb6d1b -rf0ff6bc30e8fa7e5d4201b7b9571194845ad3a83
--- lams_central/web/qb/authoring/addVsa.jsp (.../addVsa.jsp) (revision e2a265f5d454af5c8e05cc4d0fc0b635a8cb6d1b)
+++ lams_central/web/qb/authoring/addVsa.jsp (.../addVsa.jsp) (revision f0ff6bc30e8fa7e5d4201b7b9571194845ad3a83)
@@ -190,6 +190,16 @@
+
+
+
+
+
Index: lams_common/src/java/org/lamsfoundation/lams/dbupdates/patch20220411.sql
===================================================================
diff -u
--- lams_common/src/java/org/lamsfoundation/lams/dbupdates/patch20220411.sql (revision 0)
+++ lams_common/src/java/org/lamsfoundation/lams/dbupdates/patch20220411.sql (revision f0ff6bc30e8fa7e5d4201b7b9571194845ad3a83)
@@ -0,0 +1,15 @@
+-- Turn off autocommit, so nothing is committed if there is an error
+SET AUTOCOMMIT = 0;
+SET FOREIGN_KEY_CHECKS=0;
+-- Put all sql statements below here
+
+--LDEV-5307 Allow exact matching of VSAs
+
+ALTER TABLE lams_qb_question ADD COLUMN exact_match TINYINT NOT NULL DEFAULT 0 AFTER case_sensitive;
+
+-- Put all sql statements above here
+
+-- If there were no errors, commit and restore autocommit to on
+COMMIT;
+SET AUTOCOMMIT = 1;
+SET FOREIGN_KEY_CHECKS=1;
Index: lams_common/src/java/org/lamsfoundation/lams/qb/QbUtils.java
===================================================================
diff -u -rb0a4fbc85e1574ef3efe06a1020b84e2d7c7a75e -rf0ff6bc30e8fa7e5d4201b7b9571194845ad3a83
--- lams_common/src/java/org/lamsfoundation/lams/qb/QbUtils.java (.../QbUtils.java) (revision b0a4fbc85e1574ef3efe06a1020b84e2d7c7a75e)
+++ lams_common/src/java/org/lamsfoundation/lams/qb/QbUtils.java (.../QbUtils.java) (revision f0ff6bc30e8fa7e5d4201b7b9571194845ad3a83)
@@ -89,29 +89,31 @@
form.setOldCollectionUid(collectionUid);
}
- public static String normaliseVSAnswer(String answer) {
+ public static String normaliseVSAnswer(String answer, boolean isExactMatch) {
if (StringUtils.isBlank(answer)) {
return null;
}
- String normalisedAnswer = answer.replaceAll(VSA_ANSWER_NORMALISE_JAVA_REG_EXP, "");
+ String normalisedAnswer = isExactMatch ? answer.strip()
+ : answer.replaceAll(VSA_ANSWER_NORMALISE_JAVA_REG_EXP, "");
if (StringUtils.isBlank(normalisedAnswer)) {
return null;
}
return normalisedAnswer;
}
- public static Set
normaliseVSOption(String option) {
+ public static Set normaliseVSOption(String option, boolean isExactMatch) {
return StringUtils.isBlank(option) ? Set.of()
: Stream.of(option.split(VSA_ANSWER_DELIMITER)).filter(StringUtils::isNotBlank)
- .map(answer -> QbUtils.normaliseVSAnswer(answer)).filter(StringUtils::isNotBlank)
+ .map(answer -> QbUtils.normaliseVSAnswer(answer, isExactMatch)).filter(StringUtils::isNotBlank)
.collect(Collectors.toCollection(LinkedHashSet::new));
}
- public static boolean isVSAnswerAllocated(String option, String normalisedAnswer, boolean isCaseSensitive) {
+ public static boolean isVSAnswerAllocated(String option, String normalisedAnswer, boolean isCaseSensitive,
+ boolean isExactMatch) {
if (StringUtils.isBlank(option) || StringUtils.isBlank(normalisedAnswer)) {
return false;
}
- return QbUtils.normaliseVSOption(option).stream()
+ return QbUtils.normaliseVSOption(option, isExactMatch).stream()
.anyMatch(s -> isCaseSensitive ? s.equals(normalisedAnswer) : s.equalsIgnoreCase(normalisedAnswer));
}
@@ -122,7 +124,9 @@
* is an accumulator for unallocated answers so they do not appear in VSA allocation UI twice
*/
public static boolean isVSAnswerAllocated(QbQuestion qbQuestion, String answer, Set notAllocatedAnswers) {
- String normalisedAnswer = QbUtils.normaliseVSAnswer(answer);
+ boolean isExactMatch = qbQuestion.isExactMatch();
+
+ String normalisedAnswer = QbUtils.normaliseVSAnswer(answer, isExactMatch);
if (StringUtils.isBlank(normalisedAnswer)) {
return false;
}
@@ -132,7 +136,8 @@
for (QbOption option : qbQuestion.getQbOptions()) {
String name = option.getName();
- isAnswerAllocated = QbUtils.isVSAnswerAllocated(name, normalisedAnswer, isQuestionCaseSensitive);
+ isAnswerAllocated = QbUtils.isVSAnswerAllocated(name, normalisedAnswer, isQuestionCaseSensitive,
+ isExactMatch);
if (isAnswerAllocated) {
break;
}
Index: lams_common/src/java/org/lamsfoundation/lams/qb/form/QbQuestionForm.java
===================================================================
diff -u -r6bab11b98a1dfdcebfb7e11b8dcfab3128a2ff83 -rf0ff6bc30e8fa7e5d4201b7b9571194845ad3a83
--- lams_common/src/java/org/lamsfoundation/lams/qb/form/QbQuestionForm.java (.../QbQuestionForm.java) (revision 6bab11b98a1dfdcebfb7e11b8dcfab3128a2ff83)
+++ lams_common/src/java/org/lamsfoundation/lams/qb/form/QbQuestionForm.java (.../QbQuestionForm.java) (revision f0ff6bc30e8fa7e5d4201b7b9571194845ad3a83)
@@ -56,6 +56,7 @@
private boolean shuffle;
private boolean prefixAnswersWithLetters;
private boolean caseSensitive;
+ private boolean exactMatch;
private boolean correctAnswer;
private boolean allowRichEditor;
private int maxWordsLimit;
@@ -216,6 +217,14 @@
this.caseSensitive = caseSensitive;
}
+ public boolean isExactMatch() {
+ return exactMatch;
+ }
+
+ public void setExactMatch(boolean exactMatch) {
+ this.exactMatch = exactMatch;
+ }
+
public boolean isCorrectAnswer() {
return correctAnswer;
}
Index: lams_common/src/java/org/lamsfoundation/lams/qb/model/QbQuestion.java
===================================================================
diff -u -r59390e4bf349a52e22884134d890724cac1440be -rf0ff6bc30e8fa7e5d4201b7b9571194845ad3a83
--- lams_common/src/java/org/lamsfoundation/lams/qb/model/QbQuestion.java (.../QbQuestion.java) (revision 59390e4bf349a52e22884134d890724cac1440be)
+++ lams_common/src/java/org/lamsfoundation/lams/qb/model/QbQuestion.java (.../QbQuestion.java) (revision f0ff6bc30e8fa7e5d4201b7b9571194845ad3a83)
@@ -130,6 +130,9 @@
@Column(name = "case_sensitive")
private boolean caseSensitive;
+ @Column(name = "exact_match")
+ private boolean exactMatch;
+
@Column(name = "correct_answer")
private boolean correctAnswer;
@@ -448,6 +451,14 @@
this.caseSensitive = caseSensitive;
}
+ public boolean isExactMatch() {
+ return exactMatch;
+ }
+
+ public void setExactMatch(boolean exactMatch) {
+ this.exactMatch = exactMatch;
+ }
+
public boolean getCorrectAnswer() {
return correctAnswer;
}
Index: lams_common/src/java/org/lamsfoundation/lams/qb/service/QbService.java
===================================================================
diff -u -rb0a4fbc85e1574ef3efe06a1020b84e2d7c7a75e -rf0ff6bc30e8fa7e5d4201b7b9571194845ad3a83
--- lams_common/src/java/org/lamsfoundation/lams/qb/service/QbService.java (.../QbService.java) (revision b0a4fbc85e1574ef3efe06a1020b84e2d7c7a75e)
+++ lams_common/src/java/org/lamsfoundation/lams/qb/service/QbService.java (.../QbService.java) (revision f0ff6bc30e8fa7e5d4201b7b9571194845ad3a83)
@@ -815,14 +815,16 @@
@Override
public Long allocateVSAnswerToOption(Long toolQuestionUid, Long targetOptionUid, Long previousOptionUid,
String answer) {
- String normalisedAnswer = QbUtils.normaliseVSAnswer(answer);
+ QbToolQuestion toolQuestion = qbDAO.find(QbToolQuestion.class, toolQuestionUid);
+ QbQuestion qbQuestion = toolQuestion.getQbQuestion();
+ boolean isExactMatch = qbQuestion.isExactMatch();
+
+ String normalisedAnswer = QbUtils.normaliseVSAnswer(answer, isExactMatch);
if (normalisedAnswer == null && previousOptionUid.equals(-1L)) {
return null;
}
answer = answer.strip();
- QbToolQuestion toolQuestion = qbDAO.find(QbToolQuestion.class, toolQuestionUid);
- QbQuestion qbQuestion = toolQuestion.getQbQuestion();
Long qbQuestionUid = qbQuestion.getUid();
boolean isQuestionCaseSensitive = qbQuestion.isCaseSensitive();
@@ -834,8 +836,8 @@
if (previousOptionUid.equals(-1L)) {
// new allocation, check if the answer was not allocated anywhere already
String name = option.getName();
- boolean isAnswerAllocated = QbUtils.isVSAnswerAllocated(name, normalisedAnswer,
- isQuestionCaseSensitive);
+ boolean isAnswerAllocated = QbUtils.isVSAnswerAllocated(name, normalisedAnswer, isQuestionCaseSensitive,
+ isExactMatch);
if (isAnswerAllocated) {
return option.getUid();
}
@@ -862,7 +864,7 @@
Set nameWithoutUserAnswer = new LinkedHashSet<>(List.of(alternatives));
nameWithoutUserAnswer.remove(answer);
name = nameWithoutUserAnswer.isEmpty() ? ""
- : nameWithoutUserAnswer.stream().filter(a -> QbUtils.normaliseVSAnswer(a) != null)
+ : nameWithoutUserAnswer.stream().filter(a -> QbUtils.normaliseVSAnswer(a, isExactMatch) != null)
.collect(Collectors.joining(QbUtils.VSA_ANSWER_DELIMITER));
previousOption.setName(name);
qbDAO.update(previousOption);
@@ -877,7 +879,8 @@
if (targetOption != null) {
String name = targetOption.getName();
- boolean isAnswerAllocated = QbUtils.isVSAnswerAllocated(name, normalisedAnswer, isQuestionCaseSensitive);
+ boolean isAnswerAllocated = QbUtils.isVSAnswerAllocated(name, normalisedAnswer, isQuestionCaseSensitive,
+ isExactMatch);
if (isAnswerAllocated) {
// the answer has been already allocated to the target option
return targetOptionUid;
@@ -945,6 +948,7 @@
} else if ((type == QbQuestion.TYPE_VERY_SHORT_ANSWERS)) {
qbQuestion.setPenaltyFactor(Float.parseFloat(form.getPenaltyFactor()));
qbQuestion.setCaseSensitive(form.isCaseSensitive());
+ qbQuestion.setExactMatch(form.isExactMatch());
qbQuestion.setAutocompleteEnabled(form.isAutocompleteEnabled());
} else if ((type == QbQuestion.TYPE_NUMERICAL)) {
Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dao/hibernate/AssessmentResultDAOHibernate.java
===================================================================
diff -u -rb8e5c281efce81034ea2675a610ba3ea8faa41fb -rf0ff6bc30e8fa7e5d4201b7b9571194845ad3a83
--- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dao/hibernate/AssessmentResultDAOHibernate.java (.../AssessmentResultDAOHibernate.java) (revision b8e5c281efce81034ea2675a610ba3ea8faa41fb)
+++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dao/hibernate/AssessmentResultDAOHibernate.java (.../AssessmentResultDAOHibernate.java) (revision f0ff6bc30e8fa7e5d4201b7b9571194845ad3a83)
@@ -174,16 +174,18 @@
+ (parentOrganisation == null ? ""
: " OR l.organisation.organisationId = :parentOrganisationId OR "
+ "l.organisation.parentOrganisation.organisationId = :parentOrganisationId")
- + ") AND qr.qbToolQuestion.qbQuestion.uid = :qbQuestionUid AND REGEXP_REPLACE(qr.answer, '"
- + QbUtils.VSA_ANSWER_NORMALISE_SQL_REG_EXP + "', '') = :answer ORDER BY r.startDate ASC";
+ + ") AND qr.qbToolQuestion.qbQuestion.uid = :qbQuestionUid AND "
+ + (qbToolQuestion.getQbQuestion().isExactMatch() ? "TRIM(qr.answer)"
+ : "REGEXP_REPLACE(qr.answer, '" + QbUtils.VSA_ANSWER_NORMALISE_SQL_REG_EXP + "', '')")
+ + " = :answer ORDER BY r.startDate ASC";
Query q = getSession().createQuery(FIND_BY_QBQUESTION, AssessmentResult.class);
q.setParameter("qbQuestionUid", qbToolQuestion.getQbQuestion().getUid());
q.setParameter("organisationId", organisation.getOrganisationId());
if (parentOrganisation != null) {
q.setParameter("parentOrganisationId", parentOrganisation.getOrganisationId());
}
- String normalisedAnswer = QbUtils.normaliseVSAnswer(answer);
+ String normalisedAnswer = QbUtils.normaliseVSAnswer(answer, qbToolQuestion.getQbQuestion().isExactMatch());
q.setParameter("answer", normalisedAnswer);
return q.list();
}
Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dto/QuestionDTO.java
===================================================================
diff -u -r236d0e362fd2af8ffee9d0f447bf148063bd5497 -rf0ff6bc30e8fa7e5d4201b7b9571194845ad3a83
--- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dto/QuestionDTO.java (.../QuestionDTO.java) (revision 236d0e362fd2af8ffee9d0f447bf148063bd5497)
+++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/dto/QuestionDTO.java (.../QuestionDTO.java) (revision f0ff6bc30e8fa7e5d4201b7b9571194845ad3a83)
@@ -51,6 +51,8 @@
private boolean caseSensitive;
+ private boolean exactMatch;
+
private boolean correctAnswer;
private boolean allowRichEditor;
@@ -139,6 +141,7 @@
this.shuffle = qbQuestion.isShuffle();
this.prefixAnswersWithLetters = qbQuestion.isPrefixAnswersWithLetters();
this.caseSensitive = qbQuestion.isCaseSensitive();
+ this.exactMatch = qbQuestion.isExactMatch();
this.correctAnswer = qbQuestion.getCorrectAnswer();
this.allowRichEditor = qbQuestion.isAllowRichEditor();
this.maxWordsLimit = qbQuestion.getMaxWordsLimit();
@@ -296,6 +299,14 @@
this.caseSensitive = caseSensitive;
}
+ public boolean isExactMatch() {
+ return exactMatch;
+ }
+
+ public void setExactMatch(boolean exactMatch) {
+ this.exactMatch = exactMatch;
+ }
+
public boolean getCorrectAnswer() {
return correctAnswer;
}
Index: lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java
===================================================================
diff -u -rb8e5c281efce81034ea2675a610ba3ea8faa41fb -rf0ff6bc30e8fa7e5d4201b7b9571194845ad3a83
--- lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java (.../AssessmentServiceImpl.java) (revision b8e5c281efce81034ea2675a610ba3ea8faa41fb)
+++ lams_tool_assessment/src/java/org/lamsfoundation/lams/tool/assessment/service/AssessmentServiceImpl.java (.../AssessmentServiceImpl.java) (revision f0ff6bc30e8fa7e5d4201b7b9571194845ad3a83)
@@ -842,14 +842,15 @@
if (questionDto.getAnswer() != null) {
boolean isQuestionCaseSensitive = questionDto.isCaseSensitive();
- String normalisedQuestionAnswer = QbUtils.normaliseVSAnswer(questionDto.getAnswer());
+ boolean isExactMatch = questionDto.isExactMatch();
+ String normalisedQuestionAnswer = QbUtils.normaliseVSAnswer(questionDto.getAnswer(), isExactMatch);
for (OptionDTO optionDto : questionDto.getOptionDtos()) {
// refresh latest answers from DB
QbOption qbOption = qbService.getOptionByUid(optionDto.getUid());
optionDto.setName(qbOption.getName());
boolean isAnswerAllocated = QbUtils.isVSAnswerAllocated(qbOption.getName(),
- normalisedQuestionAnswer, isQuestionCaseSensitive);
+ normalisedQuestionAnswer, isQuestionCaseSensitive, isExactMatch);
if (isAnswerAllocated) {
mark = optionDto.getMaxMark() * maxMark;
@@ -1437,7 +1438,7 @@
for (AssessmentQuestionResult questionResult : allQuestionResults) {
String answer = questionResult.getAnswer();
- if (QbUtils.normaliseVSAnswer(answer) == null) {
+ if (QbUtils.normaliseVSAnswer(answer, qbQuestion.isExactMatch()) == null) {
continue;
}
@@ -3735,6 +3736,7 @@
qbQuestion.setAllowRichEditor(
JsonUtil.optBoolean(questionJSONData, RestTags.ALLOW_RICH_TEXT_EDITOR, Boolean.FALSE));
qbQuestion.setCaseSensitive(JsonUtil.optBoolean(questionJSONData, "caseSensitive", Boolean.FALSE));
+ qbQuestion.setExactMatch(JsonUtil.optBoolean(questionJSONData, "exactMatch", Boolean.FALSE));
qbQuestion.setCorrectAnswer(JsonUtil.optBoolean(questionJSONData, "correctAnswer", Boolean.FALSE));
qbQuestion.setFeedback(JsonUtil.optString(questionJSONData, "feedback"));
qbQuestion.setFeedbackOnCorrect(JsonUtil.optString(questionJSONData, "feedbackOnCorrect"));
Index: lams_tool_scratchie/conf/language/lams/ApplicationResources.properties
===================================================================
diff -u -raf79204a6effce72a9c276513762d4d7f7d5ae1a -rf0ff6bc30e8fa7e5d4201b7b9571194845ad3a83
--- lams_tool_scratchie/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision af79204a6effce72a9c276513762d4d7f7d5ae1a)
+++ lams_tool_scratchie/conf/language/lams/ApplicationResources.properties (.../ApplicationResources.properties) (revision f0ff6bc30e8fa7e5d4201b7b9571194845ad3a83)
@@ -248,6 +248,7 @@
label.no.case.unimportant = No, case is unimportant
label.yes.case.must.match = Yes, case must match
label.case.sensitivity = Case sensitivity
+label.exact.match = Learner answer must exactly match expected answer
label.autocomplete.as.student = Autocomplete (as student types answer autocomplete with stemming from answers)
label.general.feedback = General feedback
label.authoring.choice.field.required = This field is required.
Index: lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/dao/hibernate/ScratchieSessionDAOHibernate.java
===================================================================
diff -u -rb8e5c281efce81034ea2675a610ba3ea8faa41fb -rf0ff6bc30e8fa7e5d4201b7b9571194845ad3a83
--- lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/dao/hibernate/ScratchieSessionDAOHibernate.java (.../ScratchieSessionDAOHibernate.java) (revision b8e5c281efce81034ea2675a610ba3ea8faa41fb)
+++ lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/dao/hibernate/ScratchieSessionDAOHibernate.java (.../ScratchieSessionDAOHibernate.java) (revision f0ff6bc30e8fa7e5d4201b7b9571194845ad3a83)
@@ -33,12 +33,12 @@
import org.hibernate.query.Query;
import org.lamsfoundation.lams.dao.hibernate.LAMSBaseDAO;
import org.lamsfoundation.lams.learningdesign.ToolActivity;
+import org.lamsfoundation.lams.qb.QbUtils;
import org.lamsfoundation.lams.qb.model.QbToolQuestion;
import org.lamsfoundation.lams.tool.scratchie.dao.ScratchieSessionDAO;
import org.lamsfoundation.lams.tool.scratchie.model.ScratchieAnswerVisitLog;
import org.lamsfoundation.lams.tool.scratchie.model.ScratchieItem;
import org.lamsfoundation.lams.tool.scratchie.model.ScratchieSession;
-import org.lamsfoundation.lams.tool.scratchie.service.IScratchieService;
import org.lamsfoundation.lams.tool.scratchie.util.ScratchieSessionComparator;
import org.lamsfoundation.lams.usermanagement.Organisation;
import org.lamsfoundation.lams.usermanagement.OrganisationType;
@@ -121,17 +121,18 @@
+ (parentOrganisation == null ? ""
: " OR l.organisation.organisationId = :parentOrganisationId OR "
+ "l.organisation.parentOrganisation.organisationId = :parentOrganisationId")
- + ") AND item.qbQuestion.uid =:qbQuestionUid "
- + "AND session.sessionId = visitLog.sessionId AND REGEXP_REPLACE(visitLog.answer, '"
- + IScratchieService.VSA_ANSWER_NORMALISE_SQL_REG_EXP + "', '') = :answer";
+ + ") AND item.qbQuestion.uid =:qbQuestionUid " + "AND session.sessionId = visitLog.sessionId AND "
+ + (qbToolQuestion.getQbQuestion().isExactMatch() ? "TRIM(visitLog.answer)"
+ : "REGEXP_REPLACE(visitLog.answer, '" + QbUtils.VSA_ANSWER_NORMALISE_SQL_REG_EXP + "', '')")
+ + " = :answer";
Query q = getSession().createQuery(FIND_BY_QBQUESTION_AND_FINISHED, Long.class);
q.setParameter("qbQuestionUid", qbToolQuestion.getQbQuestion().getUid());
q.setParameter("organisationId", organisation.getOrganisationId());
if (parentOrganisation != null) {
q.setParameter("parentOrganisationId", parentOrganisation.getOrganisationId());
}
- String normalisedAnswer = answer.replaceAll(IScratchieService.VSA_ANSWER_NORMALISE_JAVA_REG_EXP, "");
+ String normalisedAnswer = answer.replaceAll(QbUtils.VSA_ANSWER_NORMALISE_JAVA_REG_EXP, "");
q.setParameter("answer", normalisedAnswer);
return q.list();
}
Index: lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/IScratchieService.java
===================================================================
diff -u -red8e4fb944665c1f48832c59b95944c5b5875a78 -rf0ff6bc30e8fa7e5d4201b7b9571194845ad3a83
--- lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/IScratchieService.java (.../IScratchieService.java) (revision ed8e4fb944665c1f48832c59b95944c5b5875a78)
+++ lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/IScratchieService.java (.../IScratchieService.java) (revision f0ff6bc30e8fa7e5d4201b7b9571194845ad3a83)
@@ -56,9 +56,6 @@
*/
public interface IScratchieService extends ICommonToolService {
- public static final String VSA_ANSWER_NORMALISE_JAVA_REG_EXP = "\\W";
- public static final String VSA_ANSWER_NORMALISE_SQL_REG_EXP = "[^[:alpha:][:alnum:]_]";
-
/**
* Get Scratchie
by toolContentID.
*
@@ -408,7 +405,8 @@
* @param oldItems
* @param newItems
*/
- void recalculateUserAnswers(Scratchie scratchie, Set oldItems, Set newItems, String oldPresetMarks);
+ void recalculateUserAnswers(Scratchie scratchie, Set oldItems, Set newItems,
+ String oldPresetMarks);
void releaseFromCache(Object object);
Index: lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/ScratchieServiceImpl.java
===================================================================
diff -u -rb8e5c281efce81034ea2675a610ba3ea8faa41fb -rf0ff6bc30e8fa7e5d4201b7b9571194845ad3a83
--- lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/ScratchieServiceImpl.java (.../ScratchieServiceImpl.java) (revision b8e5c281efce81034ea2675a610ba3ea8faa41fb)
+++ lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/service/ScratchieServiceImpl.java (.../ScratchieServiceImpl.java) (revision f0ff6bc30e8fa7e5d4201b7b9571194845ad3a83)
@@ -629,7 +629,7 @@
List visitLogs = scratchieAnswerVisitDao.getVsaLogsByItem(item.getUid());
for (ScratchieAnswerVisitLog visitLog : visitLogs) {
String answer = visitLog.getAnswer();
- if (QbUtils.normaliseVSAnswer(answer) == null) {
+ if (QbUtils.normaliseVSAnswer(answer, qbQuestion.isExactMatch()) == null) {
continue;
}
@@ -1100,8 +1100,9 @@
String name = correctAnswersGroup.getName();
for (String userAnswer : userAnswers) {
- String normalisedQuestionAnswer = QbUtils.normaliseVSAnswer(userAnswer);
- if (QbUtils.isVSAnswerAllocated(name, normalisedQuestionAnswer, qbQuestion.isCaseSensitive())) {
+ String normalisedQuestionAnswer = QbUtils.normaliseVSAnswer(userAnswer, qbQuestion.isExactMatch());
+ if (QbUtils.isVSAnswerAllocated(name, normalisedQuestionAnswer, qbQuestion.isCaseSensitive(),
+ qbQuestion.isExactMatch())) {
return true;
}
}
@@ -1145,9 +1146,10 @@
for (ScratchieAnswerVisitLog userLog : userLogs) {
if (userLog.getQbToolQuestion().getUid().equals(item.getUid())) {
itemAttempts++;
- String normalisedQuestionAnswer = QbUtils.normaliseVSAnswer(userLog.getAnswer());
+ String normalisedQuestionAnswer = QbUtils.normaliseVSAnswer(userLog.getAnswer(),
+ qbQuestion.isExactMatch());
if (correctVsaOption != null && QbUtils.isVSAnswerAllocated(correctVsaOption, normalisedQuestionAnswer,
- qbQuestion.isCaseSensitive())) {
+ qbQuestion.isCaseSensitive(), qbQuestion.isExactMatch())) {
break;
}
}
Index: lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/controller/AuthoringController.java
===================================================================
diff -u -rf6247c953cc7bf9a17d4025ea8e8728ae55c11ed -rf0ff6bc30e8fa7e5d4201b7b9571194845ad3a83
--- lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/controller/AuthoringController.java (.../AuthoringController.java) (revision f6247c953cc7bf9a17d4025ea8e8728ae55c11ed)
+++ lams_tool_scratchie/src/java/org/lamsfoundation/lams/tool/scratchie/web/controller/AuthoringController.java (.../AuthoringController.java) (revision f0ff6bc30e8fa7e5d4201b7b9571194845ad3a83)
@@ -380,6 +380,7 @@
if (!isMcqQuestionType) {
form.setFeedback(qbQuestion.getFeedback());
form.setCaseSensitive(qbQuestion.isCaseSensitive());
+ form.setExactMatch(qbQuestion.isExactMatch());
form.setAutocompleteEnabled(qbQuestion.isAutocompleteEnabled());
}
@@ -531,6 +532,7 @@
if (!isMcqQuestionType) {
qbQuestion.setFeedback(form.getFeedback());
qbQuestion.setCaseSensitive(form.isCaseSensitive());
+ qbQuestion.setExactMatch(form.isExactMatch());
qbQuestion.setAutocompleteEnabled(form.isAutocompleteEnabled());
}
Index: lams_tool_scratchie/web/pages/authoring/parts/addVsa.jsp
===================================================================
diff -u -re423418cca5e77a3b54cb3be496b67abe01c4183 -rf0ff6bc30e8fa7e5d4201b7b9571194845ad3a83
--- lams_tool_scratchie/web/pages/authoring/parts/addVsa.jsp (.../addVsa.jsp) (revision e423418cca5e77a3b54cb3be496b67abe01c4183)
+++ lams_tool_scratchie/web/pages/authoring/parts/addVsa.jsp (.../addVsa.jsp) (revision f0ff6bc30e8fa7e5d4201b7b9571194845ad3a83)
@@ -144,17 +144,27 @@
-
+
+
+
+
+
+
-
+