From 88b4bf05ea25e64cd270c1babd8ca4e1fac39dab Mon Sep 17 00:00:00 2001 From: srosse <none@none> Date: Mon, 9 Jul 2012 09:18:28 +0200 Subject: [PATCH] OO-305. tightly couple the submit of the assessment results to the database and to "qti.ser" --- .../ims/qti/QTIResultDetailsController.java | 6 +-- .../ims/qti/navigator/DefaultNavigator.java | 6 +++ .../ims/qti/process/AssessmentFactory.java | 16 +++++-- .../ims/qti/process/AssessmentInstance.java | 45 ++++++++++++++++++- .../olat/modules/iq/IQDisplayController.java | 10 +++-- .../java/org/olat/modules/iq/IQManager.java | 11 +++-- .../course/CourseAssessmentWebService.java | 2 +- 7 files changed, 77 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/olat/ims/qti/QTIResultDetailsController.java b/src/main/java/org/olat/ims/qti/QTIResultDetailsController.java index ef78c9b1c5d..c2f45bf0dea 100644 --- a/src/main/java/org/olat/ims/qti/QTIResultDetailsController.java +++ b/src/main/java/org/olat/ims/qti/QTIResultDetailsController.java @@ -219,12 +219,12 @@ public class QTIResultDetailsController extends BasicController { AssessableCourseNode testNode = (AssessableCourseNode)course.getRunStructure().getNode(nodeIdent); ModuleConfiguration modConfig = testNode.getModuleConfiguration(); - String resourcePathInfo = courseResourceableId + File.separator + nodeIdent; - AssessmentInstance ai = AssessmentFactory.createAssessmentInstance(assessedIdentity, modConfig, false ,resourcePathInfo); + String resourcePathInfo = courseResourceableId + File.separator + nodeIdent; + AssessmentInstance ai = AssessmentFactory.createAssessmentInstance(assessedIdentity, "", modConfig, false, courseResourceableId, nodeIdent, resourcePathInfo); //close the test ai.close(); //persist the results - iqm.persistResults(ai, courseResourceableId.longValue(), nodeIdent, assessedIdentity, ""); + iqm.persistResults(ai); //reporting Document docResReporting = iqm.getResultsReporting(ai, assessedIdentity, I18nModule.getDefaultLocale()); diff --git a/src/main/java/org/olat/ims/qti/navigator/DefaultNavigator.java b/src/main/java/org/olat/ims/qti/navigator/DefaultNavigator.java index 1b68770c63f..16bd832384c 100644 --- a/src/main/java/org/olat/ims/qti/navigator/DefaultNavigator.java +++ b/src/main/java/org/olat/ims/qti/navigator/DefaultNavigator.java @@ -36,6 +36,7 @@ import org.olat.ims.qti.container.ItemsInput; import org.olat.ims.qti.container.Output; import org.olat.ims.qti.container.SectionContext; import org.olat.ims.qti.process.AssessmentInstance; +import org.olat.modules.iq.IQManager; /** */ @@ -144,12 +145,17 @@ public class DefaultNavigator implements Serializable { public void submitAssessment() { Output pendingOutput = null; boolean pendingFeedback = getInfo().isFeedback(); + boolean alreadyClosed = getAssessmentInstance().isClosed(); if(pendingFeedback && getAssessmentInstance().getAssessmentContext().getCurrentSectionContext() != null) { ItemContext itc = getAssessmentInstance().getAssessmentContext().getCurrentSectionContext().getCurrentItemContext(); pendingOutput = itc.getOutput(); } getAssessmentInstance().close(); + if(!getAssessmentInstance().isPreview() && !alreadyClosed) { + IQManager.getInstance().persistResults(getAssessmentInstance()); + } + AssessmentContext ac = getAssessmentContext(); info.clear(); diff --git a/src/main/java/org/olat/ims/qti/process/AssessmentFactory.java b/src/main/java/org/olat/ims/qti/process/AssessmentFactory.java index 26fb86a914f..b9466cf893c 100644 --- a/src/main/java/org/olat/ims/qti/process/AssessmentFactory.java +++ b/src/main/java/org/olat/ims/qti/process/AssessmentFactory.java @@ -28,6 +28,7 @@ package org.olat.ims.qti.process; import org.olat.core.id.Identity; import org.olat.core.logging.Tracing; import org.olat.core.util.CodeHelper; +import org.olat.core.util.StringHelper; import org.olat.course.nodes.iq.IQEditController; import org.olat.modules.ModuleConfiguration; import org.olat.repository.RepositoryEntry; @@ -45,7 +46,8 @@ public class AssessmentFactory { * @param resourcePathInfo * @return */ - public static AssessmentInstance createAssessmentInstance(Identity subj, ModuleConfiguration modConfig, boolean preview, String resourcePathInfo) { + public static AssessmentInstance createAssessmentInstance(Identity subj, String remoteAddr, ModuleConfiguration modConfig, boolean preview, + long callingResId, String callingResDetail, String resourcePathInfo) { AssessmentInstance ai = null; Persister persister = null; @@ -72,7 +74,7 @@ public class AssessmentFactory { Resolver resolver = new ImsRepositoryResolver(re.getKey()); long aiID = CodeHelper.getForeverUniqueID(); try { - ai = new AssessmentInstance(re.getKey().longValue(), aiID, resolver, persister, modConfig); + ai = new AssessmentInstance(subj, remoteAddr, re.getKey().longValue(), aiID, callingResId, callingResDetail, resolver, persister, modConfig); } catch (Exception e) { return null; } } else { @@ -81,6 +83,12 @@ public class AssessmentFactory { Resolver resolver = new ImsRepositoryResolver(new Long(ai.getRepositoryEntryKey())); ai.setResolver(resolver); ai.setPersister(persister); + ai.setAssessedIdentity(subj); + ai.setCallingResId(callingResId); + ai.setCallingResDetail(callingResDetail); + if(StringHelper.containsNonWhitespace(ai.getRemoteAddr())) { + ai.setRemoteAddr(remoteAddr); + } } return ai; @@ -93,9 +101,9 @@ public class AssessmentFactory { * @param doc * @return */ - public static AssessmentInstance createAssessmentInstance(Resolver resolver, Persister persister, ModuleConfiguration modConfig) { + public static AssessmentInstance createAssessmentInstance(Identity subj, String remoteAddr, long callingResId, String callingResDetail, Resolver resolver, Persister persister, ModuleConfiguration modConfig) { long aiID = CodeHelper.getForeverUniqueID(); - return new AssessmentInstance(0, aiID, resolver, persister, modConfig); + return new AssessmentInstance(null, remoteAddr, 0, aiID, callingResId, callingResDetail, resolver, persister, modConfig); } } diff --git a/src/main/java/org/olat/ims/qti/process/AssessmentInstance.java b/src/main/java/org/olat/ims/qti/process/AssessmentInstance.java index 3a915ca9d47..e990a288a61 100644 --- a/src/main/java/org/olat/ims/qti/process/AssessmentInstance.java +++ b/src/main/java/org/olat/ims/qti/process/AssessmentInstance.java @@ -31,6 +31,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.olat.core.id.Identity; import org.olat.core.logging.AssertException; import org.olat.course.nodes.iq.IQEditController; import org.olat.ims.qti.container.AssessmentContext; @@ -54,7 +55,12 @@ public class AssessmentInstance implements Serializable { private long assessID; // the key given to this instance by the constructor; identifying the assessment within the olat context; needed after deserialisation to find the correct qti tree private long repositoryEntryKey; // the key to a repository entry private Navigator navigator; // optimise: make transient + + private long callingResId; + private String callingResDetail; private List sourceBankRefs; + private String remoteAddr; + private Identity assessedIdentity; private AssessmentContext assessmentContext; @@ -132,7 +138,12 @@ public class AssessmentInstance implements Serializable { * @param persistor the Persistor, may be null * @param modConfig */ - public AssessmentInstance(long repositoryEntryKey, long assessID, Resolver resolver, Persister persistor, ModuleConfiguration modConfig) { + public AssessmentInstance(Identity identity, String remoteAddr, long repositoryEntryKey, long assessID, long callingResId, String callingResDetail, + Resolver resolver, Persister persistor, ModuleConfiguration modConfig) { + this.assessedIdentity = identity; + this.remoteAddr = remoteAddr; + this.callingResId = callingResId; + this.callingResDetail = callingResDetail; this.repositoryEntryKey = repositoryEntryKey; this.assessID = assessID; this.resolver = resolver; @@ -203,6 +214,38 @@ public class AssessmentInstance implements Serializable { createNavigator(); } + public Identity getAssessedIdentity() { + return assessedIdentity; + } + + public void setAssessedIdentity(Identity assessedIdentity) { + this.assessedIdentity = assessedIdentity; + } + + public String getRemoteAddr() { + return remoteAddr; + } + + public void setRemoteAddr(String remoteAddr) { + this.remoteAddr = remoteAddr; + } + + public long getCallingResId() { + return callingResId; + } + + public void setCallingResId(long callingResId) { + this.callingResId = callingResId; + } + + public String getCallingResDetail() { + return callingResDetail; + } + + public void setCallingResDetail(String callingResDetail) { + this.callingResDetail = callingResDetail; + } + public int getType() { return type; } /** diff --git a/src/main/java/org/olat/modules/iq/IQDisplayController.java b/src/main/java/org/olat/modules/iq/IQDisplayController.java index 9d8403cc5c3..6dc21fc7666 100644 --- a/src/main/java/org/olat/modules/iq/IQDisplayController.java +++ b/src/main/java/org/olat/modules/iq/IQDisplayController.java @@ -261,10 +261,12 @@ public class IQDisplayController extends DefaultController implements GenericEve //try{ if (repositorySoftkey != null) { // instantiate from repository // build path information which will be used to store tempory qti file - String resourcePathInfo = this.callingResId + File.separator + this.callingResDetail; - ai = AssessmentFactory.createAssessmentInstance(ureq.getIdentity(), modConfig, iqsec.isPreview(),resourcePathInfo); + String resourcePathInfo = callingResId + File.separator + callingResDetail; + ai = AssessmentFactory.createAssessmentInstance(ureq.getIdentity(), ureq.getHttpReq().getRemoteAddr(), + modConfig, iqsec.isPreview(), callingResId, callingResDetail, resourcePathInfo); } else if (resolver != null) { // instantiate from given resolver - ai = AssessmentFactory.createAssessmentInstance(resolver, persister, modConfig); + ai = AssessmentFactory.createAssessmentInstance(ureq.getIdentity(), ureq.getHttpReq().getRemoteAddr(), + callingResId, callingResDetail, resolver, persister, modConfig); } //}finally{ //QTIEditorMainController.IS_SAVING_RWL.readLock().unlock(); @@ -528,7 +530,7 @@ public class IQDisplayController extends DefaultController implements GenericEve */ protected void postSubmitAssessment(UserRequest ureq, AssessmentInstance ai) { if (!qtistatus.isPreview()) { - iqm.persistResults(ai, callingResId, callingResDetail, ureq.getIdentity(), ureq.getHttpReq().getRemoteAddr()); + //iqm.persistResults(ai, callingResId, callingResDetail, ureq.getIdentity(), ureq.getHttpReq().getRemoteAddr()); getWindowControl().setInfo(translator.translate("status.results.saved")); } else { getWindowControl().setInfo(translator.translate("status.results.notsaved")); diff --git a/src/main/java/org/olat/modules/iq/IQManager.java b/src/main/java/org/olat/modules/iq/IQManager.java index e21fb5b107b..040336aa35d 100644 --- a/src/main/java/org/olat/modules/iq/IQManager.java +++ b/src/main/java/org/olat/modules/iq/IQManager.java @@ -317,20 +317,19 @@ public class IQManager extends BasicManager implements UserDataDeletable { * @param ureq */ - public void persistResults(AssessmentInstance ai, long resId, String resDetail, Identity assessedIdentity, String remoteAddr) { + public void persistResults(AssessmentInstance ai) { AssessmentContext ac = ai.getAssessmentContext(); QTIResultSet qtiResultSet = new QTIResultSet(); qtiResultSet.setLastModified(new Date(System.currentTimeMillis())); - qtiResultSet.setOlatResource(resId); - qtiResultSet.setOlatResourceDetail(resDetail); + qtiResultSet.setOlatResource(ai.getCallingResId()); + qtiResultSet.setOlatResourceDetail(ai.getCallingResDetail()); qtiResultSet.setRepositoryRef(ai.getRepositoryEntryKey()); - qtiResultSet.setIdentity(assessedIdentity); + qtiResultSet.setIdentity(ai.getAssessedIdentity()); qtiResultSet.setQtiType(ai.getType()); qtiResultSet.setAssessmentID(ai.getAssessID()); qtiResultSet.setDuration(new Long(ai.getAssessmentContext().getDuration())); - // TODO qtiResultSet.setLastModified(); if (ai.isSurvey()){ qtiResultSet.setScore(0); @@ -359,7 +358,7 @@ public class IQManager extends BasicManager implements UserDataDeletable { else qtiResult.setScore(ic.getScore()); qtiResult.setTstamp(new Date(ic.getLatestAnswerTime())); qtiResult.setLastModified(new Date(System.currentTimeMillis())); - qtiResult.setIp(remoteAddr); + qtiResult.setIp(ai.getRemoteAddr()); // Get user answers for this item StringBuilder sb = new StringBuilder(); diff --git a/src/main/java/org/olat/restapi/repository/course/CourseAssessmentWebService.java b/src/main/java/org/olat/restapi/repository/course/CourseAssessmentWebService.java index c0d65e7fb40..4e4c794dfca 100644 --- a/src/main/java/org/olat/restapi/repository/course/CourseAssessmentWebService.java +++ b/src/main/java/org/olat/restapi/repository/course/CourseAssessmentWebService.java @@ -358,7 +358,7 @@ public class CourseAssessmentWebService { // The consequence is that we must loop on section and items and set the // navigator on // the right position before submitting the inputs. - AssessmentInstance ai = AssessmentFactory.createAssessmentInstance(identity, modConfig, false, resourcePathInfo); + AssessmentInstance ai = AssessmentFactory.createAssessmentInstance(identity, "", modConfig, false, course.getResourceableId(), courseNode.getIdent(), resourcePathInfo); Navigator navigator = ai.getNavigator(); navigator.startAssessment(); // The type of the navigator depends on the setting of the course node -- GitLab