From baffcea47ca044fcb67f3bb1bcbf5fed1c7bff5f Mon Sep 17 00:00:00 2001
From: uhensler <urs.hensler@frentix.com>
Date: Wed, 17 Apr 2019 09:52:22 +0200
Subject: [PATCH] OO-4009: Versioning of with OnlyOffice edited files

---
 .../doceditor/onlyoffice/OnlyOfficeService.java |  2 +-
 .../manager/OnlyOfficeServiceImpl.java          |  6 ++----
 .../restapi/OnlyOfficeWebService.java           | 12 +++++++++---
 .../onlyoffice/ui/ApiConfigBuilder.java         | 17 ++++++++++++++++-
 .../ui/OnlyOfficeEditorController.java          |  1 +
 5 files changed, 29 insertions(+), 9 deletions(-)

diff --git a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/OnlyOfficeService.java b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/OnlyOfficeService.java
index c09561ab069..86bc0c858a8 100644
--- a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/OnlyOfficeService.java
+++ b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/OnlyOfficeService.java
@@ -43,7 +43,7 @@ public interface OnlyOfficeService {
 
 	boolean canUpdateContent(VFSLeaf vfsLeaf, Identity identity, String documentKey);
 
-	boolean updateContent(VFSLeaf vfsLeaf, Identity identity, String url);
+	boolean updateContent(VFSLeaf vfsLeaf, Identity identity, String url, boolean versionControlled);
 	
 	boolean isLockNeeded(Mode mode);
 
diff --git a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/manager/OnlyOfficeServiceImpl.java b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/manager/OnlyOfficeServiceImpl.java
index b3bd9cd27fb..c8167a37078 100644
--- a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/manager/OnlyOfficeServiceImpl.java
+++ b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/manager/OnlyOfficeServiceImpl.java
@@ -102,12 +102,10 @@ public class OnlyOfficeServiceImpl implements OnlyOfficeService {
 	}
 
 	@Override
-	public boolean updateContent(VFSLeaf vfsLeaf, Identity identity, String url) {
+	public boolean updateContent(VFSLeaf vfsLeaf, Identity identity, String url, boolean versionControlled) {
 		boolean updated = false;
 		try (InputStream in = new URL(url).openStream()) {
-			//TODO uh versionCntrolled
-			if(//access.isVersionControlled() && 
-					vfsLeaf.canVersion() == VFSConstants.YES) {
+			if(versionControlled && vfsLeaf.canVersion() == VFSConstants.YES) {
 				updated = vfsRepositoryService.addVersion(vfsLeaf, identity, "OnlyOffice", in);
 			} else {
 				updated = VFSManager.copyContent(in, vfsLeaf);
diff --git a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/restapi/OnlyOfficeWebService.java b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/restapi/OnlyOfficeWebService.java
index 013da213468..edef483dc8d 100644
--- a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/restapi/OnlyOfficeWebService.java
+++ b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/restapi/OnlyOfficeWebService.java
@@ -33,6 +33,7 @@ import javax.ws.rs.POST;
 import javax.ws.rs.Path;
 import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MediaType;
@@ -72,6 +73,7 @@ public class OnlyOfficeWebService {
 	@Produces(MediaType.APPLICATION_JSON)
 	public Response postCallback(
 			@PathParam("fileId") String fileId,
+			@QueryParam("versionControlled") boolean versionControlled,
 			CallbackVO callbackVO,
 			@Context HttpHeaders httpHeaders) {
 		log.debug("OnlyOffice REST post callback request for File ID: " + fileId);
@@ -91,6 +93,7 @@ public class OnlyOfficeWebService {
 		CallbackStatus status = CallbackStatus.valueOf(callbackVO.getStatus());
 		switch(status) {
 		case Editing:
+			// If a document is opened in view mode, ONLYOFFICE does not send an editing callback and therefore the document won't be locked.
 			responseVO = lock(fileId, callbackVO);
 			break;
 		case ClosedWithoutChanges:
@@ -104,7 +107,7 @@ public class OnlyOfficeWebService {
 			break;
 		case MustSave:
 		case MustForceSave:
-			responseVO = updateContent(fileId, callbackVO);
+			responseVO = updateContent(fileId, callbackVO, versionControlled);
 			break;
 		case ErrorCorrupted:
 			log.warn("ONLYOFFICE has reported that saving the document has failed. File ID: " + fileId);
@@ -152,6 +155,9 @@ public class OnlyOfficeWebService {
 		VFSLeaf vfsLeaf = onlyOfficeService.getVfsLeaf(fileId);
 		if (vfsLeaf == null) return error();
 		
+		// Every user which opens the document sets a lock, i.e. adds a new token to the lock.
+		// Because we are not able to get the LockInfo at that place, we do not unlock for every user who closes the document.
+		// We let all lock (tokens) until the last user closes the document and then we remove the lock and all its tokens.
 		boolean lastUser = callbackVO.getUsers() == null || callbackVO.getUsers().length == 0;
 		if (lastUser) {
 			onlyOfficeService.unlock(vfsLeaf);
@@ -159,7 +165,7 @@ public class OnlyOfficeWebService {
 		return success();
 	}
 
-	private CallbackResponseVO updateContent(String fileId, CallbackVO callbackVO) {
+	private CallbackResponseVO updateContent(String fileId, CallbackVO callbackVO, boolean versionControlled) {
 		String IdentityId = callbackVO.getUsers()[0];
 		Identity identity = onlyOfficeService.getIdentity(IdentityId);
 		if (identity == null) return error();
@@ -172,7 +178,7 @@ public class OnlyOfficeWebService {
 			log.debug("ONLYOFFICE has no right to update file. File ID: " + fileId + ", identity: " + IdentityId);
 			return error();
 		}
-		boolean updated = onlyOfficeService.updateContent(vfsLeaf, identity, callbackVO.getUrl());
+		boolean updated = onlyOfficeService.updateContent(vfsLeaf, identity, callbackVO.getUrl(), versionControlled);
 		onlyOfficeService.unlock(vfsLeaf);
 		return updated? success(): error();
 	}
diff --git a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/ui/ApiConfigBuilder.java b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/ui/ApiConfigBuilder.java
index 946500f5e84..e844ca05a79 100644
--- a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/ui/ApiConfigBuilder.java
+++ b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/ui/ApiConfigBuilder.java
@@ -48,7 +48,8 @@ public class ApiConfigBuilder {
 	
 	private final VFSMetadata vfsMetadata;
 	private final Identity identity;
-	private boolean edit;
+	private boolean edit = true;
+	private boolean versionControlled = false;
 	
 	private static ObjectMapper mapper = new ObjectMapper();
 	
@@ -78,6 +79,17 @@ public class ApiConfigBuilder {
 		return this;
 	}
 	
+	/**
+	 * Default: false
+	 *
+	 * @param versionControlled
+	 * @return
+	 */
+	public ApiConfigBuilder withVersionControlled(boolean versionControlled) {
+		this.versionControlled = versionControlled;
+		return this;
+	}
+	
 	public ApiConfig build() {
 		String fileName = vfsMetadata.getFilename();
 
@@ -151,6 +163,9 @@ public class ApiConfigBuilder {
 	private String getCallbackUrl() {
 		StringBuilder fileUrl = getFileUrl();
 		fileUrl.append("callback");
+		if (versionControlled) {
+			fileUrl.append("?versionControlled=true");
+		}
 		return fileUrl.toString();
 	}
 
diff --git a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/ui/OnlyOfficeEditorController.java b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/ui/OnlyOfficeEditorController.java
index e203d619302..4426e0d6e75 100644
--- a/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/ui/OnlyOfficeEditorController.java
+++ b/src/main/java/org/olat/core/commons/services/doceditor/onlyoffice/ui/OnlyOfficeEditorController.java
@@ -76,6 +76,7 @@ public class OnlyOfficeEditorController extends BasicController {
 		} else {
 			String apiConfig = ApiConfigBuilder.builder(vfsMetadata, getIdentity())
 					.withEdit(Mode.EDIT.equals(secCallback.getMode()))
+					.withVersionControlled(secCallback.isVersionControlled())
 					.buildJson();
 			log.debug("OnlyOffice ApiConfig: " + apiConfig);
 			
-- 
GitLab