From 8969bab5ba716993a62e76fc4a38826d08849e11 Mon Sep 17 00:00:00 2001
From: srosse <none@none>
Date: Thu, 29 Jan 2015 12:15:01 +0100
Subject: [PATCH] OO-1411: update certificate before deleting the repository
 entry to remove the foreign key

---
 .../certificate/CertificatesManager.java      |  3 +
 .../manager/CertificatesManagerImpl.java      | 10 ++
 .../olat/repository/handlers/FileHandler.java |  1 -
 .../manager/RepositoryServiceImpl.java        |  8 +-
 .../manager/CertificatesManagerTest.java      | 97 +++++++++++++++++++
 5 files changed, 115 insertions(+), 4 deletions(-)

diff --git a/src/main/java/org/olat/course/certificate/CertificatesManager.java b/src/main/java/org/olat/course/certificate/CertificatesManager.java
index 05ca721c746..d56331cebba 100644
--- a/src/main/java/org/olat/course/certificate/CertificatesManager.java
+++ b/src/main/java/org/olat/course/certificate/CertificatesManager.java
@@ -59,6 +59,9 @@ public interface CertificatesManager {
 	
 	public void markPublisherNews(Identity ident, ICourse course);
 	
+	//repository maintenance
+	public int deleteRepositoryEntry(RepositoryEntry re);
+	
 	//templates management
 	public List<CertificateTemplate> getTemplates();
 	
diff --git a/src/main/java/org/olat/course/certificate/manager/CertificatesManagerImpl.java b/src/main/java/org/olat/course/certificate/manager/CertificatesManagerImpl.java
index ac73f7565e0..acc66bef09f 100644
--- a/src/main/java/org/olat/course/certificate/manager/CertificatesManagerImpl.java
+++ b/src/main/java/org/olat/course/certificate/manager/CertificatesManagerImpl.java
@@ -282,6 +282,16 @@ public class CertificatesManagerImpl implements CertificatesManager, MessageList
 		}
 	}
 	
+	@Override
+	public int deleteRepositoryEntry(RepositoryEntry re) {
+		StringBuilder sb = new StringBuilder();
+		sb.append("update certificate set olatResource = null where olatResource.key=:resourceKey");
+		return dbInstance.getCurrentEntityManager()
+				.createQuery(sb.toString())
+				.setParameter("resourceKey", re.getOlatResource().getKey())
+				.executeUpdate();
+	}
+
 	@Override
 	public VFSLeaf getCertificateLeaf(Certificate certificate) {
 		VFSContainer cerContainer = getCertificateRootContainer();
diff --git a/src/main/java/org/olat/repository/handlers/FileHandler.java b/src/main/java/org/olat/repository/handlers/FileHandler.java
index 0b22fe8f133..6d4180c1f3e 100644
--- a/src/main/java/org/olat/repository/handlers/FileHandler.java
+++ b/src/main/java/org/olat/repository/handlers/FileHandler.java
@@ -28,7 +28,6 @@ package org.olat.repository.handlers;
 import java.io.File;
 import java.util.Locale;
 
-import org.olat.core.gui.media.MediaResource;
 import org.olat.core.gui.translator.Translator;
 import org.olat.core.id.Identity;
 import org.olat.core.id.OLATResourceable;
diff --git a/src/main/java/org/olat/repository/manager/RepositoryServiceImpl.java b/src/main/java/org/olat/repository/manager/RepositoryServiceImpl.java
index 88d441dd948..4df22ae347c 100644
--- a/src/main/java/org/olat/repository/manager/RepositoryServiceImpl.java
+++ b/src/main/java/org/olat/repository/manager/RepositoryServiceImpl.java
@@ -51,6 +51,7 @@ import org.olat.core.util.vfs.VFSContainer;
 import org.olat.core.util.vfs.VFSItem;
 import org.olat.core.util.vfs.VFSLeaf;
 import org.olat.course.assessment.manager.UserCourseInformationsManager;
+import org.olat.course.certificate.CertificatesManager;
 import org.olat.repository.ErrorList;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryEntryAuthorView;
@@ -107,6 +108,8 @@ public class RepositoryServiceImpl implements RepositoryService {
 	@Autowired
 	private OLATResourceManager resourceManager;
 	@Autowired
+	private CertificatesManager certificatesManager;
+	@Autowired
 	private UserCourseInformationsManager userCourseInformationsManager;
 
 	@Autowired
@@ -268,6 +271,7 @@ public class RepositoryServiceImpl implements RepositoryService {
 		return null;
 	}
 	
+	@Override
 	public ErrorList delete(RepositoryEntry entry, Identity identity, Roles roles, Locale locale) {
 		ErrorList errors = new ErrorList();
 		
@@ -284,10 +288,8 @@ public class RepositoryServiceImpl implements RepositoryService {
 			return errors;
 		}
 
-		// start transaction
-		// delete entry picture
-		
 		userCourseInformationsManager.deleteUserCourseInformations(entry);
+		certificatesManager.deleteRepositoryEntry(entry);
 		
 		// delete all bookmarks referencing deleted entry
 		CoreSpringFactory.getImpl(MarkManager.class).deleteMarks(entry);
diff --git a/src/test/java/org/olat/course/certificate/manager/CertificatesManagerTest.java b/src/test/java/org/olat/course/certificate/manager/CertificatesManagerTest.java
index 1d244037145..474bc0862d2 100644
--- a/src/test/java/org/olat/course/certificate/manager/CertificatesManagerTest.java
+++ b/src/test/java/org/olat/course/certificate/manager/CertificatesManagerTest.java
@@ -25,6 +25,7 @@ import java.net.URL;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.List;
+import java.util.Locale;
 import java.util.UUID;
 
 import org.junit.Assert;
@@ -32,16 +33,19 @@ import org.junit.Test;
 import org.olat.basesecurity.GroupRoles;
 import org.olat.core.commons.persistence.DB;
 import org.olat.core.id.Identity;
+import org.olat.core.id.Roles;
 import org.olat.core.util.vfs.VFSLeaf;
 import org.olat.course.certificate.Certificate;
 import org.olat.course.certificate.CertificateLight;
 import org.olat.course.certificate.CertificateTemplate;
 import org.olat.course.certificate.CertificatesManager;
+import org.olat.course.certificate.model.CertificateImpl;
 import org.olat.course.certificate.model.CertificateInfos;
 import org.olat.group.BusinessGroup;
 import org.olat.group.BusinessGroupService;
 import org.olat.group.manager.BusinessGroupRelationDAO;
 import org.olat.repository.RepositoryEntry;
+import org.olat.repository.RepositoryService;
 import org.olat.repository.manager.RepositoryEntryRelationDAO;
 import org.olat.test.JunitTestHelper;
 import org.olat.test.OlatTestCase;
@@ -58,6 +62,8 @@ public class CertificatesManagerTest extends OlatTestCase {
 	@Autowired
 	private DB dbInstance;
 	@Autowired
+	private RepositoryService repositoryService;
+	@Autowired
 	private CertificatesManager certificatesManager;
 	@Autowired
 	private BusinessGroupService businessGroupService;
@@ -340,4 +346,95 @@ public class CertificatesManagerTest extends OlatTestCase {
 		Assert.assertEquals(certificate.getKey(), lastCertificate.getKey());
 		Assert.assertEquals(reloadedCertificate, lastCertificate);
 	}
+	
+	/**
+	 * Create a course, add a certificate to it and delete the course.
+	 * The certificate stays.
+	 * 
+	 * @throws URISyntaxException
+	 */
+	@Test
+	public void deleteCourse()  throws URISyntaxException  {
+		//create a course with a certificate
+		Identity identity = JunitTestHelper.createAndPersistIdentityAsRndUser("cer-del-2");
+		RepositoryEntry entry = JunitTestHelper.deployDemoCourse(identity);
+		dbInstance.commitAndCloseSession();
+		Long resourceKey = entry.getOlatResource().getKey();
+		
+		Calendar cal = Calendar.getInstance();
+		cal.set(Calendar.MINUTE, 0);
+		cal.set(Calendar.SECOND, 0);
+		cal.set(Calendar.MILLISECOND, 0);
+		URL certificateUrl = CertificatesManagerTest.class.getResource("template.pdf");
+		File certificateFile = new File(certificateUrl.toURI());
+		Certificate certificate = certificatesManager.uploadCertificate(identity, cal.getTime(), entry.getOlatResource(), certificateFile);
+		Assert.assertNotNull(certificate);
+		dbInstance.commitAndCloseSession();
+		
+		//delete the course
+		Roles roles = new Roles(true, false, false, false, false, false, false);
+		repositoryService.delete(entry, identity, roles, Locale.ENGLISH);
+		dbInstance.commitAndCloseSession();
+		
+		//retrieve the certificate
+		Certificate reloadedCertificate = certificatesManager.getCertificateById(certificate.getKey());
+		Assert.assertNotNull(reloadedCertificate);
+		Assert.assertEquals(certificate, reloadedCertificate);
+		Assert.assertNotNull(reloadedCertificate.getArchivedResourceKey());
+		Assert.assertEquals(resourceKey, reloadedCertificate.getArchivedResourceKey());
+	}
+	
+	
+	/**
+	 * Create 2 courses, add a certificate to them and delete the first course.
+	 * Check that a certificate loose the relation to the deleted course but not
+	 * the other. The two certificates stay.
+	 * 
+	 * @throws URISyntaxException
+	 */
+	@Test
+	public void deleteCourse_paranoiaCheck()  throws URISyntaxException  {
+		//create a course with a certificate
+		Identity identity = JunitTestHelper.createAndPersistIdentityAsRndUser("cer-del-3");
+		RepositoryEntry entryToDelete = JunitTestHelper.deployDemoCourse(identity);
+		RepositoryEntry entry = JunitTestHelper.deployDemoCourse(identity);
+		dbInstance.commitAndCloseSession();
+		Long resourceKeyToDelete = entryToDelete.getOlatResource().getKey();
+		Long resourceKey = entry.getOlatResource().getKey();
+		
+		Calendar cal = Calendar.getInstance();
+		cal.set(Calendar.MINUTE, 0);
+		cal.set(Calendar.SECOND, 0);
+		cal.set(Calendar.MILLISECOND, 0);
+		URL certificateUrl = CertificatesManagerTest.class.getResource("template.pdf");
+		File certificateFile = new File(certificateUrl.toURI());
+		//certificate linked to the course which will be deleted
+		Certificate certificateDeletedCourse = certificatesManager.uploadCertificate(identity, cal.getTime(), entryToDelete.getOlatResource(), certificateFile);
+		Assert.assertNotNull(certificateDeletedCourse);
+		//certificate of the staying course
+		Certificate certificate = certificatesManager.uploadCertificate(identity, cal.getTime(), entry.getOlatResource(), certificateFile);
+		Assert.assertNotNull(certificate);
+		dbInstance.commitAndCloseSession();
+		
+		//delete the course
+		Roles roles = new Roles(true, false, false, false, false, false, false);
+		repositoryService.delete(entryToDelete, identity, roles, Locale.ENGLISH);
+		dbInstance.commitAndCloseSession();
+		
+		//retrieve the certificate of the deleted course
+		Certificate reloadedCertificateDeletedCourse = certificatesManager.getCertificateById(certificateDeletedCourse.getKey());
+		Assert.assertNotNull(reloadedCertificateDeletedCourse);
+		Assert.assertEquals(certificateDeletedCourse, reloadedCertificateDeletedCourse);
+		Assert.assertNotNull(reloadedCertificateDeletedCourse.getArchivedResourceKey());
+		Assert.assertNull(((CertificateImpl)reloadedCertificateDeletedCourse).getOlatResource());
+		Assert.assertEquals(resourceKeyToDelete, reloadedCertificateDeletedCourse.getArchivedResourceKey());
+		
+		//retrieve the certificate of the staying course
+		Certificate reloadedCertificate = certificatesManager.getCertificateById(certificate.getKey());
+		Assert.assertNotNull(reloadedCertificate);
+		Assert.assertEquals(certificate, reloadedCertificate);
+		Assert.assertNotNull(reloadedCertificate.getArchivedResourceKey());
+		Assert.assertEquals(resourceKey, reloadedCertificate.getArchivedResourceKey());
+		Assert.assertEquals(entry.getOlatResource(), ((CertificateImpl)reloadedCertificate).getOlatResource());
+	}
 }
-- 
GitLab