From d7c612936fe85f47a787645a16a57f31e08e2c36 Mon Sep 17 00:00:00 2001
From: srosse <none@none>
Date: Wed, 3 Jan 2018 12:04:07 +0100
Subject: [PATCH] OO-3224: check if an edit session is available before editing
 the layout of a course

---
 .../CourseLayoutGeneratorController.java      | 80 +++++++++++++------
 .../ui/courselayout/CustomConfigManager.java  |  9 ++-
 .../course/run/CourseRuntimeController.java   |  2 +-
 3 files changed, 61 insertions(+), 30 deletions(-)

diff --git a/src/main/java/org/olat/course/config/ui/courselayout/CourseLayoutGeneratorController.java b/src/main/java/org/olat/course/config/ui/courselayout/CourseLayoutGeneratorController.java
index 0d273eb3a12..b4521c18aae 100644
--- a/src/main/java/org/olat/course/config/ui/courselayout/CourseLayoutGeneratorController.java
+++ b/src/main/java/org/olat/course/config/ui/courselayout/CourseLayoutGeneratorController.java
@@ -34,7 +34,6 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 
-import org.olat.core.CoreSpringFactory;
 import org.olat.core.commons.services.image.ImageService;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.form.flexible.FormItem;
@@ -51,12 +50,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.translator.Translator;
-import org.olat.core.id.OLATResourceable;
 import org.olat.core.logging.AssertException;
 import org.olat.core.util.ArrayHelper;
 import org.olat.core.util.FileUtils;
 import org.olat.core.util.Util;
 import org.olat.core.util.coordinate.CoordinatorManager;
+import org.olat.core.util.coordinate.LockResult;
 import org.olat.core.util.vfs.VFSContainer;
 import org.olat.core.util.vfs.VFSItem;
 import org.olat.core.util.vfs.VFSLeaf;
@@ -70,7 +69,12 @@ import org.olat.course.config.ui.courselayout.attribs.AbstractLayoutAttribute;
 import org.olat.course.config.ui.courselayout.attribs.PreviewLA;
 import org.olat.course.config.ui.courselayout.attribs.SpecialAttributeFormItemHandler;
 import org.olat.course.config.ui.courselayout.elements.AbstractLayoutElement;
+import org.olat.course.run.RunMainController;
 import org.olat.course.run.environment.CourseEnvironment;
+import org.olat.repository.RepositoryEntry;
+import org.olat.resource.OLATResource;
+import org.olat.user.UserManager;
+import org.springframework.beans.factory.annotation.Autowired;
 
 /**
  * Description:<br>
@@ -89,7 +93,6 @@ public class CourseLayoutGeneratorController extends FormBasicController {
 	private FileElement logoUpl;
 	private FormLayoutContainer previewImgFlc;
 	private FormLayoutContainer styleFlc;
-	private CustomConfigManager customCMgr;
 	private LinkedHashMap<String, Map<String, FormItem>> guiWrapper;
 	private Map<String, Map<String, Object>> persistedCustomConfig;
 	private FormLayoutContainer logoImgFlc;
@@ -97,25 +100,55 @@ public class CourseLayoutGeneratorController extends FormBasicController {
 	private boolean elWithErrorExists = false;
 	private final boolean editable;
 	
-	private final OLATResourceable courseOres;
+	private LockResult lockEntry;
 	private CourseConfig courseConfig;
+	private final RepositoryEntry courseEntry;
 	private CourseEnvironment courseEnvironment;
+	
+	@Autowired
+	private UserManager userManager;
+	@Autowired
+	private CustomConfigManager customCMgr;
 
-	public CourseLayoutGeneratorController(UserRequest ureq, WindowControl wControl, OLATResourceable courseOres, CourseConfig courseConfig,
+	public CourseLayoutGeneratorController(UserRequest ureq, WindowControl wControl, RepositoryEntry entry, CourseConfig courseConfig,
 			CourseEnvironment courseEnvironment, boolean editable) {
 		super(ureq, wControl);
-		
-		this.editable = editable;
-		this.courseOres = courseOres;
+
+		this.courseEntry = entry;
 		this.courseConfig = courseConfig;
 		this.courseEnvironment = courseEnvironment;
-		customCMgr = (CustomConfigManager) CoreSpringFactory.getBean("courseConfigManager");
+		lockEntry = CoordinatorManager.getInstance().getCoordinator().getLocker()
+				.acquireLock(entry.getOlatResource(), getIdentity(), CourseFactory.COURSE_EDITOR_LOCK);
+		this.editable = (lockEntry != null && lockEntry.isSuccess()) && editable;
+		
 		// stack the translator to get attribs/elements
-		Translator pt = Util.createPackageTranslator(AbstractLayoutAttribute.class, ureq.getLocale(), getTranslator());
-		pt = Util.createPackageTranslator(AbstractLayoutElement.class, ureq.getLocale(), pt);
+		Translator pt = Util.createPackageTranslator(AbstractLayoutAttribute.class, getLocale(), getTranslator());
+		pt = Util.createPackageTranslator(AbstractLayoutElement.class, getLocale(), pt);
+		pt = Util.createPackageTranslator(RunMainController.class, getLocale(), pt);
 		setTranslator(pt);
+		
 		persistedCustomConfig = customCMgr.getCustomConfig(courseEnvironment);
 		initForm(ureq);
+		
+		if(lockEntry != null && !lockEntry.isSuccess()) {
+			String lockerName = "???";
+			if(lockEntry.getOwner() != null) {
+				lockerName = userManager.getUserDisplayName(lockEntry.getOwner());
+			}
+			showWarning("error.editoralreadylocked", new String[] { lockerName });
+		}
+	}
+	
+	
+	/**
+	 * @see org.olat.core.gui.control.DefaultController#doDispose()
+	 */
+	@Override
+	protected void doDispose() {
+		if (lockEntry != null && lockEntry.isSuccess()) {
+			CoordinatorManager.getInstance().getCoordinator().getLocker().releaseLock(lockEntry);
+			lockEntry = null;
+		}
 	}
 
 	/**
@@ -125,9 +158,9 @@ public class CourseLayoutGeneratorController extends FormBasicController {
 	protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
 		setFormTitle("tab.layout.title");
 		
-		ArrayList<String> keys = new ArrayList<String>();
-		ArrayList<String> vals = new ArrayList<String>();
-		ArrayList<String> csss = new ArrayList<String>();
+		List<String> keys = new ArrayList<String>();
+		List<String> vals = new ArrayList<String>();
+		List<String> csss = new ArrayList<String>();
 
 		String actualCSSSettings = courseConfig.getCssLayoutRef();
 		
@@ -372,9 +405,15 @@ public class CourseLayoutGeneratorController extends FormBasicController {
 	 */
 	@Override
 	protected void formOK(UserRequest ureq) {
+		OLATResource courseRes = courseEntry.getOlatResource();
+		if(CourseFactory.isCourseEditSessionOpen(courseRes.getResourceableId())) {
+			showWarning("error.editoralreadylocked", new String[] { "???" });
+			return;
+		}
+		
 		String selection = styleSel.getSelectedKey();
 		
-		ICourse course = CourseFactory.openCourseEditSession(courseOres.getResourceableId());
+		ICourse course = CourseFactory.openCourseEditSession(courseRes.getResourceableId());
 		courseEnvironment = course.getCourseEnvironment();
 		courseConfig = courseEnvironment.getCourseConfig();
 		courseConfig.setCssLayoutRef(selection);
@@ -457,15 +496,4 @@ public class CourseLayoutGeneratorController extends FormBasicController {
 		}		
 		styleFlc.contextPut("guiWrapper", guiWrapper);
 	}
-	
-	
-	/**
-	 * @see org.olat.core.gui.control.DefaultController#doDispose()
-	 */
-	@Override
-	protected void doDispose() {
-		// nothing to dispose
-	}
-
-
 }
diff --git a/src/main/java/org/olat/course/config/ui/courselayout/CustomConfigManager.java b/src/main/java/org/olat/course/config/ui/courselayout/CustomConfigManager.java
index f6a672c35cd..80fb5b9ffe4 100644
--- a/src/main/java/org/olat/course/config/ui/courselayout/CustomConfigManager.java
+++ b/src/main/java/org/olat/course/config/ui/courselayout/CustomConfigManager.java
@@ -29,7 +29,8 @@ import java.util.Map.Entry;
 
 import javax.imageio.ImageIO;
 
-import org.olat.core.manager.BasicManager;
+import org.olat.core.logging.OLog;
+import org.olat.core.logging.Tracing;
 import org.olat.core.util.FileUtils;
 import org.olat.core.util.vfs.LocalFileImpl;
 import org.olat.core.util.vfs.VFSContainer;
@@ -52,7 +53,9 @@ import com.thoughtworks.xstream.XStream;
  * Initial Date:  04.02.2011 <br>
  * @author Roman Haag, roman.haag@frentix.com, http://www.frentix.com
  */
-public class CustomConfigManager extends BasicManager {
+public class CustomConfigManager {
+	
+	private static final OLog log = Tracing.createLoggerFor(CustomConfigManager.class);
 	
 	private static final String IFRAME_CSS = "iframe.css";
 	private static final String MAIN_CSS = "main.css";
@@ -156,7 +159,7 @@ public class CustomConfigManager extends BasicManager {
 				return null;
 			}
 		} catch (IOException e) {
-			logError("Problem reading uploaded image", e);
+			log.error("Problem reading uploaded image", e);
 			return null;
 		}
 		return new int[] { width, height };
diff --git a/src/main/java/org/olat/course/run/CourseRuntimeController.java b/src/main/java/org/olat/course/run/CourseRuntimeController.java
index 52555e83e29..ac85890118a 100644
--- a/src/main/java/org/olat/course/run/CourseRuntimeController.java
+++ b/src/main/java/org/olat/course/run/CourseRuntimeController.java
@@ -1330,7 +1330,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im
 				ICourse course = CourseFactory.loadCourse(getRepositoryEntry());
 				boolean managedLayout = RepositoryEntryManagedFlag.isManaged(getRepositoryEntry(), RepositoryEntryManagedFlag.layout);
 				CourseConfig courseConfig = course.getCourseEnvironment().getCourseConfig().clone();
-				CourseLayoutGeneratorController ctrl = new CourseLayoutGeneratorController(ureq, getWindowControl(), course, courseConfig,
+				CourseLayoutGeneratorController ctrl = new CourseLayoutGeneratorController(ureq, getWindowControl(), getRepositoryEntry(), courseConfig,
 				  		course.getCourseEnvironment(), !managedLayout);
 				listenTo(ctrl);
 				courseLayoutCtrl = pushController(ureq, translate("command.layout"), ctrl);
-- 
GitLab