From f5d697bb38e2c742b16c8359feacea904b9c8128 Mon Sep 17 00:00:00 2001
From: srosse <none@none>
Date: Thu, 17 Jan 2013 15:54:38 +0100
Subject: [PATCH] OO-467: versions of runstructure, editortreemodel,
 CoruseConfig.xml + low level max number of versions check

---
 .../version/FolderVersioningConfigurator.java |  5 ++
 .../util/vfs/version/SimpleVersionConfig.java |  6 ++
 .../util/vfs/version/VersionsFileManager.java | 23 ++++++
 .../version/_spring/versioningCorecontext.xml |  4 +-
 .../org/olat/course/PersistingCourseImpl.java | 10 +++
 .../config/CourseConfigManagerImpl.java       | 11 +++
 .../util/vfs/version/VersionManagerTest.java  | 77 +++++++++++++++++++
 7 files changed, 135 insertions(+), 1 deletion(-)

diff --git a/src/main/java/org/olat/core/util/vfs/version/FolderVersioningConfigurator.java b/src/main/java/org/olat/core/util/vfs/version/FolderVersioningConfigurator.java
index 47e4e356b82..2b1a48a6cc5 100644
--- a/src/main/java/org/olat/core/util/vfs/version/FolderVersioningConfigurator.java
+++ b/src/main/java/org/olat/core/util/vfs/version/FolderVersioningConfigurator.java
@@ -32,6 +32,11 @@ import org.olat.core.util.vfs.VFSContainer;
  * @author srosse
  */
 public interface FolderVersioningConfigurator {
+	
+	/**
+	 * @return -1 for versioning without limit, 0 for no versioning, 1 - n is the maximum number of revision per file
+	 */
+	public int versionAllowed();
 
 	/**
 	 * @param relPath
diff --git a/src/main/java/org/olat/core/util/vfs/version/SimpleVersionConfig.java b/src/main/java/org/olat/core/util/vfs/version/SimpleVersionConfig.java
index 45559de0e7e..a575dedf95e 100644
--- a/src/main/java/org/olat/core/util/vfs/version/SimpleVersionConfig.java
+++ b/src/main/java/org/olat/core/util/vfs/version/SimpleVersionConfig.java
@@ -129,6 +129,12 @@ public class SimpleVersionConfig implements GenericEventListener, FolderVersioni
 		}
 	}
 
+	@Override
+	public int versionAllowed() {
+		return getVersionAllowed();
+	}
+
+	@Override
 	public int versionAllowed(String relPath) {
 		if(StringHelper.containsNonWhitespace(relPath)) {
 			if(relPath.startsWith("/tmp/")//no versioning in tmp
diff --git a/src/main/java/org/olat/core/util/vfs/version/VersionsFileManager.java b/src/main/java/org/olat/core/util/vfs/version/VersionsFileManager.java
index 5483423af1a..dc1c3f9618d 100644
--- a/src/main/java/org/olat/core/util/vfs/version/VersionsFileManager.java
+++ b/src/main/java/org/olat/core/util/vfs/version/VersionsFileManager.java
@@ -91,6 +91,8 @@ public class VersionsFileManager extends VersionsManager implements Initializabl
 	private File rootFolder;
 	private File rootVersionFolder;
 	private VFSContainer rootVersionsContainer;
+	
+	private FolderVersioningConfigurator versioningConfigurator;
 
 	/**
 	 * [spring]
@@ -98,6 +100,16 @@ public class VersionsFileManager extends VersionsManager implements Initializabl
 	private VersionsFileManager() {
 		INSTANCE = this;
 	}
+	
+	/**
+	 * [used by Spring]
+	 * @param versioningConfigurator
+	 */
+	public void setVersioningConfigurator(FolderVersioningConfigurator versioningConfigurator) {
+		this.versioningConfigurator = versioningConfigurator;
+	}
+
+
 
 	@Override
 	public Versions createVersionsFor(VFSLeaf leaf) {
@@ -603,6 +615,17 @@ public class VersionsFileManager extends VersionsManager implements Initializabl
 			if (identity != null) {
 				versions.setAuthor(identity.getName());
 			}
+			
+			int maxNumOfVersions = versioningConfigurator.versionAllowed();
+			if(maxNumOfVersions >= 0 && versions.getRevisions().size() >= maxNumOfVersions) {
+				List<VFSRevision> revisions = versions.getRevisions();
+				int numOfVersionsToDelete = Math.min(revisions.size(), (revisions.size() - maxNumOfVersions) + 1);
+				if(numOfVersionsToDelete > 0) {
+					List<VFSRevision> versionsToDelete = revisions.subList(0, numOfVersionsToDelete);
+					deleteRevisions(currentVersion, versionsToDelete);
+					versions = (VersionsFileImpl)currentVersion.getVersions();
+				}
+			}
 			versions.setComment(comment);
 			versions.getRevisions().add(newRevision);
 			versions.setRevisionNr(getNextRevisionNr(versions));
diff --git a/src/main/java/org/olat/core/util/vfs/version/_spring/versioningCorecontext.xml b/src/main/java/org/olat/core/util/vfs/version/_spring/versioningCorecontext.xml
index e90c113ca67..1bc1f9892ad 100644
--- a/src/main/java/org/olat/core/util/vfs/version/_spring/versioningCorecontext.xml
+++ b/src/main/java/org/olat/core/util/vfs/version/_spring/versioningCorecontext.xml
@@ -5,7 +5,9 @@
   http://www.springframework.org/schema/beans 
   http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
 
-	<bean id="versionsManager" class="org.olat.core.util.vfs.version.VersionsFileManager" init-method="init"/>
+	<bean id="versionsManager" class="org.olat.core.util.vfs.version.VersionsFileManager" init-method="init">
+		<property name="versioningConfigurator" ref="versioningConfigurator" />
+	</bean>
 
 	<bean id="versioningConfigurator" class="org.olat.core.util.vfs.version.SimpleVersionConfig"
 		depends-on="coordinatorManager,org.olat.core.util.WebappHelper,folderModule">
diff --git a/src/main/java/org/olat/course/PersistingCourseImpl.java b/src/main/java/org/olat/course/PersistingCourseImpl.java
index b1104e23f4a..0ad03dd2920 100644
--- a/src/main/java/org/olat/course/PersistingCourseImpl.java
+++ b/src/main/java/org/olat/course/PersistingCourseImpl.java
@@ -47,6 +47,8 @@ import org.olat.core.util.vfs.VFSContainer;
 import org.olat.core.util.vfs.VFSItem;
 import org.olat.core.util.vfs.VFSLeaf;
 import org.olat.core.util.vfs.callbacks.FullAccessWithQuotaCallback;
+import org.olat.core.util.vfs.version.Versionable;
+import org.olat.core.util.vfs.version.VersionsFileManager;
 import org.olat.core.util.xml.XStreamHelper;
 import org.olat.course.assessment.AssessmentHelper;
 import org.olat.course.config.CourseConfig;
@@ -81,6 +83,8 @@ import com.thoughtworks.xstream.XStream;
  */
 public class PersistingCourseImpl implements ICourse, OLATResourceable, Serializable {
 
+	private static final long serialVersionUID = -1022498371474445868L;
+
 	public static String COURSE_ROOT_DIR_NAME = "course";
 	
 	private static final String EDITORTREEMODEL_XML = "editortreemodel.xml";
@@ -408,6 +412,12 @@ public class PersistingCourseImpl implements ICourse, OLATResourceable, Serializ
 		VFSItem vfsItem = getCourseBaseContainer().resolve(fileName);
 		if (vfsItem == null) {
 			vfsItem = getCourseBaseContainer().createChildLeaf(fileName);
+		} else if(vfsItem.exists() && vfsItem instanceof Versionable) {
+			try {
+				VersionsFileManager.getInstance().addToRevisions((Versionable)vfsItem, null, "");
+			} catch (Exception e) {
+				log.error("Cannot versioned " + fileName, e);
+			}
 		}
 		XStream xstream = CourseXStreamAliases.getWriteCourseXStream();
 		XStreamHelper.writeObject(xstream, (VFSLeaf)vfsItem, obj);
diff --git a/src/main/java/org/olat/course/config/CourseConfigManagerImpl.java b/src/main/java/org/olat/course/config/CourseConfigManagerImpl.java
index 89fec404f5b..383883000e5 100644
--- a/src/main/java/org/olat/course/config/CourseConfigManagerImpl.java
+++ b/src/main/java/org/olat/course/config/CourseConfigManagerImpl.java
@@ -25,10 +25,14 @@
 
 package org.olat.course.config;
 
+import org.olat.core.logging.OLog;
+import org.olat.core.logging.Tracing;
 import org.olat.core.manager.BasicManager;
 import org.olat.core.util.vfs.VFSConstants;
 import org.olat.core.util.vfs.VFSItem;
 import org.olat.core.util.vfs.VFSLeaf;
+import org.olat.core.util.vfs.version.Versionable;
+import org.olat.core.util.vfs.version.VersionsFileManager;
 import org.olat.core.util.xml.XStreamHelper;
 import org.olat.course.CourseXStreamAliases;
 import org.olat.course.ICourse;
@@ -44,6 +48,7 @@ import com.thoughtworks.xstream.XStream;
  */
 public class CourseConfigManagerImpl extends BasicManager implements CourseConfigManager {
 
+	private static final OLog log = Tracing.createLoggerFor(CourseConfigManagerImpl.class);
 	private static final CourseConfigManagerImpl INSTANCE = new CourseConfigManagerImpl();
 
 	
@@ -114,6 +119,12 @@ public class CourseConfigManagerImpl extends BasicManager implements CourseConfi
 		if (configFile == null) {
 			// create new config file
 			configFile = course.getCourseBaseContainer().createChildLeaf(COURSECONFIG_XML);
+		} else if(configFile.exists() && configFile instanceof Versionable) {
+			try {
+				VersionsFileManager.getInstance().addToRevisions((Versionable)configFile, null, "");
+			} catch (Exception e) {
+				log.error("Cannot versioned CourseConfig.xml", e);
+			}
 		}
 		XStreamHelper.writeObject(configFile, courseConfig);
 	}
diff --git a/src/test/java/org/olat/core/util/vfs/version/VersionManagerTest.java b/src/test/java/org/olat/core/util/vfs/version/VersionManagerTest.java
index af8b716334b..d37232e9b28 100644
--- a/src/test/java/org/olat/core/util/vfs/version/VersionManagerTest.java
+++ b/src/test/java/org/olat/core/util/vfs/version/VersionManagerTest.java
@@ -35,6 +35,7 @@ import java.util.UUID;
 import junit.framework.Assert;
 
 import org.apache.commons.io.IOUtils;
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.olat.core.CoreSpringFactory;
@@ -67,6 +68,8 @@ public class VersionManagerTest extends OlatTestCase {
 	
 	@Autowired
 	private VersionsFileManager versionManager;
+	@Autowired
+	private SimpleVersionConfig versioningConfigurator;
 	
 	@Before
 	public void setUp() throws Exception {
@@ -82,6 +85,12 @@ public class VersionManagerTest extends OlatTestCase {
 		setuped = true;
 	}
 	
+	@After
+	public void resetMaxVersions() {
+		versioningConfigurator.setMaxNumberOfVersionsProperty(new Long(10));
+		versioningConfigurator.getMaxNumberOfVersionsProperty();
+	}
+	
 	@Test
 	public void testVersionManager() throws IOException {
 		//create a file
@@ -136,6 +145,74 @@ public class VersionManagerTest extends OlatTestCase {
 		assertEquals("Version 3", versions.getComment());
 	}
 	
+	@Test
+	public void testOverflow_lowLevel() throws IOException {
+		versioningConfigurator.setMaxNumberOfVersionsProperty(new Long(3));
+		
+		//create a file
+		OlatRootFolderImpl rootTest = new OlatRootFolderImpl("/test_" + UUID.randomUUID(), null);
+		String filename = getRandomName();
+		VFSLeaf file = rootTest.createChildLeaf(filename);
+		OutputStream out = file.getOutputStream(false);
+		InputStream in = VersionManagerTest.class.getResourceAsStream("test.txt");
+		int byteCopied = IOUtils.copy(in, out);
+		IOUtils.closeQuietly(in);
+		assertFalse(byteCopied == 0);
+		assertTrue(file instanceof Versionable);
+		
+		//save a first version
+		for(int i=0; i<5; i++) {
+			Versionable versionedFile = (Versionable)file;
+			InputStream inv = new ByteArrayInputStream(("Hello version " + i).getBytes());
+			versionedFile.getVersions().addVersion(id2, "Version " + (1 +i), inv);
+			IOUtils.closeQuietly(inv);
+		}
+
+		VFSItem retrievedFile = rootTest.resolve(filename);
+		Versions versions = VersionsFileManager.getInstance().createVersionsFor((VFSLeaf)retrievedFile);	
+		List<VFSRevision> revisions = versions.getRevisions();
+		assertNotNull(revisions);
+		assertEquals(3, revisions.size());
+		assertEquals("3", revisions.get(0).getRevisionNr());
+		assertEquals("4", revisions.get(1).getRevisionNr());
+		assertEquals("5", revisions.get(2).getRevisionNr());
+
+		assertEquals("Version 5", versions.getComment());
+		assertEquals(id2.getName(), revisions.get(2).getAuthor());
+	}
+	
+	@Test
+	public void testOverflow_lowLevel_deactivated() throws IOException {
+		versioningConfigurator.setMaxNumberOfVersionsProperty(new Long(0));
+		
+		//create a file
+		OlatRootFolderImpl rootTest = new OlatRootFolderImpl("/test_" + UUID.randomUUID(), null);
+		String filename = getRandomName();
+		VFSLeaf file = rootTest.createChildLeaf(filename);
+		OutputStream out = file.getOutputStream(false);
+		InputStream in = VersionManagerTest.class.getResourceAsStream("test.txt");
+		int byteCopied = IOUtils.copy(in, out);
+		IOUtils.closeQuietly(in);
+		assertFalse(byteCopied == 0);
+		assertTrue(file instanceof Versionable);
+		
+		//save a first version
+		for(int i=0; i<5; i++) {
+			Versionable versionedFile = (Versionable)file;
+			InputStream inv = new ByteArrayInputStream(("Hello version " + i).getBytes());
+			versionedFile.getVersions().addVersion(id2, "Version " + (1 +i), inv);
+			IOUtils.closeQuietly(inv);
+		}
+
+		VFSItem retrievedFile = rootTest.resolve(filename);
+		Versions versions = VersionsFileManager.getInstance().createVersionsFor((VFSLeaf)retrievedFile);	
+		List<VFSRevision> revisions = versions.getRevisions();
+		assertNotNull(revisions);
+		assertEquals(1, revisions.size());
+
+		assertEquals("Version 5", versions.getComment());
+	}
+	
 	@Test
 	public void testVersionChecksum() throws IOException {
 		OlatRootFolderImpl rootTest = new OlatRootFolderImpl("/ver-" + UUID.randomUUID(), null);
-- 
GitLab