From c1e5b8013b9676bdc0fab6df96d527414ed8d205 Mon Sep 17 00:00:00 2001
From: srosse <none@none>
Date: Thu, 30 Mar 2017 11:34:26 +0200
Subject: [PATCH] OO-2665: prevent upload 2 tasks with the same file, don't
 delete a file used by other tasks

---
 .../org/olat/course/nodes/gta/GTAManager.java |  9 +++-
 .../nodes/gta/manager/GTAManagerImpl.java     | 16 +++++-
 .../ui/AbstractAssignmentEditController.java  | 16 +++---
 .../nodes/gta/ui/EditTaskController.java      | 50 ++++++++++++++++---
 4 files changed, 70 insertions(+), 21 deletions(-)

diff --git a/src/main/java/org/olat/course/nodes/gta/GTAManager.java b/src/main/java/org/olat/course/nodes/gta/GTAManager.java
index 4ff0c8475f7..0cc0f38448a 100644
--- a/src/main/java/org/olat/course/nodes/gta/GTAManager.java
+++ b/src/main/java/org/olat/course/nodes/gta/GTAManager.java
@@ -74,10 +74,15 @@ public interface GTAManager {
 	 */
 	public void updateTaskDefinition(String currentFilename, TaskDefinition task, CourseEnvironment courseEnv, GTACourseNode cNode);
 	
+	/**
+	 * Remove the task definition and the file (if it's not used by an other task)
+	 * 
+	 * @param removedTask The task definition to remove
+	 * @param courseEnv The course environment
+	 * @param cNode The course element
+	 */
 	public void removeTaskDefinition(TaskDefinition removedTask, CourseEnvironment courseEnv, GTACourseNode cNode);
 	
-	
-	
 	public File getSubmitDirectory(CourseEnvironment courseEnv, GTACourseNode cNode, IdentityRef person);
 	
 	public File getSubmitDirectory(CourseEnvironment courseEnv, GTACourseNode cNode, BusinessGroupRef assessedGroup);
diff --git a/src/main/java/org/olat/course/nodes/gta/manager/GTAManagerImpl.java b/src/main/java/org/olat/course/nodes/gta/manager/GTAManagerImpl.java
index b1e4a902370..358700f7922 100644
--- a/src/main/java/org/olat/course/nodes/gta/manager/GTAManagerImpl.java
+++ b/src/main/java/org/olat/course/nodes/gta/manager/GTAManagerImpl.java
@@ -49,6 +49,7 @@ import org.olat.core.logging.Tracing;
 import org.olat.core.util.StringHelper;
 import org.olat.core.util.io.SystemFilenameFilter;
 import org.olat.core.util.vfs.VFSContainer;
+import org.olat.core.util.vfs.VFSItem;
 import org.olat.core.util.vfs.VFSManager;
 import org.olat.core.util.xml.XStreamHelper;
 import org.olat.course.nodes.GTACourseNode;
@@ -182,15 +183,26 @@ public class GTAManagerImpl implements GTAManager, DeletableGroupData {
 			@Override
 			public void sync() {
 				List<TaskDefinition> taskDefinitions = getTaskDefinitions(courseEnv, cNode);
+				boolean deleteFile = true;
 				for(int i=taskDefinitions.size(); i-->0; ) {
-					if(taskDefinitions.get(i).getFilename().equals(removedTask.getFilename())) {
+					if(taskDefinitions.get(i).getTitle().equals(removedTask.getTitle())) {
 						taskDefinitions.remove(i);
-						break;
+					} else if(taskDefinitions.get(i).getFilename().equals(removedTask.getFilename())) {
+						deleteFile = false;
+					}
+				}
+				
+				if(deleteFile) {
+					VFSContainer tasksContainer = getTasksContainer(courseEnv, cNode);
+					VFSItem item = tasksContainer.resolve(removedTask.getFilename());
+					if(item != null) {
+						item.delete();
 					}
 				}
 				storeTaskDefinitions(taskDefinitions, courseEnv, cNode);
 			}
 		});
+		
 	}
 
 	@Override
diff --git a/src/main/java/org/olat/course/nodes/gta/ui/AbstractAssignmentEditController.java b/src/main/java/org/olat/course/nodes/gta/ui/AbstractAssignmentEditController.java
index 4882a76c8da..e83f0189e2e 100644
--- a/src/main/java/org/olat/course/nodes/gta/ui/AbstractAssignmentEditController.java
+++ b/src/main/java/org/olat/course/nodes/gta/ui/AbstractAssignmentEditController.java
@@ -227,8 +227,8 @@ abstract class AbstractAssignmentEditController extends FormBasicController {
 			if(DialogBoxUIFactory.isOkEvent(event) || DialogBoxUIFactory.isYesEvent(event)) {
 				TaskDefinition row = (TaskDefinition)confirmDeleteCtrl.getUserObject();
 				doDelete(ureq, row);
-				//fireEvent(ureq, Event.DONE_EVENT);
 			}
+			cleanUp();
 		} else if(cmc == source) {
 			cleanUp();
 		}
@@ -236,9 +236,11 @@ abstract class AbstractAssignmentEditController extends FormBasicController {
 	}
 	
 	private void cleanUp() {
+		removeAsListenerAndDispose(confirmDeleteCtrl);
 		removeAsListenerAndDispose(editTaskCtrl);
 		removeAsListenerAndDispose(addTaskCtrl);
 		removeAsListenerAndDispose(cmc);
+		confirmDeleteCtrl = null;
 		editTaskCtrl = null;
 		addTaskCtrl = null;
 		cmc = null;
@@ -269,7 +271,8 @@ abstract class AbstractAssignmentEditController extends FormBasicController {
 	}
 	
 	private void doAddTask(UserRequest ureq) {
-		addTaskCtrl = new EditTaskController(ureq, getWindowControl(), tasksFolder);
+		List<TaskDefinition> currentDefinitions = gtaManager.getTaskDefinitions(courseEnv, gtaNode);
+		addTaskCtrl = new EditTaskController(ureq, getWindowControl(), tasksFolder, currentDefinitions);
 		listenTo(addTaskCtrl);
 
 		String title = translate("add.task");
@@ -287,7 +290,8 @@ abstract class AbstractAssignmentEditController extends FormBasicController {
 	}
 	
 	private void doReplaceTask(UserRequest ureq, TaskDefinition taskDef) {
-		editTaskCtrl = new EditTaskController(ureq, getWindowControl(), taskDef, tasksFolder);
+		List<TaskDefinition> currentDefinitions = gtaManager.getTaskDefinitions(courseEnv, gtaNode);
+		editTaskCtrl = new EditTaskController(ureq, getWindowControl(), taskDef, tasksFolder, currentDefinitions);
 		listenTo(editTaskCtrl);
 
 		String title = translate("edit.task");
@@ -359,12 +363,6 @@ abstract class AbstractAssignmentEditController extends FormBasicController {
 	
 	private void doDelete(UserRequest ureq, TaskDefinition taskDef) {
 		gtaManager.removeTaskDefinition(taskDef, courseEnv, gtaNode);
-		
-		VFSItem item = tasksContainer.resolve(taskDef.getFilename());
-		if(item != null) {
-			item.delete();
-		}
-		
 		updateModel();
 		fireEvent(ureq, Event.DONE_EVENT);
 	}
diff --git a/src/main/java/org/olat/course/nodes/gta/ui/EditTaskController.java b/src/main/java/org/olat/course/nodes/gta/ui/EditTaskController.java
index c21436a1caf..328b62a4dd8 100644
--- a/src/main/java/org/olat/course/nodes/gta/ui/EditTaskController.java
+++ b/src/main/java/org/olat/course/nodes/gta/ui/EditTaskController.java
@@ -23,6 +23,7 @@ import java.io.File;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.StandardCopyOption;
+import java.util.List;
 
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.form.flexible.FormItemContainer;
@@ -53,22 +54,27 @@ public class EditTaskController extends FormBasicController {
 	private final File taskContainer;
 	
 	private final String filenameToReplace;
+	private final List<TaskDefinition> currentDefinitions;
 	
-	public EditTaskController(UserRequest ureq, WindowControl wControl, File taskContainer) {
-		this(ureq, wControl, new TaskDefinition(), taskContainer, false);
+	public EditTaskController(UserRequest ureq, WindowControl wControl, File taskContainer,
+			List<TaskDefinition> currentDefinitions) {
+		this(ureq, wControl, new TaskDefinition(), taskContainer, currentDefinitions, false);
 	}
 	
-	public EditTaskController(UserRequest ureq, WindowControl wControl, TaskDefinition task, File taskContainer) {
-		this(ureq, wControl, task, taskContainer, true);
+	public EditTaskController(UserRequest ureq, WindowControl wControl, TaskDefinition task, File taskContainer,
+			List<TaskDefinition> currentDefinitions) {
+		this(ureq, wControl, task, taskContainer, currentDefinitions, true);
 	}
 	
 	public EditTaskController(UserRequest ureq, WindowControl wControl,
-			TaskDefinition task, File taskContainer, boolean replaceFile) {
+			TaskDefinition task, File taskContainer,
+			List<TaskDefinition> currentDefinitions, boolean replaceFile) {
 		super(ureq, wControl);
 		this.replaceFile = replaceFile;
 		this.task = task;
 		this.filenameToReplace = task != null ? task.getFilename() : null;
 		this.taskContainer = taskContainer;
+		this.currentDefinitions = currentDefinitions;
 		initForm(ureq);
 	}
 	
@@ -128,6 +134,23 @@ public class EditTaskController extends FormBasicController {
 		if(fileEl.getInitialFile() == null && fileEl.getUploadFile() == null) {
 			fileEl.setErrorKey("form.mandatory.hover", null);
 			allOk &= false;
+		} else if(!replaceFile && fileEl.getUploadFile() != null) {
+			String filename = fileEl.getUploadFileName();
+			File target = new File(taskContainer, filename);
+			if(target.exists()) {
+				fileEl.setErrorKey("error.file.exists", new String[]{ filename });
+				allOk &= false;
+			}
+		} else if(replaceFile && fileEl.getUploadFile() != null) {
+			String filename = fileEl.getUploadFileName();
+			if(currentDefinitions != null) {
+				for(TaskDefinition definition:currentDefinitions) {
+					if(filename.equals(definition.getFilename()) && !task.getTitle().equals(definition.getTitle())) {
+						fileEl.setErrorKey("error.file.exists", new String[]{ filename });
+						allOk &= false;
+					}
+				}
+			}
 		}
 		
 		return allOk & super.validateFormLogic(ureq);
@@ -140,9 +163,20 @@ public class EditTaskController extends FormBasicController {
 		
 		if(fileEl.getUploadFile() != null) {
 			if(replaceFile && StringHelper.containsNonWhitespace(task.getFilename())) {
-				File currentFile = new File(taskContainer, task.getFilename());
-				if(currentFile.exists()) {
-					currentFile.delete();
+				int usage = 0;
+				if(currentDefinitions != null) {
+					for(TaskDefinition definition:currentDefinitions) {
+						if(task.getFilename().equals(definition.getFilename())) {
+							usage++;
+						}
+					}
+				}
+				
+				if(usage == 1) {
+					File currentFile = new File(taskContainer, task.getFilename());
+					if(currentFile.exists()) {
+						currentFile.delete();
+					}
 				}
 			}
 			
-- 
GitLab