From 455b9adcdd3b522323862ea3cc16386e0980d113 Mon Sep 17 00:00:00 2001
From: uhensler <urs.hensler@frentix.com>
Date: Fri, 20 Mar 2020 13:43:57 +0100
Subject: [PATCH] OO-4207: Set course node access type in rest api

---
 .../java/org/olat/course/CourseFactory.java   | 36 +++++++++++++++++++
 ...CreateCourseRepositoryEntryController.java | 36 ++-----------------
 .../repository/course/CoursesWebService.java  | 22 +++++++-----
 .../olat/restapi/support/ObjectFactory.java   |  1 +
 .../org/olat/restapi/support/vo/CourseVO.java |  9 +++++
 .../java/org/olat/restapi/CoursesTest.java    | 24 +++++++++++++
 6 files changed, 86 insertions(+), 42 deletions(-)

diff --git a/src/main/java/org/olat/course/CourseFactory.java b/src/main/java/org/olat/course/CourseFactory.java
index 463f0ac0b9f..d5392e88fcf 100644
--- a/src/main/java/org/olat/course/CourseFactory.java
+++ b/src/main/java/org/olat/course/CourseFactory.java
@@ -105,6 +105,8 @@ import org.olat.course.editor.PublishSetInformations;
 import org.olat.course.editor.StatusDescription;
 import org.olat.course.groupsandrights.CourseGroupManager;
 import org.olat.course.groupsandrights.PersistingCourseGroupManager;
+import org.olat.course.nodeaccess.NodeAccessService;
+import org.olat.course.nodeaccess.NodeAccessType;
 import org.olat.course.nodes.BCCourseNode;
 import org.olat.course.nodes.CourseNode;
 import org.olat.course.nodes.STCourseNode;
@@ -121,6 +123,7 @@ import org.olat.course.tree.PublishTreeModel;
 import org.olat.group.BusinessGroup;
 import org.olat.instantMessaging.InstantMessagingService;
 import org.olat.instantMessaging.manager.ChatLogHelper;
+import org.olat.modules.ModuleConfiguration;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryEntrySecurity;
 import org.olat.repository.RepositoryEntryStatusEnum;
@@ -236,6 +239,39 @@ public class CourseFactory {
 		return newCourse;
 	}
 
+	public static ICourse initNodeAccessType(RepositoryEntry addedEntry, NodeAccessType type) {
+		OLATResourceable courseOres = addedEntry.getOlatResource();
+		if (CourseFactory.isCourseEditSessionOpen(courseOres.getResourceableId())) {
+			log.warn("Not able to set the course node access type: Edit session is already open!");
+			return loadCourse(addedEntry);
+		}
+		
+		ICourse course = CourseFactory.openCourseEditSession(courseOres.getResourceableId());
+		CourseConfig courseConfig = course.getCourseEnvironment().getCourseConfig();
+		String nodeAccessType = type.getType();
+		courseConfig.setNodeAccessType(nodeAccessType);
+		
+		ModuleConfiguration runConfig = course.getCourseEnvironment().getRunStructure().getRootNode().getModuleConfiguration();
+		CourseEditorTreeNode courseEditorTreeNode = (CourseEditorTreeNode)course.getEditorTreeModel().getRootNode();
+		ModuleConfiguration editorConfig = courseEditorTreeNode.getCourseNode().getModuleConfiguration();
+		
+		NodeAccessService nodeAccessService = CoreSpringFactory.getImpl(NodeAccessService.class);
+		boolean scoreCalculatorSupported = nodeAccessService.isScoreCalculatorSupported(type);
+		runConfig.setBooleanEntry(STCourseNode.CONFIG_SCORE_CALCULATOR_SUPPORTED, scoreCalculatorSupported);
+		editorConfig.setBooleanEntry(STCourseNode.CONFIG_SCORE_CALCULATOR_SUPPORTED, scoreCalculatorSupported);
+		
+		if (!scoreCalculatorSupported) {
+			runConfig.setStringValue(STCourseNode.CONFIG_SCORE_KEY, STCourseNode.CONFIG_SCORE_VALUE_SUM);
+			runConfig.setBooleanEntry(STCourseNode.CONFIG_PASSED_PROGRESS, true);
+			editorConfig.setStringValue(STCourseNode.CONFIG_SCORE_KEY, STCourseNode.CONFIG_SCORE_VALUE_SUM);
+			editorConfig.setBooleanEntry(STCourseNode.CONFIG_PASSED_PROGRESS, true);
+		}
+		
+		CourseFactory.setCourseConfig(course.getResourceableId(), courseConfig);
+		CourseFactory.saveCourse(addedEntry.getOlatResource().getResourceableId());
+		CourseFactory.closeCourseEditSession(course.getResourceableId(), true);
+		return course;
+	}
 
 
 	/**
diff --git a/src/main/java/org/olat/repository/ui/author/CreateCourseRepositoryEntryController.java b/src/main/java/org/olat/repository/ui/author/CreateCourseRepositoryEntryController.java
index 3f15b4fc8dd..2b200b3aec1 100644
--- a/src/main/java/org/olat/repository/ui/author/CreateCourseRepositoryEntryController.java
+++ b/src/main/java/org/olat/repository/ui/author/CreateCourseRepositoryEntryController.java
@@ -28,18 +28,13 @@ import org.olat.core.gui.components.form.flexible.impl.FormEvent;
 import org.olat.core.gui.components.util.KeyValues;
 import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.WindowControl;
-import org.olat.core.id.OLATResourceable;
 import org.olat.core.logging.Tracing;
 import org.olat.course.CourseFactory;
-import org.olat.course.ICourse;
 import org.olat.course.condition.ConditionNodeAccessProvider;
 import org.olat.course.config.CourseConfig;
 import org.olat.course.nodeaccess.NodeAccessProviderIdentifier;
 import org.olat.course.nodeaccess.NodeAccessService;
 import org.olat.course.nodeaccess.NodeAccessType;
-import org.olat.course.nodes.STCourseNode;
-import org.olat.course.tree.CourseEditorTreeNode;
-import org.olat.modules.ModuleConfiguration;
 import org.olat.repository.handlers.RepositoryHandler;
 import org.springframework.beans.factory.annotation.Autowired;
 
@@ -90,35 +85,8 @@ public class CreateCourseRepositoryEntryController extends CreateRepositoryEntry
 
 	@Override
 	protected void afterEntryCreated() {
-		OLATResourceable courseOres = getAddedEntry().getOlatResource();
-		if (CourseFactory.isCourseEditSessionOpen(courseOres.getResourceableId())) {
-			log.warn("Not able to set the course node access type: Edit session is already open!");
-			return;
-		}
-		
-		ICourse course = CourseFactory.openCourseEditSession(courseOres.getResourceableId());
-		CourseConfig courseConfig = course.getCourseEnvironment().getCourseConfig();
-		String nodeAccessType = nodeAccessEl.getSelectedKey();
-		courseConfig.setNodeAccessType(nodeAccessType);
-		
-		ModuleConfiguration runConfig = course.getCourseEnvironment().getRunStructure().getRootNode().getModuleConfiguration();
-		CourseEditorTreeNode courseEditorTreeNode = (CourseEditorTreeNode)course.getEditorTreeModel().getRootNode();
-		ModuleConfiguration editorConfig = courseEditorTreeNode.getCourseNode().getModuleConfiguration();
-		
-		boolean scoreCalculatorSupported = nodeAccessService.isScoreCalculatorSupported(NodeAccessType.of(nodeAccessType));
-		runConfig.setBooleanEntry(STCourseNode.CONFIG_SCORE_CALCULATOR_SUPPORTED, scoreCalculatorSupported);
-		editorConfig.setBooleanEntry(STCourseNode.CONFIG_SCORE_CALCULATOR_SUPPORTED, scoreCalculatorSupported);
-		
-		if (!scoreCalculatorSupported) {
-			runConfig.setStringValue(STCourseNode.CONFIG_SCORE_KEY, STCourseNode.CONFIG_SCORE_VALUE_SUM);
-			runConfig.setBooleanEntry(STCourseNode.CONFIG_PASSED_PROGRESS, true);
-			editorConfig.setStringValue(STCourseNode.CONFIG_SCORE_KEY, STCourseNode.CONFIG_SCORE_VALUE_SUM);
-			editorConfig.setBooleanEntry(STCourseNode.CONFIG_PASSED_PROGRESS, true);
-		}
-		
-		CourseFactory.setCourseConfig(course.getResourceableId(), courseConfig);
-		CourseFactory.saveCourse(getAddedEntry().getOlatResource().getResourceableId());
-		CourseFactory.closeCourseEditSession(course.getResourceableId(), true);
+		String type = nodeAccessEl.getSelectedKey();
+		CourseFactory.initNodeAccessType(getAddedEntry(), NodeAccessType.of(type));
 	}
 	
 }
diff --git a/src/main/java/org/olat/restapi/repository/course/CoursesWebService.java b/src/main/java/org/olat/restapi/repository/course/CoursesWebService.java
index 5485780ccdc..00d58443308 100644
--- a/src/main/java/org/olat/restapi/repository/course/CoursesWebService.java
+++ b/src/main/java/org/olat/restapi/repository/course/CoursesWebService.java
@@ -20,7 +20,6 @@
 package org.olat.restapi.repository.course;
 
 import static org.olat.restapi.security.RestSecurityHelper.getIdentity;
-
 import static org.olat.restapi.security.RestSecurityHelper.getRoles;
 import static org.olat.restapi.security.RestSecurityHelper.getUserRequest;
 
@@ -70,6 +69,7 @@ import org.olat.course.CourseFactory;
 import org.olat.course.CourseModule;
 import org.olat.course.ICourse;
 import org.olat.course.config.CourseConfig;
+import org.olat.course.nodeaccess.NodeAccessType;
 import org.olat.course.nodes.CourseNode;
 import org.olat.course.tree.CourseEditorTreeNode;
 import org.olat.repository.RepositoryEntry;
@@ -286,7 +286,8 @@ public class CoursesWebService {
 			@QueryParam("managedFlags") String managedFlags, @QueryParam("sharedFolderSoftKey") String sharedFolderSoftKey,
 			@QueryParam("copyFrom") Long copyFrom, @QueryParam("initialAuthor") Long initialAuthor,
 			@QueryParam("setAuthor")  @DefaultValue("true") Boolean setAuthor,
-			@QueryParam("organisationKey") Long organisationKey, @Context HttpServletRequest request) {
+			@QueryParam("organisationKey") Long organisationKey, @QueryParam("nodeAccessType") String nodeAccessType, 
+			@Context HttpServletRequest request) {
 		if(!isAuthor(request)) {
 			return Response.serverError().status(Status.UNAUTHORIZED).build();
 		}
@@ -332,7 +333,8 @@ public class CoursesWebService {
 			course = createEmptyCourse(id, shortTitle, title, displayName, description,
 					objectives, requirements, credits, expenditureOfWork,
 					softKey, accessStatus, accessAllUsers, accessGuests, organisationKey,
-					authors, location, externalId, externalRef, managedFlags, configVO);
+					authors, location, externalId, externalRef, managedFlags, nodeAccessType, 
+					configVO);
 		}
 		if(course == null) {
 			return Response.serverError().status(Status.NOT_FOUND).build();
@@ -371,9 +373,8 @@ public class CoursesWebService {
 		ICourse course = createEmptyCourse(ureq.getIdentity(),
 				courseVo.getTitle(), courseVo.getTitle(), courseVo.getTitle(), courseVo.getDescription(), null, null, null, null,
 				courseVo.getSoftKey(), RepositoryEntryStatusEnum.preparation, false, false, courseVo.getOrganisationKey(),
-				courseVo.getAuthors(), courseVo.getLocation(),
-				courseVo.getExternalId(), courseVo.getExternalRef(), courseVo.getManagedFlags(),
-				configVO);
+				courseVo.getAuthors(), courseVo.getLocation(), courseVo.getExternalId(), courseVo.getExternalRef(), 
+				courseVo.getManagedFlags(), courseVo.getNodeAccessType(), configVO);
 		CourseVO vo = ObjectFactory.get(course);
 		return Response.ok(vo).build();
 	}
@@ -638,6 +639,7 @@ public class CoursesWebService {
 	 * @param externalId
 	 * @param externalRef
 	 * @param managedFlags
+	 * @param nodeAccessType 
 	 * @param courseConfigVO
 	 * @return
 	 */
@@ -645,7 +647,7 @@ public class CoursesWebService {
 			String description, String objectives, String requirements, String credits, String expenditureOfWork, String softKey,
 			RepositoryEntryStatusEnum status, boolean allUsers, boolean guests,
 			Long organisationKey, String authors, String location, String externalId, String externalRef,
-			String managedFlags, CourseConfigVO courseConfigVO) {
+			String managedFlags, String nodeAccessType, CourseConfigVO courseConfigVO) {
 
 		if(!StringHelper.containsNonWhitespace(reDisplayName)) {
 			reDisplayName = shortTitle;
@@ -686,7 +688,11 @@ public class CoursesWebService {
 			addedEntry = repositoryService.update(addedEntry);
 
 			// create an empty course
-			CourseFactory.createCourse(addedEntry, shortTitle, longTitle, "");
+			ICourse course = CourseFactory.createCourse(addedEntry, shortTitle, longTitle, "");
+			NodeAccessType type = StringHelper.containsNonWhitespace(nodeAccessType)
+					? NodeAccessType.of(nodeAccessType)
+					: course.getCourseConfig().getNodeAccessType(); // default type
+			CourseFactory.initNodeAccessType(addedEntry, type);
 			return prepareCourse(addedEntry, shortTitle, longTitle, courseConfigVO);
 		} catch (Exception e) {
 			throw new WebApplicationException(e);
diff --git a/src/main/java/org/olat/restapi/support/ObjectFactory.java b/src/main/java/org/olat/restapi/support/ObjectFactory.java
index 5efc5329b36..8207ba218e7 100644
--- a/src/main/java/org/olat/restapi/support/ObjectFactory.java
+++ b/src/main/java/org/olat/restapi/support/ObjectFactory.java
@@ -164,6 +164,7 @@ public class ObjectFactory {
 		vo.setDescription(re.getDescription());
 		vo.setTitle(course.getCourseTitle());
 		vo.setEditorRootNodeId(course.getEditorTreeModel().getRootNode().getIdent());
+		vo.setNodeAccessType(course.getCourseConfig().getNodeAccessType().getType());
 		vo.setSoftKey(re.getSoftkey());
 		vo.setRepoEntryKey(re.getKey());
 		OLATResource resource = re.getOlatResource();
diff --git a/src/main/java/org/olat/restapi/support/vo/CourseVO.java b/src/main/java/org/olat/restapi/support/vo/CourseVO.java
index 6e6bcf83d31..ed0050883a9 100644
--- a/src/main/java/org/olat/restapi/support/vo/CourseVO.java
+++ b/src/main/java/org/olat/restapi/support/vo/CourseVO.java
@@ -88,6 +88,7 @@ public class CourseVO {
 	
 	private String title;
 	private String editorRootNodeId;
+	private String nodeAccessType;
 	
 	private RepositoryEntryLifecycleVO lifecycle;
 	
@@ -223,6 +224,14 @@ public class CourseVO {
 		this.editorRootNodeId = editorRootNodeId;
 	}
 
+	public String getNodeAccessType() {
+		return nodeAccessType;
+	}
+
+	public void setNodeAccessType(String nodeAccessType) {
+		this.nodeAccessType = nodeAccessType;
+	}
+
 	public RepositoryEntryLifecycleVO getLifecycle() {
 		return lifecycle;
 	}
diff --git a/src/test/java/org/olat/restapi/CoursesTest.java b/src/test/java/org/olat/restapi/CoursesTest.java
index 101e5b819c3..11bb07c9fd9 100644
--- a/src/test/java/org/olat/restapi/CoursesTest.java
+++ b/src/test/java/org/olat/restapi/CoursesTest.java
@@ -66,6 +66,8 @@ import org.olat.core.logging.Tracing;
 import org.olat.core.util.StringHelper;
 import org.olat.course.CourseFactory;
 import org.olat.course.ICourse;
+import org.olat.course.condition.ConditionNodeAccessProvider;
+import org.olat.course.config.CourseConfig;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryEntryRelationType;
 import org.olat.repository.RepositoryEntryStatusEnum;
@@ -435,6 +437,28 @@ public class CoursesTest extends OlatRestTestCase {
 		Assert.assertEquals("AC-825761", re.getExternalRef());
 	}
 
+	@Test
+	public void testCreateEmpty_nodeAccessType() throws IOException, URISyntaxException {
+		assertTrue(conn.login("administrator", "openolat"));
+
+		URI uri = UriBuilder.fromUri(getContextURI()).path("repo").path("courses")
+			.queryParam("shortTitle", "courseCC")
+			.queryParam("title", "course cc long name")
+			.queryParam("nodeAccessType", ConditionNodeAccessProvider.TYPE)
+			.build();
+		HttpPut method = conn.createPut(uri, MediaType.APPLICATION_JSON, true);
+
+		HttpResponse response = conn.execute(method);
+		assertEquals(200, response.getStatusLine().getStatusCode());
+		CourseVO courseVO = conn.parse(response, CourseVO.class);
+		assertNotNull(courseVO);
+		//check course config
+		RepositoryEntry re = repositoryManager.lookupRepositoryEntry(courseVO.getRepoEntryKey());
+		ICourse course = CourseFactory.loadCourse(re);
+		CourseConfig courseConfig = course.getCourseConfig();
+		assertEquals(ConditionNodeAccessProvider.TYPE, courseConfig.getNodeAccessType().getType());
+	}
+
 	@Test
 	public void testImportCourse() throws IOException, URISyntaxException {
 		URL cpUrl = CoursesTest.class.getResource("Course_with_blog.zip");
-- 
GitLab