From 299ad9771c97559f26d21af076b597376ea08f02 Mon Sep 17 00:00:00 2001
From: srosse <none@none>
Date: Fri, 15 Nov 2013 14:25:05 +0100
Subject: [PATCH] OO-865: implements the deletion of taxonomy levels (only if
 not used or without children)

---
 .../org/olat/modules/qpool/QPoolService.java  |  2 ++
 .../manager/QuestionPoolServiceImpl.java      |  5 +++
 .../qpool/manager/TaxonomyLevelDAO.java       | 22 +++++++++++++
 .../ui/admin/TaxonomyLevelController.java     | 32 +++++++++++++++++--
 .../qpool/ui/admin/TaxonomyTreeModel.java     |  2 +-
 .../ui/admin/_i18n/LocalStrings_de.properties |  4 +++
 .../ui/admin/_i18n/LocalStrings_en.properties |  4 +++
 .../ui/admin/_i18n/LocalStrings_fr.properties |  4 +++
 .../qpool/manager/TaxonomyLevelDAOTest.java   | 17 ++++++++++
 9 files changed, 88 insertions(+), 4 deletions(-)

diff --git a/src/main/java/org/olat/modules/qpool/QPoolService.java b/src/main/java/org/olat/modules/qpool/QPoolService.java
index f1d7fa97b4e..c20094e7ad4 100644
--- a/src/main/java/org/olat/modules/qpool/QPoolService.java
+++ b/src/main/java/org/olat/modules/qpool/QPoolService.java
@@ -158,6 +158,8 @@ public interface QPoolService {
 	
 	public TaxonomyLevel updateTaxonomyLevel(String newField, TaxonomyLevel level);
 	
+	public boolean delete(TaxonomyLevel level);
+	
 	
 	//pool administration
 	public void createPool(Identity identity, String name, boolean publicPool);
diff --git a/src/main/java/org/olat/modules/qpool/manager/QuestionPoolServiceImpl.java b/src/main/java/org/olat/modules/qpool/manager/QuestionPoolServiceImpl.java
index 9e4051a65d4..1964dea898f 100644
--- a/src/main/java/org/olat/modules/qpool/manager/QuestionPoolServiceImpl.java
+++ b/src/main/java/org/olat/modules/qpool/manager/QuestionPoolServiceImpl.java
@@ -752,4 +752,9 @@ public class QuestionPoolServiceImpl implements QPoolService {
 	public TaxonomyLevel updateTaxonomyLevel(String newField, TaxonomyLevel level) {
 		return taxonomyLevelDao.update(newField, level);
 	}
+
+	@Override
+	public boolean delete(TaxonomyLevel level) {
+		return taxonomyLevelDao.delete(level);
+	}
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/modules/qpool/manager/TaxonomyLevelDAO.java b/src/main/java/org/olat/modules/qpool/manager/TaxonomyLevelDAO.java
index 46931397903..b1f0bef9c7c 100644
--- a/src/main/java/org/olat/modules/qpool/manager/TaxonomyLevelDAO.java
+++ b/src/main/java/org/olat/modules/qpool/manager/TaxonomyLevelDAO.java
@@ -88,6 +88,28 @@ public class TaxonomyLevelDAO {
 		return mergedField;
 	}
 	
+	public boolean delete(TaxonomyLevel field) {
+		int used = countItemUsing(field);
+		int children = countChildren(field);
+		if(used == 0 && children == 0) {
+			TaxonomyLevel impl = loadLevelById(field.getKey());
+			if(impl != null) {
+				dbInstance.getCurrentEntityManager().remove(impl);
+			}
+			return true;
+		}
+		return false;
+	}
+	
+	public int countChildren(TaxonomyLevel field) {
+		StringBuilder sb = new StringBuilder();
+		sb.append("select count(taxonomyLevel) from qtaxonomylevel taxonomyLevel where taxonomyLevel.parentField.key=:taxonomyLevelKey");
+		return dbInstance.getCurrentEntityManager()
+				.createQuery(sb.toString(), Number.class)
+				.setParameter("taxonomyLevelKey", field.getKey())
+				.getSingleResult().intValue();
+	}
+	
 	public int countItemUsing(TaxonomyLevel field) {
 		StringBuilder sb = new StringBuilder();
 		sb.append("select count(item) from questionitem item where item.taxonomyLevel.key=:taxonomyLevelKey");
diff --git a/src/main/java/org/olat/modules/qpool/ui/admin/TaxonomyLevelController.java b/src/main/java/org/olat/modules/qpool/ui/admin/TaxonomyLevelController.java
index 4969098e959..c5de619b3d8 100644
--- a/src/main/java/org/olat/modules/qpool/ui/admin/TaxonomyLevelController.java
+++ b/src/main/java/org/olat/modules/qpool/ui/admin/TaxonomyLevelController.java
@@ -19,6 +19,7 @@
  */
 package org.olat.modules.qpool.ui.admin;
 
+import org.olat.core.CoreSpringFactory;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.form.flexible.FormItem;
 import org.olat.core.gui.components.form.flexible.FormItemContainer;
@@ -32,8 +33,12 @@ import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.Event;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController;
+import org.olat.core.gui.control.generic.modal.DialogBoxController;
+import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory;
 import org.olat.core.util.Util;
+import org.olat.modules.qpool.QPoolService;
 import org.olat.modules.qpool.TaxonomyLevel;
+import org.olat.modules.qpool.model.QItemType;
 import org.olat.modules.qpool.ui.QuestionsController;
 
 /**
@@ -48,11 +53,14 @@ public class TaxonomyLevelController extends FormBasicController {
 	private StaticTextElement pathEl, fieldEl;
 	private CloseableModalController cmc;
 	private TaxonomyLevelEditController editCtrl;
+	private DialogBoxController confirmDeleteCtrl;
 	
 	private TaxonomyLevel taxonomyLevel;
+	private final QPoolService qpoolService;
 	
 	public TaxonomyLevelController(UserRequest ureq, WindowControl wControl) {
 		super(ureq, wControl, Util.createPackageTranslator(QuestionsController.class, ureq.getLocale()));
+		qpoolService = CoreSpringFactory.getImpl(QPoolService.class);
 		initForm(ureq);
 		//make it invisible, no level to show
 		flc.setVisible(false);
@@ -72,8 +80,7 @@ public class TaxonomyLevelController extends FormBasicController {
 		buttonsCont.setRootForm(mainForm);
 		formLayout.add(buttonsCont);
 		editButton = uifactory.addFormLink("edit", buttonsCont, Link.BUTTON);
-		//TODO define behavior of the delete (cascade, reattach...)
-		//deleteButton = uifactory.addFormLink("delete", buttonsCont, Link.BUTTON);
+		deleteButton = uifactory.addFormLink("delete", buttonsCont, Link.BUTTON);
 	}
 	
 	public TaxonomyLevel getTaxonomyLevel() {
@@ -106,7 +113,7 @@ public class TaxonomyLevelController extends FormBasicController {
 		if(editButton == source) {
 			doEditLevel(ureq);
 		} else if(deleteButton == source) {
-			
+			doConfirmDelete(ureq);
 		}
 		super.formInnerEvent(ureq, source, event);
 	}
@@ -122,6 +129,10 @@ public class TaxonomyLevelController extends FormBasicController {
 			cleanUp();
 		} else if(cmc == source) {
 			cleanUp();
+		} else if(source == confirmDeleteCtrl) {
+			if(DialogBoxUIFactory.isOkEvent(event) || DialogBoxUIFactory.isYesEvent(event)) {
+				doDelete(ureq);
+			}
 		}
 	}
 	
@@ -131,6 +142,21 @@ public class TaxonomyLevelController extends FormBasicController {
 		editCtrl = null;
 		cmc = null;
 	}
+	
+	private void doConfirmDelete(UserRequest ureq) {
+		String title = translate("delete.taxonomyLevel");
+		String text = translate("delete.taxonomyLevel.confirm", new String[]{ taxonomyLevel.getField() });
+		confirmDeleteCtrl = activateOkCancelDialog(ureq, title, text, confirmDeleteCtrl);
+	}
+	
+	private void doDelete(UserRequest ureq) {
+		if(qpoolService.delete(taxonomyLevel)) {
+			showInfo("taxonomyLevel.deleted");
+			fireEvent(ureq, Event.CHANGED_EVENT);
+		} else {
+			showError("taxonomyLevel.notdeleted");
+		}
+	}
 
 	private void doEditLevel(UserRequest ureq) {
 		if(taxonomyLevel == null) return;
diff --git a/src/main/java/org/olat/modules/qpool/ui/admin/TaxonomyTreeModel.java b/src/main/java/org/olat/modules/qpool/ui/admin/TaxonomyTreeModel.java
index 9ca879e1efd..9f5b17bb996 100644
--- a/src/main/java/org/olat/modules/qpool/ui/admin/TaxonomyTreeModel.java
+++ b/src/main/java/org/olat/modules/qpool/ui/admin/TaxonomyTreeModel.java
@@ -68,7 +68,7 @@ public class TaxonomyTreeModel extends GenericTreeModel {
 				GenericTreeNode parentNode = fieldKeyToNode.get(parentKey);
 				if(parentNode == null) {
 					parentNode = new GenericTreeNode(parentField.getField(), parentField);
-					fieldKeyToNode.put(key, parentNode);
+					fieldKeyToNode.put(parentKey, parentNode);
 				}
 				parentNode.addChild(node);
 			}
diff --git a/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_de.properties
index 931d8628b39..a860cc1194d 100644
--- a/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_de.properties
+++ b/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_de.properties
@@ -12,6 +12,8 @@ delete.level=L\u00F6schen
 delete.level.confirm=Wollen Sie wirklich diese Stufe l\u00F6schen?
 delete.license=L\u00F6schen
 delete.license.confirm=Wollen Sie wirklich diese Lizenz l\u00F6schen?
+delete.taxonomyLevel=L\u00F6schen
+delete.taxonomyLevel.confirm=Wollen Sie wirklich diese Fachbereich "{0}" l\u00F6schen?
 delete.type=L\u00F6schen
 delete.type.confirm=Wollen Sie wirklich diesen Typ l\u00F6schen?
 edit.taxonomyLevel=Fachbereich bearbeiten
@@ -24,6 +26,8 @@ level.level=Stufe
 level.translation=\u00DCbersetzung
 license.id=ID
 license.key=Lizenz
+taxonomyLevel.deleted=Fachbereich wurde erfolgreich gel\u00F6scht
+taxonomyLevel.notdeleted=Fachbereich konnte nicht gel\u00F6scht werden, eventuell wird er bereits verwendet.
 type.key=ID
 type.translation=\u00DCbersetzung
 type.type=Typ
diff --git a/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_en.properties
index 75cad1eb09d..a40d30fa6fd 100644
--- a/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_en.properties
+++ b/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_en.properties
@@ -10,6 +10,8 @@ create.license=Create license
 create.type=Create type
 delete.level=Delete
 delete.level.confirm=Do you really want to delete this level?
+delete.taxonomyLevel=Delete
+delete.taxonomyLevel.confirm=Do you really want to delete this subject "{0}"?
 delete.license=Delete
 delete.license.confirm=Do you really want to delete this license?
 delete.type=Delete
@@ -24,6 +26,8 @@ level.level=Level
 level.translation=Translation
 license.id=ID
 license.key=License
+taxonomyLevel.deleted=Subject has been successfully deleted.
+taxonomyLevel.notdeleted=The subject cannot be deleted, it is probably in use.
 type.key=ID
 type.translation=Translation
 type.type=Type
diff --git a/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_fr.properties
index 75c38a2f719..bff10ec9598 100644
--- a/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_fr.properties
+++ b/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_fr.properties
@@ -10,6 +10,8 @@ create.license=Cr\u00E9er une license
 create.type=Cr\u00E9er un type
 delete.level=Effacer
 delete.level.confirm=Voulez-vous vraiment effacer ce niveau?
+delete.taxonomyLevel=Effacer
+delete.taxonomyLevel.confirm=Voulez-vous vraiment effacer le sujet suivant "{0}"?
 delete.license=Effacer
 delete.license.confirm=Voulez-vous vraiment effacer cette license?
 delete.type=Effacer
@@ -24,6 +26,8 @@ level.level=Niveau
 level.translation=Traduction
 license.id=ID
 license.key=License
+taxonomyLevel.deleted=Le sujet a \u00E9t\u00E9 effac\u00E9 avec succ\u00E8s.
+taxonomyLevel.notdeleted=Le sujet n'a pas pu \u00EAtre effac\u00E9 avec succ\u00E8s, il est probablement encore utilis\u00E9.
 type.key=ID
 type.translation=Traduction
 type.type=Type
diff --git a/src/test/java/org/olat/modules/qpool/manager/TaxonomyLevelDAOTest.java b/src/test/java/org/olat/modules/qpool/manager/TaxonomyLevelDAOTest.java
index 490f308dfb5..fb96198c3b9 100644
--- a/src/test/java/org/olat/modules/qpool/manager/TaxonomyLevelDAOTest.java
+++ b/src/test/java/org/olat/modules/qpool/manager/TaxonomyLevelDAOTest.java
@@ -195,4 +195,21 @@ public class TaxonomyLevelDAOTest extends OlatTestCase {
 		int numOfItems = taxonomyLevelDao.countItemUsing(level);
 		Assert.assertEquals(2, numOfItems);
 	}
+	
+	
+	@Test
+	public void countChildren_TaxonomyLevel() {
+		TaxonomyLevel galaxy = taxonomyLevelDao.createAndPersist(null, "Galaxy");
+		TaxonomyLevel andromeda = taxonomyLevelDao.createAndPersist(galaxy, "Andromeda");
+		TaxonomyLevel ngc = taxonomyLevelDao.createAndPersist(galaxy, "NGC 2502");
+		Assert.assertNotNull(andromeda);
+		Assert.assertNotNull(ngc);
+		dbInstance.commitAndCloseSession();
+		
+		//check count
+		int numOfChildrenGalaxy = taxonomyLevelDao.countChildren(galaxy);
+		Assert.assertEquals(2, numOfChildrenGalaxy);
+		int numOfChildrenAdnromeda = taxonomyLevelDao.countChildren(andromeda);
+		Assert.assertEquals(0, numOfChildrenAdnromeda);
+	}
 }
-- 
GitLab