From a8cbee775862ec7602c573c2458c4475d395273c Mon Sep 17 00:00:00 2001
From: srosse <none@none>
Date: Wed, 2 Sep 2015 12:34:29 +0200
Subject: [PATCH] OO-1668: delete LTI outcomes before deleting the course

---
 .../olat/course/nodes/BasicLTICourseNode.java | 19 +++++++++---
 .../java/org/olat/ims/lti/LTIManager.java     |  6 ++++
 .../olat/ims/lti/manager/LTIManagerImpl.java  |  8 +++++
 .../java/org/olat/ims/lti/LTIManagerTest.java | 31 +++++++++++++++++--
 4 files changed, 58 insertions(+), 6 deletions(-)

diff --git a/src/main/java/org/olat/course/nodes/BasicLTICourseNode.java b/src/main/java/org/olat/course/nodes/BasicLTICourseNode.java
index 127c1fba499..a5d4b954171 100644
--- a/src/main/java/org/olat/course/nodes/BasicLTICourseNode.java
+++ b/src/main/java/org/olat/course/nodes/BasicLTICourseNode.java
@@ -27,6 +27,7 @@ package org.olat.course.nodes;
 
 import java.util.List;
 
+import org.olat.core.CoreSpringFactory;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.stack.BreadcrumbPanel;
 import org.olat.core.gui.control.Controller;
@@ -49,6 +50,7 @@ import org.olat.course.run.navigation.NodeRunConstructionResult;
 import org.olat.course.run.scoring.ScoreEvaluation;
 import org.olat.course.run.userview.NodeEvaluation;
 import org.olat.course.run.userview.UserCourseEnvironment;
+import org.olat.ims.lti.LTIManager;
 import org.olat.ims.lti.ui.LTIResultDetailsController;
 import org.olat.modules.ModuleConfiguration;
 import org.olat.repository.RepositoryEntry;
@@ -61,6 +63,7 @@ import org.olat.resource.OLATResource;
 public class BasicLTICourseNode extends AbstractAccessableCourseNode implements AssessableCourseNode {
 
 	private static final long serialVersionUID = 2210572148308757127L;
+	private static final String translatorPackage = Util.getPackageName(LTIEditController.class);
 	private static final String TYPE = "lti";
 
 	public static final String CONFIG_KEY_AUTHORROLE = "authorRole";
@@ -144,8 +147,7 @@ public class BasicLTICourseNode extends AbstractAccessableCourseNode implements
 		if (!isValid) {
 			// FIXME: refine statusdescriptions
 			String[] params = new String[] { this.getShortTitle() };
-			String translPackage = Util.getPackageName(LTIConfigForm.class);
-			sd = new StatusDescription(StatusDescription.ERROR, NLS_ERROR_HOSTMISSING_SHORT, NLS_ERROR_HOSTMISSING_LONG, params, translPackage);
+			sd = new StatusDescription(StatusDescription.ERROR, NLS_ERROR_HOSTMISSING_SHORT, NLS_ERROR_HOSTMISSING_LONG, params, translatorPackage);
 			sd.setDescriptionForUnit(getIdent());
 			// set which pane is affected by error
 			sd.setActivateableViewIdentifier(LTIEditController.PANE_TAB_LTCONFIG);
@@ -161,8 +163,8 @@ public class BasicLTICourseNode extends AbstractAccessableCourseNode implements
 		oneClickStatusCache = null;
 		// only here we know which translator to take for translating condition
 		// error messages
-		String translatorStr = Util.getPackageName(LTIEditController.class);
-		List<StatusDescription> sds =  isConfigValidWithTranslator(cev, translatorStr, getConditionExpressions());
+		
+		List<StatusDescription> sds =  isConfigValidWithTranslator(cev, translatorPackage, getConditionExpressions());
 		oneClickStatusCache = StatusDescriptionHelper.sort(sds);
 		return oneClickStatusCache;
 	}
@@ -182,6 +184,15 @@ public class BasicLTICourseNode extends AbstractAccessableCourseNode implements
 	public boolean needsReferenceToARepositoryEntry() {
 		return false;
 	}
+	
+	/**
+	 * @see org.olat.course.nodes.CourseNode#cleanupOnDelete(org.olat.course.ICourse)
+	 */
+	@Override
+	public void cleanupOnDelete(ICourse course) {
+		OLATResource resource = course.getCourseEnvironment().getCourseGroupManager().getCourseResource();
+		CoreSpringFactory.getImpl(LTIManager.class).deleteOutcomes(resource);
+	}
 
 	/**
 	 * Update the module configuration to have all mandatory configuration flags
diff --git a/src/main/java/org/olat/ims/lti/LTIManager.java b/src/main/java/org/olat/ims/lti/LTIManager.java
index 88ec60a65e1..aa28560ab8e 100644
--- a/src/main/java/org/olat/ims/lti/LTIManager.java
+++ b/src/main/java/org/olat/ims/lti/LTIManager.java
@@ -50,5 +50,11 @@ public interface LTIManager {
 
 	public List<LTIOutcome> loadOutcomes(Identity identity, OLATResource resource, String resSubPath);
 	
+	/**
+	 * Remove the outcomes of a resource, typically before deleting a course.
+	 * @param resource
+	 */
+	public void deleteOutcomes(OLATResource resource);
+	
 
 }
diff --git a/src/main/java/org/olat/ims/lti/manager/LTIManagerImpl.java b/src/main/java/org/olat/ims/lti/manager/LTIManagerImpl.java
index bc2a0045af0..3956a5b7d39 100644
--- a/src/main/java/org/olat/ims/lti/manager/LTIManagerImpl.java
+++ b/src/main/java/org/olat/ims/lti/manager/LTIManagerImpl.java
@@ -111,6 +111,14 @@ public class LTIManagerImpl implements LTIManager {
 		}
 		return outcomes.getResultList();
 	}
+	
+	@Override
+	public void deleteOutcomes(OLATResource resource) {
+		String q = "delete from ltioutcome as outcome where outcome.resource=:resource";
+		dbInstance.getCurrentEntityManager().createQuery(q)
+			.setParameter("resource", resource)
+			.executeUpdate();
+	}
 
 	@Override
 	public Map<String,String> sign(Map<String,String> props, String url, String oauthKey, String oauthSecret) {
diff --git a/src/test/java/org/olat/ims/lti/LTIManagerTest.java b/src/test/java/org/olat/ims/lti/LTIManagerTest.java
index 051d650f910..5ed7b16ada0 100644
--- a/src/test/java/org/olat/ims/lti/LTIManagerTest.java
+++ b/src/test/java/org/olat/ims/lti/LTIManagerTest.java
@@ -96,6 +96,33 @@ public class LTIManagerTest extends OlatTestCase {
 		Assert.assertTrue(outcomes.contains(outcome2));
 	}
 	
-
-
+	@Test
+	public void deleteOutcome() {
+		Identity id = JunitTestHelper.createAndPersistIdentityAsUser("lti-3-" + UUID.randomUUID().toString());
+		OLATResource resource1 = JunitTestHelper.createRandomResource();
+		OLATResource resource2 = JunitTestHelper.createRandomResource();
+		LTIOutcome outcome1 = ltiManager.createOutcome(id, resource1, "sub", "update", "new-outcome", "lti score value");
+		LTIOutcome outcome2 = ltiManager.createOutcome(id, resource1, "sub", "delete", "new-outcome", null);
+		LTIOutcome outcome3 = ltiManager.createOutcome(id, resource2, "sub", "delete", "new-outcome", null);
+		dbInstance.commitAndCloseSession();
+		
+		//check they exist
+		List<LTIOutcome> outcomes1 = ltiManager.loadOutcomes(id, resource1, "sub");
+		Assert.assertEquals(2, outcomes1.size());
+		Assert.assertTrue(outcomes1.contains(outcome1));
+		Assert.assertTrue(outcomes1.contains(outcome2));
+		List<LTIOutcome> outcomes2 = ltiManager.loadOutcomes(id, resource2, "sub");
+		Assert.assertEquals(1, outcomes2.size());
+		
+		//delete outcomes of resource 1
+		ltiManager.deleteOutcomes(resource1);
+		dbInstance.commitAndCloseSession();
+		
+		//check that only the outcome of resource 2 survives
+		List<LTIOutcome> checkOutcomes1 = ltiManager.loadOutcomes(id, resource1, "sub");
+		Assert.assertTrue(checkOutcomes1.isEmpty());
+		List<LTIOutcome> checkOutcomes2 = ltiManager.loadOutcomes(id, resource2, "sub");
+		Assert.assertEquals(1, checkOutcomes2.size());
+		Assert.assertTrue(checkOutcomes2.contains(outcome3));
+	}
 }
-- 
GitLab