diff --git a/src/main/java/org/olat/_spring/extensionContext.xml b/src/main/java/org/olat/_spring/extensionContext.xml index 647de02fe74d1ff9866f5785131af5ad4c254668..fb44fccf81f836b7f8f9dd82bdf0e407a36a5b80 100644 --- a/src/main/java/org/olat/_spring/extensionContext.xml +++ b/src/main/java/org/olat/_spring/extensionContext.xml @@ -383,25 +383,6 @@ </list> </property> </bean> - <!-- the version ("versionisierung") menu-entry --> - <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints" > - <property name="order" value="7204" /> - <property name="navigationKey" value="versioning" /> - <property name="actionController"> - <bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype"> - <property name="className" value="org.olat.admin.version.VersionAdminController"/> - </bean> - </property> - <property name="translationPackage" value="org.olat.admin" /> - <property name="i18nActionKey" value="menu.versions"/> - <property name="i18nDescriptionKey" value="menu.versions.alt"/> - <property name="parentTreeNodeIdentifier" value="sysconfigParent" /> - <property name="extensionPoints"> - <list> - <value>org.olat.admin.SystemAdminMainController</value> - </list> - </property> - </bean> <!-- Security admin. panel --> <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> <property name="order" value="8805" /> diff --git a/src/main/java/org/olat/admin/version/OrphanVersionsController.java b/src/main/java/org/olat/admin/version/OrphanVersionsController.java deleted file mode 100644 index 75b3e505f478ab24309554bcec54771161d6af05..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/admin/version/OrphanVersionsController.java +++ /dev/null @@ -1,201 +0,0 @@ -/** - * <a href="http://www.openolat.org"> - * OpenOLAT - Online Learning and Training</a><br> - * <p> - * Licensed under the Apache License, Version 2.0 (the "License"); <br> - * you may not use this file except in compliance with the License.<br> - * You may obtain a copy of the License at the - * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> - * <p> - * Unless required by applicable law or agreed to in writing,<br> - * software distributed under the License is distributed on an "AS IS" BASIS, <br> - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> - * See the License for the specific language governing permissions and <br> - * limitations under the License. - * <p> - * Initial code contributed and copyrighted by<br> - * frentix GmbH, http://www.frentix.com - * <p> - */ -package org.olat.admin.version; - -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; -import java.util.ArrayList; -import java.util.BitSet; -import java.util.Collections; -import java.util.List; -import java.util.Locale; - -import org.olat.core.gui.UserRequest; -import org.olat.core.gui.components.Component; -import org.olat.core.gui.components.table.DefaultColumnDescriptor; -import org.olat.core.gui.components.table.StaticColumnDescriptor; -import org.olat.core.gui.components.table.Table; -import org.olat.core.gui.components.table.TableController; -import org.olat.core.gui.components.table.TableDataModel; -import org.olat.core.gui.components.table.TableEvent; -import org.olat.core.gui.components.table.TableGuiConfiguration; -import org.olat.core.gui.components.table.TableMultiSelectEvent; -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.control.controller.BasicController; -import org.olat.core.util.vfs.version.OrphanVersion; -import org.olat.core.util.vfs.version.VFSRevision; -import org.olat.core.util.vfs.version.VersionsManager; -import org.springframework.beans.factory.annotation.Autowired; - -/** - * - * Description:<br> - * List all orphans - * - * <P> - * Initial Date: 5 mai 2011 <br> - * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com - */ -public class OrphanVersionsController extends BasicController { - - private static final String CMD_DELETE = "delete"; - private static final DecimalFormat sizeFormat = new DecimalFormat("#0.#", new DecimalFormatSymbols(Locale.ENGLISH)); - - private TableController tableCtr; - private final List<OrphanVersion> orphans; - - @Autowired - private VersionsManager versionsManager; - - public OrphanVersionsController(UserRequest ureq, WindowControl wControl, List<OrphanVersion> orphans) { - super(ureq, wControl); - - TableGuiConfiguration tableConfig = new TableGuiConfiguration(); - tableConfig.setTableEmptyMessage(translate("table.empty")); - tableConfig.setDownloadOffered(true); - tableConfig.setMultiSelect(true); - - this.orphans = orphans; - - tableCtr = new TableController(tableConfig, ureq, getWindowControl(), getTranslator()); - tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("table.header.file", 0, null, getLocale())); - tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("table.header.versions", 1, null, getLocale())); - tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("table.header.size", 2, null, getLocale())); - tableCtr.addColumnDescriptor(new StaticColumnDescriptor(CMD_DELETE, "delete", translate("delete"))); - tableCtr.setTableDataModel(new OrphanTableModel(orphans)); - - tableCtr.addMultiSelectAction("delete", CMD_DELETE); - - listenTo(tableCtr); - - putInitialPanel(tableCtr.getInitialComponent()); - } - - @Override - protected void doDispose() { - // - } - - @Override - protected void event(UserRequest ureq, Component source, Event event) { - // - } - - @Override - protected void event(UserRequest ureq, Controller source, Event event) { - if(source == tableCtr) { - if (event.getCommand().equals(Table.COMMANDLINK_ROWACTION_CLICKED)) { - TableEvent te = (TableEvent) event; - String actionid = te.getActionId(); - int rowid = te.getRowId(); - OrphanVersion orphan = (OrphanVersion) tableCtr.getTableDataModel().getObject(rowid); - if (actionid.equals(CMD_DELETE)) { - versionsManager.delete(orphan); - orphans.remove(orphan); - tableCtr.modelChanged(); - } - } else if (event.getCommand().equals(Table.COMMAND_MULTISELECT)) { - // Multiselect events - TableMultiSelectEvent tmse = (TableMultiSelectEvent) event; - BitSet selectedOrphans = tmse.getSelection(); - String actionid = tmse.getAction(); - if (CMD_DELETE.equals(actionid)) { - List<OrphanVersion> toRemove = new ArrayList<>(); - for (int i=selectedOrphans.nextSetBit(0); i >= 0; i=selectedOrphans.nextSetBit(i+1)) { - int rowCount = tableCtr.getTableDataModel().getRowCount(); - if(i >= 0 && i < rowCount) { - OrphanVersion orphan = (OrphanVersion)tableCtr.getTableDataModel().getObject(i); - versionsManager.delete(orphan); - toRemove.add(orphan); - } - } - for(OrphanVersion orphan:toRemove) { - orphans.remove(orphan); - } - tableCtr.setTableDataModel(new OrphanTableModel(orphans)); - tableCtr.modelChanged(); - } - } - } - } - - private class OrphanTableModel implements TableDataModel<OrphanVersion> { - - private List<OrphanVersion> orphanList; - - public OrphanTableModel(List<OrphanVersion> orphans) { - this.orphanList = orphans; - } - - @Override - public int getColumnCount() { - return 3; - } - - @Override - public int getRowCount() { - return orphanList.size(); - } - - @Override - public Object getValueAt(int row, int col) { - OrphanVersion orphan = getObject(row); - switch(col) { - case 0: return orphan.getOriginalFilePath(); - case 1: { - return orphan.getVersions().getRevisions().size(); - } - case 2: { - List<VFSRevision> versions = orphan.getVersions().getRevisions(); - long size = 0l; - for(VFSRevision revision:versions) { - size += revision.getSize(); - } - - String unit = "KB"; - double humanSize = size / 1024.0d; - if(humanSize > 1024) { - humanSize /= 1024; - unit = "MB"; - } - return sizeFormat.format(humanSize) + " " + unit; - } - default: return "ERROR"; - } - } - - @Override - public OrphanVersion getObject(int row) { - return orphanList.get(row); - } - - @Override - public void setObjects(List<OrphanVersion> objects) { - orphanList = objects; - } - - @Override - public Object createCopyWithEmptyList() { - return new OrphanTableModel(Collections.<OrphanVersion>emptyList()); - } - } -} \ No newline at end of file diff --git a/src/main/java/org/olat/admin/version/_i18n/LocalStrings_ar.properties b/src/main/java/org/olat/admin/version/_i18n/LocalStrings_ar.properties deleted file mode 100644 index 0353651394a26988d4e1bd12b8379c899f615cc5..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/admin/version/_i18n/LocalStrings_ar.properties +++ /dev/null @@ -1,14 +0,0 @@ -#Mon Feb 22 14:19:03 CET 2010 - - - - - -form.version=\u0627\u0644\u0625\u0635\u062F\u0627\u0631\u0627\u062A - -version.intro=\u064A\u0631\u062C\u0649 \u0648\u0636\u0639 \u0627\u0644\u0639\u062F\u062F \u0627\u0644\u0623\u0642\u0635\u0649 \u0645\u0646 \u0627\u0644\u0625\u0635\u062F\u0627\u0631\u0627\u062A \u0641\u0649 \u0627\u0644\u0645\u062C\u0644\u062F (\u0645\u062C\u0644\u062F \u0627\u0644\u0645\u062C\u0645\u0648\u0639\u0629\u060C \u0645\u062C\u0644\u062F \u0627\u0644\u0645\u0642\u0631\u0631\u060C \u0625\u0627\u0644\u062E). -version.notANumber=\u0644\u0645 \u064A\u062A\u0645 \u062A\u062D\u062F\u064A\u062F \u0631\u0642\u0645 -version.numOfVersions=\u0631\u0642\u0645 \u0627\u0644\u0625\u0635\u062F\u0627\u0631\u0627\u062A -version.off=\u062A\u0639\u0637\u064A\u0644 \u0627\u0644\u0625\u0635\u062F\u0627\u0631\u0627\u062A -version.title=\u0627\u0644\u0625\u0635\u062F\u0627\u0631\u0627\u062A -version.unlimited=\u063A\u064A\u0631 \u0645\u062D\u062F\u0648\u062F diff --git a/src/main/java/org/olat/admin/version/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/admin/version/_i18n/LocalStrings_de.properties deleted file mode 100644 index 15003597c8303da357992b4a97ac0f1d6660b585..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/admin/version/_i18n/LocalStrings_de.properties +++ /dev/null @@ -1,30 +0,0 @@ -#Mon Mar 02 09:54:03 CET 2009 -form.version=Versionierung -version.intro=Stellen Sie die maximale Anzahl von Versionen f\u00fcr eine Datei einer Ordnerkomponente (Gruppenordner, Kursordner etc.) ein. -version.title=Versionierung -version.numOfVersions=Anzahl Versionen -version.notANumber=Keine Zahl gew\u00e4hlt -version.unlimited=Unlimitiert -version.off=Versionierung ausgeschaltet -version.clean.up=Orphan Versionen l\u00f6schen -version.orphan.size=Orphan Versionen Gr\u00f6sse -version.orphan.size.calc=Gr\u00f6sse rechnen -version.orphan.size.calculating=Gr\u00f6sse am rechnen... -version.show.orphans=Orphan Versionen auflisten -version.prune.history=Versionen aufr\u00e4umen -version.maintenance.title=Verwaltung -version.maintenance.intro=Verwaltung von Versionen -table.header.file=Datei -table.header.versions=Anzhal Versionen -table.header.size=Gr\u00f6sse -table.empty=Keine orphan Versionen \u00fcbrig - - - - - - - - -confirm.delete.orphans=Wollen Sie wirklich alle Orphan Versionen l\u00f6schen? -confirm.prune.history=Wollen Sie wirklich die \u00fcberfl\u00fcssige Versionen l\u00f6schen? diff --git a/src/main/java/org/olat/admin/version/_i18n/LocalStrings_el.properties b/src/main/java/org/olat/admin/version/_i18n/LocalStrings_el.properties deleted file mode 100644 index 44aa0f618e17b24a3b0d53f5b8471649c5a10ede..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/admin/version/_i18n/LocalStrings_el.properties +++ /dev/null @@ -1,11 +0,0 @@ -#Fri Mar 12 16:12:40 CET 2010 - - -form.version=\u0395\u03BA\u03B4\u03CC\u03C3\u03B5\u03B9\u03C2 - -version.intro=\u03A0\u03B1\u03C1\u03B1\u03BA\u03B1\u03BB\u03CE \u03C1\u03C5\u03B8\u03BC\u03AF\u03C3\u03C4\u03B5 \u03C4\u03BF \u03BC\u03AD\u03B3\u03B9\u03C3\u03C4\u03BF \u03B1\u03C1\u03B9\u03B8\u03BC\u03CC \u03C4\u03C9\u03BD \u03B5\u03BA\u03B4\u03CC\u03C3\u03B5\u03C9\u03BD \u03B3\u03B9\u03B1 \u03AD\u03BD\u03B1 \u03C3\u03C4\u03BF\u03B9\u03C7\u03B5\u03AF\u03BF \u03C4\u03BF\u03C5 \u03C6\u03B1\u03BA\u03AD\u03BB\u03BF\u03C5 (\u03C6\u03AC\u03BA\u03B5\u03BB\u03BF\u03C2 \u03BF\u03BC\u03AC\u03B4\u03B1\u03C2, \u03C6\u03AC\u03BA\u03B5\u03BB\u03BF\u03C2 \u03BC\u03B1\u03B8\u03AE\u03BC\u03B1\u03C4\u03BF\u03C2 \u03BA\u03C4\u03BB.) -version.notANumber=\u0394\u03B5\u03BD \u03B5\u03C0\u03B9\u03BB\u03AD\u03C7\u03B8\u03B7\u03BA\u03B5 \u03B1\u03C1\u03B9\u03B8\u03BC\u03CC\u03C2 -version.numOfVersions=\u0391\u03C1\u03B9\u03B8\u03BC\u03CC\u03C2 \u03B5\u03BA\u03B4\u03CC\u03C3\u03B5\u03C9\u03BD -version.off=\u039F\u03B9 \u03B5\u03BA\u03B4\u03CC\u03C3\u03B5\u03B9\u03C2 \u03AD\u03C7\u03BF\u03C5\u03BD \u03B1\u03C0\u03B5\u03BD\u03B5\u03C1\u03B3\u03BF\u03C0\u03BF\u03B9\u03B7\u03B8\u03B5\u03AF -version.title=\u0395\u03BA\u03B4\u03CC\u03C3\u03B5\u03B9\u03C2 -version.unlimited=\u0391\u03C0\u03B5\u03C1\u03B9\u03CC\u03C1\u03B9\u03C3\u03C4\u03BF\u03C2 diff --git a/src/main/java/org/olat/admin/version/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/admin/version/_i18n/LocalStrings_fr.properties deleted file mode 100644 index b03f93f15367c68331f76af26ff60d3ec3bce95e..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/admin/version/_i18n/LocalStrings_fr.properties +++ /dev/null @@ -1,30 +0,0 @@ -#Sat Nov 02 20:59:58 CET 2013 - - - - - - - -confirm.delete.orphans=Voulez-vous vraiment effacer toutes les versions orphelines? -confirm.prune.history=Voulez-vous vraiment effacer toutes les versions qui d\u00E9passent la limite configur\u00E9e? -form.version=V\u00E9rification des version - -table.empty=Aucune version orpheline ne reste -table.header.file=Fichier -table.header.size=Taille -table.header.versions=Nombre de versions -version.clean.up=Supprimer les versions orphelines -version.intro=Etablir le nombre maximal de versions pour un fichier d'un dossier (dossier de groupe, dossier de cours etc.). -version.maintenance.intro=Administration des versions -version.maintenance.title=Administration -version.notANumber=Aucun nombre choisi -version.numOfVersions=Nombre de versions -version.off=V\u00E9rification des versions d\u00E9sactiv\u00E9s -version.orphan.size=Taille des versions orphelines -version.orphan.size.calc=Calculer la taille -version.orphan.size.calculating=Taille en cours de calcul -version.prune.history=Nettoyer les versions -version.show.orphans=Liste des versions orphelines -version.title=V\u00E9rification des versions -version.unlimited=Illimit\u00E9 diff --git a/src/main/java/org/olat/admin/version/_i18n/LocalStrings_jp.properties b/src/main/java/org/olat/admin/version/_i18n/LocalStrings_jp.properties deleted file mode 100644 index 2ce6cbd6f87f33e061aef49a192402dc0a40c448..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/admin/version/_i18n/LocalStrings_jp.properties +++ /dev/null @@ -1,11 +0,0 @@ -#Thu Sep 23 20:31:41 CEST 2010 - - -form.version=\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0 - -version.intro=\u30D5\u30A9\u30EB\u30C0\u69CB\u6210\u30D5\u30A1\u30A4\u30EB (\u30B0\u30EB\u30FC\u30D7\u30D5\u30A9\u30EB\u30C0\u3001\u30B3\u30FC\u30B9\u30D5\u30A9\u30EB\u30C0\u7B49) \u306E\u6700\u5927\u30D0\u30FC\u30B8\u30E7\u30F3\u6570\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002 -version.notANumber=\u6570\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002 -version.numOfVersions=\u30D0\u30FC\u30B8\u30E7\u30F3\u6570 -version.off=\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0\u7121\u52B9 -version.title=\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0 -version.unlimited=\u7121\u5236\u9650 diff --git a/src/main/java/org/olat/admin/version/_i18n/LocalStrings_nl_NL.properties b/src/main/java/org/olat/admin/version/_i18n/LocalStrings_nl_NL.properties deleted file mode 100644 index c7d2bb586b2cd8ecb99d528de8a8227b83d54b96..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/admin/version/_i18n/LocalStrings_nl_NL.properties +++ /dev/null @@ -1,14 +0,0 @@ -#Thu Sep 08 16:42:42 CEST 2011 - - - - - -form.version=Versionering - -version.intro=Gelieve het maximum aantal versies voor een maponderdeel in te stellen (groepmap, cursusmap, etc.). -version.notANumber=Geen nummer geselecteerd -version.numOfVersions=Aantal versies -version.off=Versionering gedeactiveerd -version.title=Versionering -version.unlimited=Ongelimiteerd diff --git a/src/main/java/org/olat/admin/version/_i18n/LocalStrings_pl.properties b/src/main/java/org/olat/admin/version/_i18n/LocalStrings_pl.properties deleted file mode 100644 index fe25fb23924fcdda49e5a05c7b54cac9b8f2c87f..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/admin/version/_i18n/LocalStrings_pl.properties +++ /dev/null @@ -1,19 +0,0 @@ -#Sun Dec 23 19:39:03 CET 2012 - - - -form.version=Wersjonowanie - -table.header.file=Plik -table.header.size=Rozmiar -table.header.versions=Liczba wersji -version.intro=Podaj maksymaln\u0105 liczb\u0119 wersji dla folder\u00F3w (folder grupy, folder kursu, itd.). -version.maintenance.intro=Zarz\u0105dzanie wersjami -version.maintenance.title=Zarz\u0105dzanie -version.notANumber=Nie wybrano liczby -version.numOfVersions=Liczba wersji -version.off=Wersjonowanie wy\u0142\u0105czone -version.orphan.size.calc=Oblicz rozmiar -version.orphan.size.calculating=Trwa obliczanie... -version.title=Wersjonowanie -version.unlimited=Brak limitu diff --git a/src/main/java/org/olat/admin/version/_i18n/LocalStrings_zh_CN.properties b/src/main/java/org/olat/admin/version/_i18n/LocalStrings_zh_CN.properties deleted file mode 100644 index ffc281ebc04a453ee1b5f4ad3750da07a2cd38e5..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/admin/version/_i18n/LocalStrings_zh_CN.properties +++ /dev/null @@ -1,22 +0,0 @@ -#Mon Nov 10 00:41:46 CET 2014 - - - - - -form.version=\u7248\u672C - -version.clean.up=\u5220\u9664Orphan\u7248\u672C -version.intro=\u8BF7\u4E3A\u7EC4\u6210\u6587\u4EF6\u5939\uFF08\u7FA4\u7EC4\u6587\u4EF6\u5939\uFF0C\u5B66\u7A0B\u6587\u4EF6\u5939\uFF0C\u7B49\uFF09\u7684\u6587\u4EF6\u8BBE\u7F6E\u7248\u672C\u7684\u6700\u5927\u6570\u76EE\u3002 -version.maintenance.intro=\u7248\u672C\u7BA1\u7406 -version.maintenance.title=\u7BA1\u7406 -version.notANumber=\u672A\u9009\u62E9\u4EFB\u4F55\u6570\u5B57 -version.numOfVersions=\u7248\u672C\u7684\u6570\u76EE -version.off=\u5DF2\u5173\u95ED\u7248\u672C -version.orphan.size=Orphan\u7248\u672C\u5927\u5C0F -version.orphan.size.calc=\u5927\u5C0F\u8BA1\u7B97 -version.orphan.size.calculating=\u6B63\u5728\u8BA1\u7B97\u5927\u5C0F -version.prune.history=\u7248\u672C\u6E05\u7406 -version.show.orphans=\u5217\u51FAOrphan\u7248\u672C -version.title=\u7248\u672C -version.unlimited=\u65E0\u9650 diff --git a/src/main/java/org/olat/admin/version/_i18n/LocalStrings_zh_TW.properties b/src/main/java/org/olat/admin/version/_i18n/LocalStrings_zh_TW.properties deleted file mode 100644 index ce649bf4e7d5a8647e03ec6e63fae93a8b4b2c5b..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/admin/version/_i18n/LocalStrings_zh_TW.properties +++ /dev/null @@ -1,9 +0,0 @@ -#Sat Sep 18 15:10:48 CEST 2010 -form.version=\u7248\u672C - -version.intro=\u8ACB\u8A2D\u5B9A\u8CC7\u6599\u593E\u7D44\u6210\u7684\u6A94\u6848\uFF08\u5B58\u53D6\u8CC7\u6599\u593E\u3001\u8AB2\u7A0B\u8CC7\u6599\u593E\uFF0C\u7B49\uFF09\u7684\u6700\u5927\u7248\u672C\u6578\u3002 -version.notANumber=\u672A\u9078\u64C7\u4EFB\u4F55\u6578\u5B57 -version.numOfVersions=\u7248\u672C\u6578 -version.off=\u505C\u7528\u7248\u672C\u63A7\u5236 -version.title=\u7248\u672C -version.unlimited=\u7121\u9650 diff --git a/src/main/java/org/olat/core/commons/editor/fileeditor/FileEditorController.java b/src/main/java/org/olat/core/commons/editor/fileeditor/FileEditorController.java index 4fec7f7b421a6d3dc83fb01193707b364ca95a76..9cb508a07c5edb8be1e5fe9fb4311661e986b35e 100644 --- a/src/main/java/org/olat/core/commons/editor/fileeditor/FileEditorController.java +++ b/src/main/java/org/olat/core/commons/editor/fileeditor/FileEditorController.java @@ -31,7 +31,7 @@ import org.olat.core.commons.editor.htmleditor.HTMLEditorController; import org.olat.core.commons.editor.htmleditor.WysiwygFactory; import org.olat.core.commons.editor.plaintexteditor.TextEditorController; import org.olat.core.commons.modules.bc.components.FolderComponent; -import org.olat.core.commons.modules.bc.version.VersionCommentController; +import org.olat.core.commons.services.vfs.ui.version.VersionCommentController; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.velocity.VelocityContainer; diff --git a/src/main/java/org/olat/core/commons/editor/htmleditor/HTMLEditorController.java b/src/main/java/org/olat/core/commons/editor/htmleditor/HTMLEditorController.java index 6e29fa66ad6fd6b45c53c13fa63215df3957d78e..75d219a5ac7ce3435a218a5005081a518a1c6742 100644 --- a/src/main/java/org/olat/core/commons/editor/htmleditor/HTMLEditorController.java +++ b/src/main/java/org/olat/core/commons/editor/htmleditor/HTMLEditorController.java @@ -26,6 +26,7 @@ import java.util.Date; import org.olat.core.commons.controllers.linkchooser.CustomLinkTreeModel; import org.olat.core.commons.modules.bc.FolderConfig; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItemContainer; @@ -52,13 +53,14 @@ import org.olat.core.util.coordinate.CoordinatorManager; import org.olat.core.util.coordinate.LockResult; import org.olat.core.util.resource.OresHelper; import org.olat.core.util.vfs.LocalFileImpl; +import org.olat.core.util.vfs.VFSConstants; 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.version.Versionable; import org.olat.modules.edusharing.EdusharingFilter; import org.olat.modules.edusharing.VFSEdusharingProvider; import org.olat.user.UserManager; +import org.springframework.beans.factory.annotation.Autowired; /** * Description:<br> @@ -120,6 +122,11 @@ public class HTMLEditorController extends FormBasicController { private String fileToLargeError = null; private VFSEdusharingProvider edusharingProvider; private Object userObject; + + @Autowired + private UserManager userManager; + @Autowired + private VFSRepositoryService vfsRepositoryService; /** * Factory method to create a file based HTML editor instance that uses @@ -199,7 +206,7 @@ public class HTMLEditorController extends FormBasicController { VelocityContainer vc = (VelocityContainer) flc.getComponent(); if (!lock.isSuccess()) { vc.contextPut("locked", Boolean.TRUE); - String fullname = UserManager.getInstance().getUserDisplayName(lock.getOwner()); + String fullname = userManager.getUserDisplayName(lock.getOwner()); vc.contextPut("lockOwner", fullname); editable = false; return; @@ -390,11 +397,15 @@ public class HTMLEditorController extends FormBasicController { */ private String parsePage(VFSLeaf vfsLeaf) { // Load data with given encoding - InputStream is = vfsLeaf.getInputStream(); - if (is == null) { throw new AssertException("Could not open input stream for file::" - + getFileDebuggingPath(this.baseContainer, this.fileRelPath)); } - this.charSet = SimpleHtmlParser.extractHTMLCharset(vfsLeaf); - String leafData = FileUtils.load(is, charSet); + String leafData = null; + try(InputStream is = vfsLeaf.getInputStream()) { + if (is == null) { throw new AssertException("Could not open input stream for file::" + + getFileDebuggingPath(this.baseContainer, this.fileRelPath)); } + this.charSet = SimpleHtmlParser.extractHTMLCharset(vfsLeaf); + leafData = FileUtils.load(is, charSet); + } catch(IOException e) { + logError("", e); + } if (leafData == null || leafData.length() == 0) { leafData = ""; } @@ -471,9 +482,9 @@ public class HTMLEditorController extends FormBasicController { } // save the file - if(versionsEnabled && fileLeaf instanceof Versionable && ((Versionable)fileLeaf).getVersions().isVersioned()) { + if(versionsEnabled && fileLeaf.canVersion() == VFSConstants.YES) { try(InputStream inStream = FileUtils.getInputStream(fileContent.toString(), charSet)) { - ((Versionable)fileLeaf).getVersions().addVersion(getIdentity(), "", inStream); + vfsRepositoryService.addVersion(fileLeaf, getIdentity(), "", inStream); } catch(IOException e) { logError("", e); } diff --git a/src/main/java/org/olat/core/commons/editor/plaintexteditor/TextEditorController.java b/src/main/java/org/olat/core/commons/editor/plaintexteditor/TextEditorController.java index c1ee7edfcff0241ad71f3c01823bdb3c1b8fc3a5..31a8cae7deeb0874e9afb5e6212270f6f2c74252 100644 --- a/src/main/java/org/olat/core/commons/editor/plaintexteditor/TextEditorController.java +++ b/src/main/java/org/olat/core/commons/editor/plaintexteditor/TextEditorController.java @@ -24,6 +24,7 @@ import java.io.InputStream; import java.io.OutputStream; import org.olat.core.commons.modules.bc.FolderConfig; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItemContainer; @@ -37,8 +38,9 @@ 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.util.FileUtils; +import org.olat.core.util.vfs.VFSConstants; import org.olat.core.util.vfs.VFSLeaf; -import org.olat.core.util.vfs.version.Versionable; +import org.springframework.beans.factory.annotation.Autowired; /** * @@ -56,6 +58,9 @@ public class TextEditorController extends FormBasicController { private final VFSLeaf vfsLeaf; private final String encoding; private final boolean readonly; + + @Autowired + private VFSRepositoryService vfsRepositoryService; public TextEditorController(UserRequest ureq, WindowControl wControl, VFSLeaf vfsLeaf, String encoding, boolean readonly) { super(ureq, wControl, LAYOUT_VERTICAL); @@ -109,9 +114,9 @@ public class TextEditorController extends FormBasicController { private void doSave() { String content = contentEl.getValue(); - if(vfsLeaf instanceof Versionable && ((Versionable)vfsLeaf).getVersions().isVersioned()) { + if(vfsLeaf.canVersion() == VFSConstants.YES) { try (InputStream inStream = FileUtils.getInputStream(content, encoding)) { - ((Versionable)vfsLeaf).getVersions().addVersion(getIdentity(), "", inStream); + vfsRepositoryService.addVersion(vfsLeaf, getIdentity(), "", inStream); } catch (IOException e) { logError("", e); } diff --git a/src/main/java/org/olat/core/commons/modules/bc/FileCopyController.java b/src/main/java/org/olat/core/commons/modules/bc/FileCopyController.java index 2c263e52f0819bb68164d6945db02adeebc2dbac..968d51b2b0b008118cf7345c4a1aa60cf4a84a52 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/FileCopyController.java +++ b/src/main/java/org/olat/core/commons/modules/bc/FileCopyController.java @@ -22,14 +22,20 @@ package org.olat.core.commons.modules.bc; import static java.util.Arrays.asList; +import java.util.List; + import org.olat.core.commons.controllers.linkchooser.FileLinkChooserController; import org.olat.core.commons.controllers.linkchooser.LinkChooserController; import org.olat.core.commons.controllers.linkchooser.URLChoosenEvent; import org.olat.core.commons.modules.bc.commands.FolderCommand; import org.olat.core.commons.modules.bc.commands.FolderCommandStatus; import org.olat.core.commons.modules.bc.components.FolderComponent; -import org.olat.core.commons.modules.bc.version.RevisionListController; -import org.olat.core.commons.modules.bc.version.VersionCommentController; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRepositoryService; +import org.olat.core.commons.services.vfs.VFSRevision; +import org.olat.core.commons.services.vfs.VFSVersionModule; +import org.olat.core.commons.services.vfs.ui.version.RevisionListController; +import org.olat.core.commons.services.vfs.ui.version.VersionCommentController; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.velocity.VelocityContainer; import org.olat.core.gui.control.Controller; @@ -45,14 +51,13 @@ import org.olat.core.logging.activity.CoreLoggingResourceable; import org.olat.core.logging.activity.ThreadLocalUserActivityLogger; import org.olat.core.util.FileUtils; import org.olat.core.util.Util; +import org.olat.core.util.vfs.VFSConstants; 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.VFSLockApplicationType; import org.olat.core.util.vfs.VFSLockManager; import org.olat.core.util.vfs.VFSManager; -import org.olat.core.util.vfs.version.Versionable; -import org.olat.core.util.vfs.version.Versions; import org.springframework.beans.factory.annotation.Autowired; /** @@ -80,6 +85,10 @@ public class FileCopyController extends LinkChooserController { @Autowired private VFSLockManager vfsLockManager; + @Autowired + private VFSVersionModule versionsModule; + @Autowired + private VFSRepositoryService vfsRepositoryService; public FileCopyController(UserRequest ureq, WindowControl wControl, VFSContainer rootDir, FolderComponent folderComponent) { @@ -129,10 +138,9 @@ public class FileCopyController extends LinkChooserController { if (event instanceof ButtonClickedEvent) { ButtonClickedEvent buttonClickedEvent = (ButtonClickedEvent) event; if (buttonClickedEvent.getPosition() == 0) { //ok - if (existingVFSItem instanceof Versionable && ((Versionable)existingVFSItem).getVersions().isVersioned()) { + if (existingVFSItem.canVersion() == VFSConstants.YES) { //new version - String relPath = existingVFSItem.getRelPath(); - int maxNumOfRevisions = FolderConfig.versionsAllowed(relPath); + int maxNumOfRevisions = versionsModule.getMaxNumberOfVersions(); if(maxNumOfRevisions == 0) { //someone play with the configuration // Overwrite... @@ -222,8 +230,7 @@ public class FileCopyController extends LinkChooserController { } //ok, new version of the file - Versionable existingVersionableItem = (Versionable)existingVFSItem; - boolean ok = existingVersionableItem.getVersions().addVersion(ureq.getIdentity(), comment, sourceLeaf.getInputStream()); + boolean ok = vfsRepositoryService.addVersion(existingVFSItem, ureq.getIdentity(), comment, sourceLeaf.getInputStream()); if(ok) { newFile = existingVFSItem; } @@ -248,14 +255,14 @@ public class FileCopyController extends LinkChooserController { //don't want to delete revisions fireEvent(ureq, FolderCommand.FOLDERCOMMAND_FINISHED); } else { - if (existingVFSItem instanceof Versionable && ((Versionable)existingVFSItem).getVersions().isVersioned()) { - + if (existingVFSItem.canVersion() == VFSConstants.YES) { + revisionListDialogBox.deactivate(); - Versionable versionable = (Versionable)existingVFSItem; - Versions versions = versionable.getVersions(); - int maxNumOfRevisions = FolderConfig.versionsAllowed(null); - if(maxNumOfRevisions < 0 || maxNumOfRevisions > versions.getRevisions().size()) { + int maxNumOfRevisions = versionsModule.getMaxNumberOfVersions(); + VFSMetadata metadata = vfsRepositoryService.getMetadataFor(existingVFSItem); + List<VFSRevision> revisions = vfsRepositoryService.getRevisions(metadata); + if(maxNumOfRevisions < 0 || maxNumOfRevisions > revisions.size()) { removeAsListenerAndDispose(commentVersionCtr); boolean locked = vfsLockManager.isLocked(existingVFSItem, VFSLockApplicationType.vfs); @@ -271,7 +278,7 @@ public class FileCopyController extends LinkChooserController { } else { removeAsListenerAndDispose(revisionListCtr); - revisionListCtr = new RevisionListController(ureq,getWindowControl(),versionable, false); + revisionListCtr = new RevisionListController(ureq,getWindowControl(), existingVFSItem, false); listenTo(revisionListCtr); removeAsListenerAndDispose(revisionListDialogBox); @@ -308,11 +315,11 @@ public class FileCopyController extends LinkChooserController { asList(translate("ul.overwrite.threeoptions.rename", renamedFilename), translate("ul.overwrite.threeoptions.cancel"))); listenTo(lockedFileDialog); lockedFileDialog.activate(); - } else if (existingVFSItem instanceof Versionable && ((Versionable)existingVFSItem).getVersions().isVersioned()) { - Versionable versionable = (Versionable)existingVFSItem; - Versions versions = versionable.getVersions(); - String relPath = existingVFSItem.getRelPath(); - int maxNumOfRevisions = FolderConfig.versionsAllowed(relPath); + } else if (existingVFSItem.canVersion() == VFSConstants.YES) { + + int maxNumOfRevisions = versionsModule.getMaxNumberOfVersions(); + VFSMetadata metadata = vfsRepositoryService.getMetadataFor(existingVFSItem); + List<VFSRevision> revisions = vfsRepositoryService.getRevisions(metadata); if(maxNumOfRevisions == 0) { //it's possible if someone change the configuration // let calling method decide what to do. @@ -325,7 +332,7 @@ public class FileCopyController extends LinkChooserController { overwriteDialog.activate(); - } else if(versions.getRevisions().isEmpty() || maxNumOfRevisions < 0 || maxNumOfRevisions > versions.getRevisions().size()) { + } else if(revisions.isEmpty() || maxNumOfRevisions < 0 || maxNumOfRevisions > revisions.size()) { // let calling method decide what to do. removeAsListenerAndDispose(overwriteDialog); overwriteDialog = DialogBoxUIFactory.createGenericDialog(ureq, getWindowControl(), translate("ul.overwrite.threeoptions.title"), @@ -338,11 +345,11 @@ public class FileCopyController extends LinkChooserController { } else { - String title = translate("ul.tooManyRevisions.title", new String[]{Integer.toString(maxNumOfRevisions), Integer.toString(versions.getRevisions().size())}); - String description = translate("ul.tooManyRevisions.description", new String[]{Integer.toString(maxNumOfRevisions), Integer.toString(versions.getRevisions().size())}); + String title = translate("ul.tooManyRevisions.title", new String[]{Integer.toString(maxNumOfRevisions), Integer.toString(revisions.size())}); + String description = translate("ul.tooManyRevisions.description", new String[]{Integer.toString(maxNumOfRevisions), Integer.toString(revisions.size())}); removeAsListenerAndDispose(revisionListCtr); - revisionListCtr = new RevisionListController(ureq, getWindowControl(), versionable, null, description, false); + revisionListCtr = new RevisionListController(ureq, getWindowControl(), existingVFSItem, null, description, false); listenTo(revisionListCtr); removeAsListenerAndDispose(revisionListDialogBox); diff --git a/src/main/java/org/olat/core/commons/modules/bc/FileUploadController.java b/src/main/java/org/olat/core/commons/modules/bc/FileUploadController.java index 65f6cdb07fb5bc4265e40faf29a79db483ef0e55..de3ee19f34f602bd963538ab43e8eeb28235634c 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/FileUploadController.java +++ b/src/main/java/org/olat/core/commons/modules/bc/FileUploadController.java @@ -41,11 +41,13 @@ import java.util.regex.Pattern; import org.olat.core.commons.modules.bc.commands.FolderCommandStatus; import org.olat.core.commons.modules.bc.meta.MetaInfoFormController; -import org.olat.core.commons.modules.bc.version.RevisionListController; -import org.olat.core.commons.modules.bc.version.VersionCommentController; import org.olat.core.commons.services.image.ImageService; import org.olat.core.commons.services.vfs.VFSMetadata; import org.olat.core.commons.services.vfs.VFSRepositoryService; +import org.olat.core.commons.services.vfs.VFSRevision; +import org.olat.core.commons.services.vfs.VFSVersionModule; +import org.olat.core.commons.services.vfs.ui.version.RevisionListController; +import org.olat.core.commons.services.vfs.ui.version.VersionCommentController; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItemContainer; @@ -82,8 +84,6 @@ import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSLockApplicationType; import org.olat.core.util.vfs.VFSLockManager; import org.olat.core.util.vfs.VFSManager; -import org.olat.core.util.vfs.version.Versionable; -import org.olat.core.util.vfs.version.Versions; import org.springframework.beans.factory.annotation.Autowired; /** @@ -156,6 +156,8 @@ public class FileUploadController extends FormBasicController { @Autowired private VFSLockManager vfsLockManager; @Autowired + private VFSVersionModule versionsModule; + @Autowired private VFSRepositoryService vfsRepositoryService; private String subfolderPath; @@ -431,7 +433,7 @@ public class FileUploadController extends FormBasicController { if(FolderCommandStatus.STATUS_CANCELED == revisionListCtr.getStatus()) { //don't want to delete revisions, clean the temporary file doCancel(ureq); - } else if (existingVFSItem instanceof Versionable && ((Versionable)existingVFSItem).getVersions().isVersioned()) { + } else if (existingVFSItem.canVersion() == VFSConstants.YES) { doFinishRevisionList(ureq); } } @@ -449,7 +451,7 @@ public class FileUploadController extends FormBasicController { } private void doFinishOverwrite(UserRequest ureq) { - if (existingVFSItem instanceof Versionable && ((Versionable)existingVFSItem).getVersions().isVersioned()) { + if (existingVFSItem.canVersion() == VFSConstants.YES) { //new version int maxNumOfRevisions = getMaxNumOfRevisionsOfExistingVFSItem(); if(maxNumOfRevisions == 0) { @@ -496,12 +498,11 @@ public class FileUploadController extends FormBasicController { } //ok, new version of the file - Versionable existingVersionableItem = (Versionable)existingVFSItem; - boolean ok = existingVersionableItem.getVersions().addVersion(ureq.getIdentity(), comment, newFile.getInputStream()); - if(ok) { - newFile.deleteSilently(); - //what can i do if existingVFSItem is a container - if(existingVFSItem instanceof VFSLeaf) { + if(existingVFSItem instanceof VFSLeaf && existingVFSItem.canVersion() == VFSConstants.YES) { + boolean ok = vfsRepositoryService.addVersion((VFSLeaf)existingVFSItem, ureq.getIdentity(), comment, newFile.getInputStream()); + if(ok) { + newFile.deleteSilently(); + //what can i do if existingVFSItem is a container newFile = (VFSLeaf)existingVFSItem; } } @@ -513,28 +514,30 @@ public class FileUploadController extends FormBasicController { existingVFSItem = existingVFSItem.getParentContainer().resolve(existingVFSItem.getName()); } - Versionable versionable = (Versionable)existingVFSItem; - Versions versions = versionable.getVersions(); + VFSMetadata metadata = vfsRepositoryService.getMetadataFor(existingVFSItem); + List<VFSRevision> revisions = vfsRepositoryService.getRevisions(metadata); int maxNumOfRevisions = getMaxNumOfRevisionsOfExistingVFSItem(); - if(maxNumOfRevisions < 0 || maxNumOfRevisions > versions.getRevisions().size()) { + if(maxNumOfRevisions < 0 || maxNumOfRevisions > revisions.size()) { askForComment(ureq); } else { - askToReduceRevisionList(ureq, versionable); + askToReduceRevisionList(ureq, (VFSLeaf)existingVFSItem); } } private int getMaxNumOfRevisionsOfExistingVFSItem() { - String relPath = existingVFSItem.getRelPath(); - return FolderConfig.versionsAllowed(relPath); + return versionsModule.getMaxNumberOfVersions(); } - private void askToReduceRevisionList(UserRequest ureq, Versionable versionable) { + private void askToReduceRevisionList(UserRequest ureq, VFSLeaf versionable) { removeAsListenerAndDispose(revisionListCtr); removeAsListenerAndDispose(revisionListDialogBox); - Versions versions = versionable.getVersions(); int maxNumOfRevisions = getMaxNumOfRevisionsOfExistingVFSItem(); - String[] params = new String[]{ Integer.toString(maxNumOfRevisions), Integer.toString(versions.getRevisions().size()) }; + VFSMetadata metadata = vfsRepositoryService.getMetadataFor(versionable); + List<VFSRevision> revisions = vfsRepositoryService.getRevisions(metadata); + + int numOfRevisions = revisions.size(); + String[] params = new String[]{ Integer.toString(maxNumOfRevisions), Integer.toString(numOfRevisions) }; String title = translate("ul.tooManyRevisions.title", params); String description = translate("ul.tooManyRevisions.description", params); @@ -627,7 +630,7 @@ public class FileUploadController extends FormBasicController { if (locked) { //the file is locked and cannot be overwritten lockedFileDialog(ureq, renamedFilename); - } else if (existingVFSItem instanceof Versionable && ((Versionable)existingVFSItem).getVersions().isVersioned()) { + } else if (existingVFSItem.canVersion() == VFSConstants.YES) { uploadVersionedFile(ureq, renamedFilename); } else { askOverwriteOrRename(ureq, renamedFilename); @@ -651,19 +654,19 @@ public class FileUploadController extends FormBasicController { } private void uploadVersionedFile(UserRequest ureq, String renamedFilename) { - Versionable versionable = (Versionable)existingVFSItem; - Versions versions = versionable.getVersions(); + VFSMetadata metadata = vfsRepositoryService.getMetadataFor(existingVFSItem); + List<VFSRevision> revisions = vfsRepositoryService.getRevisions(metadata); int maxNumOfRevisions = getMaxNumOfRevisionsOfExistingVFSItem(); if(maxNumOfRevisions == 0) { //it's possible if someone change the configuration // let calling method decide what to do. askOverwriteOrRename(ureq, renamedFilename); - } else if(versions.getRevisions().isEmpty() || maxNumOfRevisions < 0 || maxNumOfRevisions > versions.getRevisions().size()) { + } else if(revisions.isEmpty() || maxNumOfRevisions < 0 || maxNumOfRevisions > revisions.size()) { // let calling method decide what to do. askNewVersionOrRename(ureq, renamedFilename); } else { //too many revisions - askToReduceRevisionList(ureq, versionable); + askToReduceRevisionList(ureq, (VFSLeaf)existingVFSItem); } } diff --git a/src/main/java/org/olat/core/commons/modules/bc/FolderConfig.java b/src/main/java/org/olat/core/commons/modules/bc/FolderConfig.java index 3f23ab173cbce1a1e67c8f1dcac82603af5334b3..1ef8d746f45618f1643e73ecb0487af4e65dfe18 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/FolderConfig.java +++ b/src/main/java/org/olat/core/commons/modules/bc/FolderConfig.java @@ -29,9 +29,6 @@ package org.olat.core.commons.modules.bc; import java.nio.file.Path; import java.nio.file.Paths; -import org.olat.core.util.vfs.VFSContainer; -import org.olat.core.util.vfs.version.FolderVersioningConfigurator; - /** * Initial Date: 18.12.2002 * @@ -63,7 +60,6 @@ public class FolderConfig { private static final String META_DIR = "/.meta"; private static final String TMP_DIR = "/tmp"; private static final String VERSION_DIR = "/.version"; - private static FolderVersioningConfigurator versioningConfigurator; private static boolean sendDocumentToExtern; private static boolean sendDocumentLinkOnly; @@ -333,33 +329,4 @@ public class FolderConfig { public static boolean getSendDocumentLinkOnly() { return sendDocumentLinkOnly; } - - public static FolderVersioningConfigurator getVersioningConfigurator() { - return versioningConfigurator; - } - - public static void setVersioningConfigurator(FolderVersioningConfigurator versioningConfigurator) { - FolderConfig.versioningConfigurator = versioningConfigurator; - } - - /** - * @return -1 if the number of revisions for the file is unlimited; 0 if versions are not allowed; - * 1 - n is the maximum allowed number of revisions - */ - public static int versionsAllowed(String relPath) { - if(versioningConfigurator == null) { - return 0; - } - return versioningConfigurator.versionAllowed(relPath); - } - - /** - * @return true if versioning is enabled for the container - */ - public static boolean versionsEnabled(VFSContainer container) { - if(versioningConfigurator == null) { - return false; - } - return versioningConfigurator.versionEnabled(container); - } } diff --git a/src/main/java/org/olat/core/commons/modules/bc/FolderModule.java b/src/main/java/org/olat/core/commons/modules/bc/FolderModule.java index 5d69dbc670628f3f6400c85eeeb05c56c050b42d..7f63a76277842a06a00bef70f70cab91f577119c 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/FolderModule.java +++ b/src/main/java/org/olat/core/commons/modules/bc/FolderModule.java @@ -35,7 +35,6 @@ import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.util.StringHelper; import org.olat.core.util.coordinate.CoordinatorManager; -import org.olat.core.util.vfs.version.FolderVersioningConfigurator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @@ -67,9 +66,6 @@ public class FolderModule extends AbstractSpringModule { @Value("${folder.force.download:true}") private String forceDownload; - @Autowired - private FolderVersioningConfigurator versioning; - @Autowired public FolderModule(CoordinatorManager coordinatorManager) { super(coordinatorManager); @@ -114,7 +110,6 @@ public class FolderModule extends AbstractSpringModule { @Override public void init() { - FolderConfig.setVersioningConfigurator(versioning); updateProperties(); } @@ -125,14 +120,6 @@ public class FolderModule extends AbstractSpringModule { } } - /** - * [used by spring] - * @param versioning - */ - public void setVersioning(FolderVersioningConfigurator versioning) { - this.versioning = versioning; - } - public boolean isForceDownload() { return "true".equals(forceDownload); } diff --git a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdDeletedFiles.java b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdDeletedFiles.java index 40427a79e913e75f6274e577f4cd402a5bb00e48..bec2c048bede67c42358436d563853f7e6508f62 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdDeletedFiles.java +++ b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdDeletedFiles.java @@ -20,7 +20,7 @@ package org.olat.core.commons.modules.bc.commands; import org.olat.core.commons.modules.bc.components.FolderComponent; -import org.olat.core.commons.modules.bc.version.DeletedFileListController; +import org.olat.core.commons.services.vfs.ui.version.DeletedFileListController; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.control.Controller; diff --git a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdMoveCopy.java b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdMoveCopy.java index 0a76ea7fa15712894a42616e9a0fe0f545822d56..d4d3fa1b41695a0aadf5460a85881fa5d9943e5d 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdMoveCopy.java +++ b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdMoveCopy.java @@ -34,6 +34,7 @@ import org.olat.core.commons.modules.bc.FolderEvent; import org.olat.core.commons.modules.bc.components.FolderComponent; import org.olat.core.commons.services.notifications.NotificationsManager; import org.olat.core.commons.services.notifications.SubscriptionContext; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.link.Link; @@ -57,7 +58,6 @@ import org.olat.core.util.vfs.VFSManager; import org.olat.core.util.vfs.VFSStatus; import org.olat.core.util.vfs.callbacks.VFSSecurityCallback; import org.olat.core.util.vfs.filters.VFSItemFilter; -import org.olat.core.util.vfs.version.Versionable; import org.springframework.beans.factory.annotation.Autowired; public class CmdMoveCopy extends DefaultController implements FolderCommand { @@ -75,6 +75,8 @@ public class CmdMoveCopy extends DefaultController implements FolderCommand { @Autowired private VFSLockManager vfsLockManager; + @Autowired + private VFSRepositoryService vfsRepositoryService; protected CmdMoveCopy(WindowControl wControl, boolean move) { super(wControl); @@ -170,10 +172,10 @@ public class CmdMoveCopy extends DefaultController implements FolderCommand { for (VFSItem vfsSource:sources) { VFSItem targetFile = target.resolve(vfsSource.getName()); - if(vfsSource instanceof VFSLeaf && targetFile != null && targetFile instanceof Versionable - && ((Versionable)targetFile).getVersions().isVersioned()) { + if(vfsSource instanceof VFSLeaf && targetFile != null && targetFile.canVersion() == VFSConstants.YES) { //add a new version to the file - ((Versionable)targetFile).getVersions().addVersion(null, "", ((VFSLeaf)vfsSource).getInputStream()); + VFSLeaf sourceLeaf = (VFSLeaf)vfsSource; + vfsRepositoryService.addVersion(sourceLeaf, ureq.getIdentity(), "", sourceLeaf.getInputStream()); } else { vfsStatus = target.copyFrom(vfsSource); } diff --git a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdUnzip.java b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdUnzip.java index a1334855f360f927938f0b287e596663fe4de91e..7cdae01ead18df875c1f4ce05b8fa76ea0ab94b9 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdUnzip.java +++ b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdUnzip.java @@ -31,7 +31,6 @@ import java.util.Collections; import java.util.List; import org.olat.core.commons.modules.bc.FileSelection; -import org.olat.core.commons.modules.bc.FolderConfig; import org.olat.core.commons.modules.bc.components.FolderComponent; import org.olat.core.commons.services.notifications.NotificationsManager; import org.olat.core.commons.services.notifications.SubscriptionContext; @@ -154,8 +153,7 @@ public class CmdUnzip extends BasicController implements FolderCommand { return Collections.emptyList(); } - boolean versioning = FolderConfig.versionsEnabled(currentContainer); - if(!versioning) { + if(currentContainer.canVersion() != VFSConstants.YES) { //this command don't overwrite existing folders return Collections.emptyList(); } @@ -182,7 +180,7 @@ public class CmdUnzip extends BasicController implements FolderCommand { // we make a new folder with the same name as the zip file String sZipContainer = name.substring(0, name.length() - 4); - boolean versioning = FolderConfig.versionsEnabled(currentContainer); + boolean versioning = currentContainer.canVersion() == VFSConstants.YES; VFSContainer zipContainer = currentContainer.createChildContainer(sZipContainer); if (zipContainer == null) { diff --git a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdViewRevisions.java b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdViewRevisions.java index bec22c4fe9f3635e622b254091419a4859954e0a..740bdb31f021f0be1e91307f08922071488a04d9 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdViewRevisions.java +++ b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdViewRevisions.java @@ -21,7 +21,7 @@ package org.olat.core.commons.modules.bc.commands; import org.olat.core.commons.modules.bc.components.FolderComponent; import org.olat.core.commons.modules.bc.components.ListRenderer; -import org.olat.core.commons.modules.bc.version.RevisionListController; +import org.olat.core.commons.services.vfs.ui.version.RevisionListController; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.control.Controller; @@ -30,10 +30,10 @@ import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.BasicController; import org.olat.core.gui.translator.Translator; import org.olat.core.util.StringHelper; +import org.olat.core.util.vfs.VFSConstants; import org.olat.core.util.vfs.VFSItem; import org.olat.core.util.vfs.VFSLockApplicationType; import org.olat.core.util.vfs.VFSLockManager; -import org.olat.core.util.vfs.version.Versionable; import org.springframework.beans.factory.annotation.Autowired; /** @@ -84,7 +84,7 @@ public class CmdViewRevisions extends BasicController implements FolderCommand { if(status == FolderCommandStatus.STATUS_FAILED) { return null; } - if (!(currentItem instanceof Versionable)) { + if (currentItem.canVersion() != VFSConstants.YES) { status = FolderCommandStatus.STATUS_FAILED; getWindowControl().setError(translator.translate("failed")); return null; @@ -93,7 +93,7 @@ public class CmdViewRevisions extends BasicController implements FolderCommand { setTranslator(translator); boolean locked = vfsLockManager.isLockedForMe(currentItem, ureq.getIdentity(), ureq.getUserSession().getRoles(), VFSLockApplicationType.vfs); - revisionListCtr = new RevisionListController(ureq, wControl, (Versionable)currentItem, locked); + revisionListCtr = new RevisionListController(ureq, wControl, currentItem, locked); listenTo(revisionListCtr); putInitialPanel(revisionListCtr.getInitialComponent()); return this; diff --git a/src/main/java/org/olat/core/commons/modules/bc/components/FolderComponent.java b/src/main/java/org/olat/core/commons/modules/bc/components/FolderComponent.java index 477fa8eaeddab031b17f40e473b57e09e12a43fe..25619784fcd784900da1627f9374c727048e54f8 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/components/FolderComponent.java +++ b/src/main/java/org/olat/core/commons/modules/bc/components/FolderComponent.java @@ -59,7 +59,6 @@ import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.filters.VFSItemExcludePrefixFilter; import org.olat.core.util.vfs.filters.VFSItemFilter; import org.olat.core.util.vfs.filters.VFSSystemItemFilter; -import org.olat.core.util.vfs.version.Versionable; /** * Initial Date: Feb 11, 2004 @@ -287,6 +286,8 @@ public class FolderComponent extends AbstractComponent { comparator = new Comparator<VFSItem>() { @Override public int compare(VFSItem o1, VFSItem o2) { + return o1.getName().compareTo(o2.getName()); + /* Versionable v1 = null; Versionable v2 = null; if (o1 instanceof Versionable) { @@ -309,6 +310,7 @@ public class FolderComponent extends AbstractComponent { return 1; } return (sortAsc) ? collator.compare(r1, r2) : collator.compare(r2, r1); + */ } }; } else if (col.equals(SORT_LOCK)) { // sort after modification date (if same, then name) diff --git a/src/main/java/org/olat/core/commons/modules/bc/components/FolderComponentRenderer.java b/src/main/java/org/olat/core/commons/modules/bc/components/FolderComponentRenderer.java index c701737ce8def2f52090fe78255ebef3ed153646..bd0a601f5e5baa20a7118b3ce9eaa44a2e9d5100 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/components/FolderComponentRenderer.java +++ b/src/main/java/org/olat/core/commons/modules/bc/components/FolderComponentRenderer.java @@ -28,7 +28,6 @@ package org.olat.core.commons.modules.bc.components; import java.util.List; -import org.olat.core.commons.modules.bc.FolderConfig; import org.olat.core.commons.modules.bc.FolderRunController; import org.olat.core.commons.modules.bc.commands.FolderCommandFactory; import org.olat.core.gui.components.Component; @@ -95,7 +94,7 @@ public class FolderComponentRenderer extends DefaultComponentRenderer { } boolean canDelete = false; - boolean canVersion = FolderConfig.versionsEnabled(fc.getCurrentContainer()); + boolean canVersion = fc.getCurrentContainer().canVersion() == VFSConstants.YES; boolean canMail = fc.isCanMail(); List<VFSItem> children = fc.getCurrentContainerChildren(); diff --git a/src/main/java/org/olat/core/commons/modules/bc/components/ListRenderer.java b/src/main/java/org/olat/core/commons/modules/bc/components/ListRenderer.java index 8e67aaede13707a04e85259dd23881de2d78b929..5b9fa671b8dc0caeff90b8c1b0230d65615bba49 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/components/ListRenderer.java +++ b/src/main/java/org/olat/core/commons/modules/bc/components/ListRenderer.java @@ -35,7 +35,6 @@ import java.util.stream.Collectors; import org.olat.core.CoreSpringFactory; import org.olat.core.commons.modules.bc.FileSelection; -import org.olat.core.commons.modules.bc.FolderConfig; import org.olat.core.commons.modules.bc.FolderLicenseHandler; import org.olat.core.commons.modules.bc.FolderManager; import org.olat.core.commons.services.license.License; @@ -45,6 +44,7 @@ import org.olat.core.commons.services.license.ui.LicenseRenderer; import org.olat.core.commons.services.vfs.VFSLeafEditor; import org.olat.core.commons.services.vfs.VFSMetadata; import org.olat.core.commons.services.vfs.VFSRepositoryService; +import org.olat.core.commons.services.vfs.VFSRevision; import org.olat.core.gui.components.form.flexible.impl.NameValuePair; import org.olat.core.gui.control.winmgr.AJAXFlags; import org.olat.core.gui.render.StringOutput; @@ -66,8 +66,6 @@ import org.olat.core.util.vfs.VFSLockManager; import org.olat.core.util.vfs.VirtualContainer; import org.olat.core.util.vfs.filters.VFSSystemItemFilter; import org.olat.core.util.vfs.lock.LockInfo; -import org.olat.core.util.vfs.version.Versionable; -import org.olat.core.util.vfs.version.Versions; import org.olat.user.UserManager; /** @@ -142,7 +140,7 @@ public class ListRenderer { } VFSContainer currentContainer = fc.getCurrentContainer(); - boolean canVersion = FolderConfig.versionsEnabled(currentContainer); + boolean canVersion = currentContainer.canVersion() == VFSConstants.YES; String sortOrder = fc.getCurrentSortOrder(); boolean sortAsc = fc.isCurrentSortAsc(); String sortCss = (sortAsc ? "o_orderby_asc" : "o_orderby_desc"); @@ -222,15 +220,11 @@ public class ListRenderer { canWrite = canWrite && !(fc.getCurrentContainer() instanceof VirtualContainer); boolean isAbstract = (child instanceof AbstractVirtualContainer); - Versions versions = null; - if(canContainerVersion && child instanceof Versionable) { - Versionable versionable = (Versionable)child; - Versions possibleVersions = versionable.getVersions(); - if(possibleVersions.isVersioned()) { - versions = possibleVersions; - } + List<VFSRevision> revisions = null; + if(canContainerVersion && child.canVersion() == VFSConstants.YES) { + revisions = vfsRepositoryService.getRevisions(metadata); } - boolean canVersion = versions != null && !versions.getRevisions().isEmpty(); + boolean canVersion = revisions != null && !revisions.isEmpty(); VFSLeaf leaf = null; if (child instanceof VFSLeaf) { @@ -410,9 +404,9 @@ public class ListRenderer { } if(canContainerVersion) { - if (canVersion && versions != null) { + if (canVersion && revisions != null) { sb.append("<span class='text-muted small'>") - .append(versions.getRevisionNr()) + .append(metadata.getRevisionNr()) .append("</span>"); } sb.append("</td><td>"); diff --git a/src/main/java/org/olat/core/commons/modules/bc/version/DeletedFileListController.java b/src/main/java/org/olat/core/commons/modules/bc/version/DeletedFileListController.java deleted file mode 100644 index dd67832da5f51ccd4c95a634a7c310e67d335146..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/core/commons/modules/bc/version/DeletedFileListController.java +++ /dev/null @@ -1,339 +0,0 @@ -/** - * <a href="http://www.openolat.org"> - * OpenOLAT - Online Learning and Training</a><br> - * <p> - * Licensed under the Apache License, Version 2.0 (the "License"); <br> - * you may not use this file except in compliance with the License.<br> - * You may obtain a copy of the License at the - * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> - * <p> - * Unless required by applicable law or agreed to in writing,<br> - * software distributed under the License is distributed on an "AS IS" BASIS, <br> - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> - * See the License for the specific language governing permissions and <br> - * limitations under the License. - * <p> - * Initial code contributed and copyrighted by<br> - * frentix GmbH, http://www.frentix.com - * <p> - */ -package org.olat.core.commons.modules.bc.version; - -import java.text.DateFormat; -import java.util.ArrayList; -import java.util.BitSet; -import java.util.Calendar; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -import org.olat.basesecurity.BaseSecurityModule; -import org.olat.core.commons.modules.bc.commands.FolderCommand; -import org.olat.core.commons.modules.bc.commands.FolderCommandStatus; -import org.olat.core.gui.UserRequest; -import org.olat.core.gui.components.Component; -import org.olat.core.gui.components.table.BaseTableDataModelWithoutFilter; -import org.olat.core.gui.components.table.DefaultColumnDescriptor; -import org.olat.core.gui.components.table.StaticColumnDescriptor; -import org.olat.core.gui.components.table.TableController; -import org.olat.core.gui.components.table.TableDataModel; -import org.olat.core.gui.components.table.TableEvent; -import org.olat.core.gui.components.table.TableGuiConfiguration; -import org.olat.core.gui.components.table.TableMultiSelectEvent; -import org.olat.core.gui.components.velocity.VelocityContainer; -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.control.controller.BasicController; -import org.olat.core.gui.control.generic.modal.DialogBoxController; -import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory; -import org.olat.core.gui.media.MediaResource; -import org.olat.core.util.StringHelper; -import org.olat.core.util.vfs.VFSContainer; -import org.olat.core.util.vfs.VFSManager; -import org.olat.core.util.vfs.VFSRevisionMediaResource; -import org.olat.core.util.vfs.callbacks.VFSSecurityCallback; -import org.olat.core.util.vfs.version.VFSRevision; -import org.olat.core.util.vfs.version.Versions; -import org.olat.core.util.vfs.version.VersionsManager; -import org.olat.user.UserManager; -import org.springframework.beans.factory.annotation.Autowired; - -/** - * - * Description:<br> - * This controller shows the list of deleted files in a container.<br> - * Events: - * <ul> - * <li>FOLDERCOMMAND_FINISHED</li> - * </ul> - * <P> - * Initial Date: 15 sept. 2009 <br> - * - * @author srosse - */ -public class DeletedFileListController extends BasicController { - - private static final String CMD_DOWNLOAD = "download"; - private static final String CMD_RESTORE = "restore"; - private static final String CMD_DELETE = "delete"; - private static final String CMD_CANCEL = "cancel"; - - private int status = FolderCommandStatus.STATUS_SUCCESS; - - private final VFSContainer container; - private final List<Versions> deletedFiles; - - private VelocityContainer mainVC; - private TableController deletedFilesListTableCtr; - private DialogBoxController dialogCtr; - - private boolean isAdmin; - - @Autowired - private UserManager userManager; - @Autowired - private VersionsManager versionsManager; - @Autowired - private BaseSecurityModule securityModule; - - public DeletedFileListController(UserRequest ureq, WindowControl wControl, VFSContainer container) { - super(ureq, wControl); - this.container = container; - deletedFiles = versionsManager.getDeletedFiles(container); - - isAdmin = securityModule.isUserAllowedAdminProps(ureq.getUserSession().getRoles()); - - TableGuiConfiguration summaryTableConfig = new TableGuiConfiguration(); - summaryTableConfig.setDownloadOffered(false); - summaryTableConfig.setTableEmptyMessage(getTranslator().translate("version.noDeletedFiles")); - - deletedFilesListTableCtr = new TableController(summaryTableConfig, ureq, getWindowControl(), getTranslator()); - - deletedFilesListTableCtr.addColumnDescriptor(new DefaultColumnDescriptor("version.name", 0, null, ureq.getLocale())); - deletedFilesListTableCtr.addColumnDescriptor(new DefaultColumnDescriptor("version.author", 1, null, ureq.getLocale())); - deletedFilesListTableCtr.addColumnDescriptor(new DefaultColumnDescriptor("version.deletedBy", 2, null, ureq.getLocale())); - deletedFilesListTableCtr.addColumnDescriptor(new DefaultColumnDescriptor("version.date", 3, null, ureq.getLocale())); - deletedFilesListTableCtr.addColumnDescriptor(new StaticColumnDescriptor(CMD_DOWNLOAD, "version.download", getTranslator().translate( - "version.download"))); - - VFSSecurityCallback secCallback = VFSManager.findInheritedSecurityCallback(container); - if (secCallback != null) { - if (secCallback.canDeleteRevisionsPermanently()) { - deletedFilesListTableCtr.addMultiSelectAction("delete", CMD_DELETE); - } - if (secCallback.canWrite()) { - deletedFilesListTableCtr.addMultiSelectAction("version.restore", CMD_RESTORE); - } - } - - deletedFilesListTableCtr.addMultiSelectAction("cancel", CMD_CANCEL); - deletedFilesListTableCtr.setMultiSelect(true); - loadModel(ureq); - listenTo(deletedFilesListTableCtr); - - mainVC = createVelocityContainer("deleted_files"); - mainVC.put("deletedFileList", deletedFilesListTableCtr.getInitialComponent()); - putInitialPanel(mainVC); - } - - private void loadModel(UserRequest ureq) { - Collection<String> names = new HashSet<>(); - for(Versions deletedFile:deletedFiles) { - if(deletedFile.getCreator() != null && !"-".equals(deletedFile.getCreator())) { - names.add(deletedFile.getCreator()); - } - VFSRevision lastRevision = getLastRevision(deletedFile); - if(lastRevision != null && lastRevision.getAuthor() != null && !"-".equals(lastRevision.getAuthor())) { - names.add(lastRevision.getAuthor()); - } - } - - Map<String, String> mappedFullnames = userManager.getUserDisplayNamesByUserName(names); - DeletedFileListDataModel model = new DeletedFileListDataModel(deletedFiles, mappedFullnames, ureq.getLocale()); - deletedFilesListTableCtr.setTableDataModel(model); - } - - @Override - protected void doDispose() { - // - } - - public int getStatus() { - return status; - } - - @Override - protected void event(UserRequest ureq, Component source, Event event) { - // nothing to track - } - - @Override - protected void event(UserRequest ureq, Controller source, Event event) { - if (source == deletedFilesListTableCtr) { - if (event instanceof TableEvent) { - TableEvent tEvent = (TableEvent) event; - int row = tEvent.getRowId(); - if (CMD_DOWNLOAD.equals(tEvent.getActionId())) { - VFSRevision version = getLastRevision(deletedFiles.get(row)); - MediaResource resource = new VFSRevisionMediaResource(version, true); - ureq.getDispatchResult().setResultingMediaResource(resource); - } else if (CMD_RESTORE.equals(tEvent.getActionId())) { - VFSRevision version = getLastRevision(deletedFiles.get(row)); - if (versionsManager.restore(container, version)) { - status = FolderCommandStatus.STATUS_SUCCESS; - fireEvent(ureq, FolderCommand.FOLDERCOMMAND_FINISHED); - } else { - status = FolderCommandStatus.STATUS_FAILED; - // ERROR - } - } - } else if (event instanceof TableMultiSelectEvent) { - TableMultiSelectEvent tEvent = (TableMultiSelectEvent) event; - if (CMD_CANCEL.equals(tEvent.getAction())) { - status = FolderCommandStatus.STATUS_CANCELED; - fireEvent(ureq, FolderCommand.FOLDERCOMMAND_FINISHED); - } else if (CMD_RESTORE.equals(tEvent.getAction())) { - List<VFSRevision> selectedRevisions = getSelectedRevisions(tEvent.getSelection()); - boolean allOk = true; - for (VFSRevision revision : selectedRevisions) { - allOk &= versionsManager.restore(container, revision); - } - if (allOk) { - status = FolderCommandStatus.STATUS_SUCCESS; - fireEvent(ureq, FolderCommand.FOLDERCOMMAND_FINISHED); - } else { - status = FolderCommandStatus.STATUS_FAILED; - } - } else if (CMD_DELETE.equals(tEvent.getAction())) { - List<Versions> versionsToDelete = getSelectedVersions(tEvent.getSelection()); - if (!versionsToDelete.isEmpty()) { - - String msg = translate("version.del.confirm") + "<p>" + renderVersionsAsHtml(versionsToDelete) + "</p>"; - // create dialog controller - dialogCtr = activateYesNoDialog(ureq, translate("version.del.header"), msg, dialogCtr); - dialogCtr.setUserObject(versionsToDelete); - } - } - } - } else if (source == dialogCtr) { - if (DialogBoxUIFactory.isYesEvent(event)) { - @SuppressWarnings("unchecked") - List<Versions> versionsToDelete = (List<Versions>)dialogCtr.getUserObject(); - versionsManager.deleteVersions(container, versionsToDelete); - status = FolderCommandStatus.STATUS_SUCCESS; - fireEvent(ureq, FolderCommand.FOLDERCOMMAND_FINISHED); - } - } - } - - private String renderVersionsAsHtml(List<Versions> versions) { - StringBuilder sb = new StringBuilder(); - sb.append("<ul>"); - for (Versions version:versions) { - VFSRevision lastRevision = getLastRevision(version); - if (lastRevision != null) { - sb.append("<li>") - .append(lastRevision.getName()) - .append("</li>"); - } - } - sb.append("</ul>"); - return sb.toString(); - } - - protected List<Versions> getSelectedVersions(BitSet objectMarkers) { - List<Versions> results = new ArrayList<>(); - for (int i = objectMarkers.nextSetBit(0); i >= 0; i = objectMarkers.nextSetBit(i + 1)) { - if (i >= 0 && i < deletedFiles.size()) { - results.add(deletedFiles.get(i)); - } - } - return results; - } - - protected List<VFSRevision> getSelectedRevisions(BitSet objectMarkers) { - List<VFSRevision> results = new ArrayList<>(); - for (int i = objectMarkers.nextSetBit(0); i >= 0; i = objectMarkers.nextSetBit(i + 1)) { - if (i >= 0 && i < deletedFiles.size()) { - VFSRevision elem = getLastRevision(deletedFiles.get(i)); - if (elem != null) { - results.add(elem); - } - } - } - return results; - } - - protected VFSRevision getLastRevision(Versions versions) { - VFSRevision lastRevision = null; - if (!versions.getRevisions().isEmpty()) { - lastRevision = versions.getRevisions().get(versions.getRevisions().size() - 1); - } - return lastRevision; - } - - public class DeletedFileListDataModel extends BaseTableDataModelWithoutFilter<Versions> implements TableDataModel<Versions> { - private final DateFormat format; - private final List<Versions> versionList; - private final Calendar cal = Calendar.getInstance(); - private final Map<String, String> mappedFullnames; - - public DeletedFileListDataModel(List<Versions> versionList, Map<String, String> mappedFullnames, Locale locale) { - this.versionList = versionList; - this.mappedFullnames = mappedFullnames; - format = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale); - } - - public int getColumnCount() { - return 4; - } - - public int getRowCount() { - return versionList.size(); - } - - public Object getValueAt(int row, int col) { - Versions versioned = versionList.get(row); - switch (col) { - case 0: { - VFSRevision lastRevision = getLastRevision(versioned); - return lastRevision == null ? null : lastRevision.getName(); - } - case 1: - return getFullName(versioned.getCreator()); - case 2: { - VFSRevision lastRevision = getLastRevision(versioned); - return lastRevision == null ? null : getFullName(lastRevision.getAuthor()); - } - case 3: { - VFSRevision lastRevision = getLastRevision(versioned); - if (lastRevision == null) return null; - cal.setTimeInMillis(lastRevision.getLastModified()); - return format.format(cal.getTime()); - } - default: - return ""; - } - } - - private String getFullName(String name) { - if(!StringHelper.containsNonWhitespace(name)) { - return null; - } - String fullName = mappedFullnames.get(name); - if(fullName == null) { - return null; - } - - StringBuilder sb = new StringBuilder(); - sb.append(fullName); - if(isAdmin) { - sb.append(" (").append(name).append(")"); - } - return sb.toString(); - } - } -} diff --git a/src/main/java/org/olat/core/commons/modules/bc/version/RevisionListController.java b/src/main/java/org/olat/core/commons/modules/bc/version/RevisionListController.java deleted file mode 100644 index aca68052e2cd7f1d8c1666d2d0220f8482b72bf6..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/core/commons/modules/bc/version/RevisionListController.java +++ /dev/null @@ -1,407 +0,0 @@ -/** - * <a href="http://www.openolat.org"> - * OpenOLAT - Online Learning and Training</a><br> - * <p> - * Licensed under the Apache License, Version 2.0 (the "License"); <br> - * you may not use this file except in compliance with the License.<br> - * You may obtain a copy of the License at the - * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> - * <p> - * Unless required by applicable law or agreed to in writing,<br> - * software distributed under the License is distributed on an "AS IS" BASIS, <br> - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> - * See the License for the specific language governing permissions and <br> - * limitations under the License. - * <p> - * Initial code contributed and copyrighted by<br> - * frentix GmbH, http://www.frentix.com - * <p> - */ -package org.olat.core.commons.modules.bc.version; - -import java.io.InputStream; -import java.text.DateFormat; -import java.util.ArrayList; -import java.util.BitSet; -import java.util.Calendar; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -import org.olat.basesecurity.BaseSecurity; -import org.olat.basesecurity.BaseSecurityModule; -import org.olat.basesecurity.IdentityShort; -import org.olat.core.commons.modules.bc.commands.FolderCommand; -import org.olat.core.commons.modules.bc.commands.FolderCommandStatus; -import org.olat.core.gui.UserRequest; -import org.olat.core.gui.components.Component; -import org.olat.core.gui.components.table.BaseTableDataModelWithoutFilter; -import org.olat.core.gui.components.table.DefaultColumnDescriptor; -import org.olat.core.gui.components.table.StaticColumnDescriptor; -import org.olat.core.gui.components.table.TableController; -import org.olat.core.gui.components.table.TableDataModel; -import org.olat.core.gui.components.table.TableEvent; -import org.olat.core.gui.components.table.TableGuiConfiguration; -import org.olat.core.gui.components.table.TableMultiSelectEvent; -import org.olat.core.gui.components.velocity.VelocityContainer; -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.control.controller.BasicController; -import org.olat.core.gui.control.generic.modal.DialogBoxController; -import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory; -import org.olat.core.gui.media.MediaResource; -import org.olat.core.util.StringHelper; -import org.olat.core.util.vfs.VFSLeaf; -import org.olat.core.util.vfs.VFSMediaResource; -import org.olat.core.util.vfs.VFSRevisionMediaResource; -import org.olat.core.util.vfs.version.VFSRevision; -import org.olat.core.util.vfs.version.Versionable; -import org.olat.core.util.vfs.version.Versions; -import org.olat.user.UserManager; -import org.springframework.beans.factory.annotation.Autowired; - -/** - * - * Description:<br> - * This controller shows the list of revisions from a versioned file.<br> - * Events: - * <ul> - * <li>FOLDERCOMMAND_FINISHED</li> - * </ul> - * <P> - * Initial Date: 15 sept. 2009 <br> - * - * @author srosse - */ -public class RevisionListController extends BasicController { - - private static final String CMD_DOWNLOAD = "download"; - private static final String CMD_RESTORE = "restore"; - private static final String CMD_DELETE = "delete"; - private static final String CMD_CANCEL = "cancel"; - - private int status = FolderCommandStatus.STATUS_SUCCESS; - - private final Versionable versionedFile; - private TableController revisionListTableCtr; - private DialogBoxController confirmDeleteBoxCtr; - private final VelocityContainer mainVC; - private final boolean isAdmin; - - @Autowired - private UserManager userManager; - @Autowired - private BaseSecurity securityManager; - @Autowired - private BaseSecurityModule securityModule; - - public RevisionListController(UserRequest ureq, WindowControl wControl, Versionable versionedFile, boolean readOnly) { - this(ureq, wControl, versionedFile, null, null, readOnly); - } - - public RevisionListController(UserRequest ureq, WindowControl wControl, Versionable versionedFile, - String title, String description, boolean readOnly) { - super(ureq, wControl); - isAdmin = securityModule.isUserAllowedAdminProps(ureq.getUserSession().getRoles()); - - //reload the file with all possible precautions - VFSLeaf versionedLeaf = null; - if(versionedFile instanceof VFSLeaf) { - versionedLeaf = (VFSLeaf)versionedFile; - } - if(versionedLeaf != null && versionedLeaf.getParentContainer() != null) { - //reload the file - versionedLeaf = (VFSLeaf)versionedLeaf.getParentContainer().resolve(((VFSLeaf) versionedFile).getName()); - if(versionedLeaf instanceof Versionable) { - versionedFile = (Versionable)versionedLeaf; - } - } - this.versionedFile = versionedFile; - - TableGuiConfiguration summaryTableConfig = new TableGuiConfiguration(); - summaryTableConfig.setDownloadOffered(true); - summaryTableConfig.setTableEmptyMessage(getTranslator().translate("version.noRevisions")); - - revisionListTableCtr = new TableController(summaryTableConfig, ureq, getWindowControl(), getTranslator()); - revisionListTableCtr.addColumnDescriptor(new DefaultColumnDescriptor("version.nr", 0, null, ureq.getLocale()) { - @Override - public int compareTo(int rowa, int rowb) { - Object a = table.getTableDataModel().getValueAt(rowa, dataColumn); - Object b = table.getTableDataModel().getValueAt(rowb, dataColumn); - if (a == null || b == null) { - boolean bb = (b == null); - return (a == null) ? (bb ? 0: -1) : (bb ? 1: 0); - } - try { - Long la = new Long((String)a); - Long lb = new Long((String)b); - return la.compareTo(lb); - } catch (NumberFormatException e) { - return super.compareTo(rowa, rowb); - } - } - }); - revisionListTableCtr.addColumnDescriptor(new DefaultColumnDescriptor("version.author", 1, null, ureq.getLocale())); - revisionListTableCtr.addColumnDescriptor(new DefaultColumnDescriptor("version.comment", 2, null, ureq.getLocale())); - revisionListTableCtr.addColumnDescriptor(new DefaultColumnDescriptor("version.date", 3, null, ureq.getLocale())); - revisionListTableCtr.addColumnDescriptor(new StaticColumnDescriptor(CMD_DOWNLOAD, "version.download", getTranslator().translate( - "version.download"))); - //read only cannot restore / delete - if(!readOnly) { - revisionListTableCtr.addColumnDescriptor(new StaticColumnDescriptor(CMD_RESTORE, "version.restore", getTranslator().translate( - "version.restore"))); - revisionListTableCtr.addMultiSelectAction("delete", CMD_DELETE); - } - - revisionListTableCtr.addMultiSelectAction("cancel", CMD_CANCEL); - revisionListTableCtr.setMultiSelect(true); - loadModel(versionedLeaf); - listenTo(revisionListTableCtr); - - mainVC = createVelocityContainer("revisions"); - mainVC.put("revisionList", revisionListTableCtr.getInitialComponent()); - - if (StringHelper.containsNonWhitespace(title)) { - mainVC.contextPut("title", title); - } - if (StringHelper.containsNonWhitespace(description)) { - mainVC.contextPut("description", description); - } - - putInitialPanel(mainVC); - } - - private void loadModel(VFSLeaf versionedLeaf) { - Versions versions = versionedFile.getVersions(); - List<VFSRevision> revisions = new ArrayList<>(versions.getRevisions()); - revisions.add(new CurrentRevision(versionedLeaf, versions)); - - Collection<String> names = new HashSet<>(); - for(VFSRevision revision:revisions) { - if(revision.getAuthor() != null) { - names.add(revision.getAuthor()); - } - } - - Map<String, IdentityShort> mappedIdentities = new HashMap<>(); - for(IdentityShort identity :securityManager.findShortIdentitiesByName(names)) { - mappedIdentities.put(identity.getName(), identity); - } - - revisionListTableCtr.setTableDataModel(new RevisionListDataModel(revisions, mappedIdentities, getLocale())); - } - - @Override - protected void doDispose() { - // disposed by BasicController - } - - public int getStatus() { - return status; - } - - @Override - protected void event(UserRequest ureq, Component source, Event event) { - // nothing to track - } - - @Override - protected void event(UserRequest ureq, Controller source, Event event) { - if (source == revisionListTableCtr) { - if (event instanceof TableEvent) { - TableEvent tEvent = (TableEvent) event; - int row = tEvent.getRowId(); - if (CMD_DOWNLOAD.equals(tEvent.getActionId())) { - - MediaResource resource; - if(row < versionedFile.getVersions().getRevisions().size()) { - //restore current, do nothing - VFSRevision version = versionedFile.getVersions().getRevisions().get(row); - resource = new VFSRevisionMediaResource(version, true); - } else { - resource = new VFSMediaResource((VFSLeaf)versionedFile); - ((VFSMediaResource)resource).setDownloadable(true); - } - ureq.getDispatchResult().setResultingMediaResource(resource); - } else if (CMD_RESTORE.equals(tEvent.getActionId())) { - if(row >= versionedFile.getVersions().getRevisions().size()) { - //restore current, do nothing - status = FolderCommandStatus.STATUS_SUCCESS; - fireEvent(ureq, FolderCommand.FOLDERCOMMAND_FINISHED); - } else { - VFSRevision version = versionedFile.getVersions().getRevisions().get(row); - String comment = translate("version.restore.comment", new String[]{version.getRevisionNr()}); - if (versionedFile.getVersions().restore(ureq.getIdentity(), version, comment)) { - status = FolderCommandStatus.STATUS_SUCCESS; - fireEvent(ureq, FolderCommand.FOLDERCOMMAND_FINISHED); - } else { - status = FolderCommandStatus.STATUS_FAILED; - showError("version.restore.failed"); - fireEvent(ureq, FolderCommand.FOLDERCOMMAND_FINISHED); - } - } - } - } else if (event instanceof TableMultiSelectEvent) { - TableMultiSelectEvent tEvent = (TableMultiSelectEvent) event; - if (CMD_CANCEL.equals(tEvent.getAction())) { - status = FolderCommandStatus.STATUS_CANCELED; - fireEvent(ureq, FolderCommand.FOLDERCOMMAND_FINISHED); - } else { - List<VFSRevision> selectedVersions = getSelectedRevisions(tEvent.getSelection()); - if (!selectedVersions.isEmpty()) { - if (CMD_DELETE.equals(tEvent.getAction())) { - String numOfVersionToDelete = Integer.toString(selectedVersions.size()); - confirmDeleteBoxCtr = activateYesNoDialog(ureq, null, translate("version.confirmDelete", - new String[] { numOfVersionToDelete }), confirmDeleteBoxCtr); - confirmDeleteBoxCtr.setUserObject(selectedVersions); - } - } - } - } - } else if (source == confirmDeleteBoxCtr) { - if (DialogBoxUIFactory.isYesEvent(event)) { - @SuppressWarnings("unchecked") - List<VFSRevision> selectedVersions = (List<VFSRevision>) confirmDeleteBoxCtr.getUserObject(); - versionedFile.getVersions().delete(ureq.getIdentity(), selectedVersions); - status = FolderCommandStatus.STATUS_SUCCESS; - } else { - status = FolderCommandStatus.STATUS_CANCELED; - } - fireEvent(ureq, FolderCommand.FOLDERCOMMAND_FINISHED); - } - } - - private List<VFSRevision> getSelectedRevisions(BitSet objectMarkers) { - List<VFSRevision> allVersions = versionedFile.getVersions().getRevisions(); - - List<VFSRevision> results = new ArrayList<>(); - for (int i = objectMarkers.nextSetBit(0); i >= 0; i = objectMarkers.nextSetBit(i + 1)) { - if (i >= 0 && i < allVersions.size()) { - VFSRevision elem = allVersions.get(i); - results.add(elem); - } - } - - return results; - } - - public class RevisionListDataModel extends BaseTableDataModelWithoutFilter<VFSRevision> implements TableDataModel<VFSRevision> { - private final DateFormat format; - private final List<VFSRevision> versionList; - private final Calendar cal = Calendar.getInstance(); - private final Map<String, IdentityShort> mappedIdentities; - - public RevisionListDataModel(List<VFSRevision> versionList, Map<String, IdentityShort> mappedIdentities, Locale locale) { - this.versionList = versionList; - this.mappedIdentities = mappedIdentities; - format = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale); - } - - @Override - public int getColumnCount() { - return 4; - } - - @Override - public int getRowCount() { - return versionList.size(); - } - - @Override - public Object getValueAt(int row, int col) { - VFSRevision version = versionList.get(row); - switch (col) { - case 0: - return version.getRevisionNr(); - case 1: - return getFullName(version.getAuthor()); - case 2: { - String comment = version.getComment(); - if (StringHelper.containsNonWhitespace(comment)) { - return comment; - } else if ("1".equals(version.getRevisionNr())) { - return translate("version.initialRevision"); - } - return ""; - } - case 3: - cal.setTimeInMillis(version.getLastModified()); - return format.format(cal.getTime()); - default: - return ""; - } - } - - private String getFullName(String name) { - if(!StringHelper.containsNonWhitespace(name)) { - return null; - } - IdentityShort id = mappedIdentities.get(name); - if(id == null) { - return null; - } - - StringBuilder sb = new StringBuilder(); - sb.append(userManager.getUserDisplayName(id)); - if(isAdmin) { - sb.append(" (").append(name).append(")"); - } - return sb.toString(); - } - } - - public class CurrentRevision implements VFSRevision { - private final VFSLeaf versionFile; - private final Versions versions; - - public CurrentRevision(VFSLeaf versionFile, Versions versions) { - this.versionFile = versionFile; - this.versions = versions; - } - - @Override - public String getAuthor() { - return versions.getAuthor(); - } - - @Override - public String getComment() { - String comment = versions.getComment(); - if (StringHelper.containsNonWhitespace(comment)) { - return comment; - } else if ("1".equals(versions.getRevisionNr())) { - return translate("version.initialRevision"); - } - return ""; - } - - @Override - public InputStream getInputStream() { - return versionFile.getInputStream(); - } - - @Override - public long getLastModified() { - return versionFile.getLastModified(); - } - - @Override - public String getName() { - return versionFile.getName(); - } - - @Override - public String getRevisionNr() { - return versions.getRevisionNr(); - } - - @Override - public long getSize() { - return versionFile.getSize(); - } - } -} \ No newline at end of file diff --git a/src/main/java/org/olat/core/commons/modules/bc/version/_content/deleted_files.html b/src/main/java/org/olat/core/commons/modules/bc/version/_content/deleted_files.html deleted file mode 100644 index bd3427a4b59ce5aeba63d79167e4ad1431506500..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/core/commons/modules/bc/version/_content/deleted_files.html +++ /dev/null @@ -1 +0,0 @@ -$r.render("deletedFileList") \ No newline at end of file diff --git a/src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_de.properties deleted file mode 100644 index 47fe5f593a8e7b51d4db733e5ef1ad26a8baeb76..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_de.properties +++ /dev/null @@ -1,25 +0,0 @@ -version.author=Autor -version.comment=Kommentar -version.date=Datum -version.deletedBy=Gel\u00F6scht von -version.deletedFiles=Gel\u00F6schte Dateien -version.download=Herunterladen -version.name=Datei -version.noDeletedFiles=Es gibt keine gel\u00F6schten Dateien unter der Dokument-Kontrolle. -version.noRevisions=Es gibt noch keine Revision dieser Datei. -version.nr=Revision -version.initialRevision=Initiale Version -version.restore=Wiederherstellen -version.confirmDelete=Wollen Sie wirklich {0} Revision(en) l\u00F6schen? -version.comment=Kommentar -version.comment.title=Kommentar -version.comment.alltitle=Kommentar / Sperre -version.comment.description=Dieses Dokument steht unter Dokument-Kontrolle. Bitte kommentieren Sie die gemachten \u00c4nderungen. -version.del.confirm=Wollen Sie folgende Dateien wirklich endg\u00FCltig l\u00F6schen? -version.del.header=L\u00F6schen best\u00E4tigen -version.restore.failed=Datei konnte nicht wiederhergestellt werden. -version.restore.comment=Version {0} wiederhergestellt -meta.comment.title=Sperre -meta.locked=Dateisperre -meta.retainlock=Die Datei f\u00FCr andere Benutzer gesperrt lassen -meta.unlock=Die Datei f\u00FCr andere Benutzer frei geben \ No newline at end of file diff --git a/src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_en.properties deleted file mode 100644 index 51521130c650860e13e81cec4b22416eff25a520..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_en.properties +++ /dev/null @@ -1,25 +0,0 @@ -#Mon Jan 25 15:05:06 CET 2010 -meta.comment.title=Lock -meta.locked=File locked -meta.retainlock=Continue locking of file for other users -meta.unlock=Unlock file for other users -version.author=Author -version.comment=Comment -version.comment.alltitle=Comment/lock -version.comment.description=Changes are tracked in this document. Please comment your modifications. -version.comment.title=Comment -version.confirmDelete=Do you really want to delete {0} revision(s)? -version.date=Date -version.del.confirm=Do you really want to delete the following files for good? -version.del.header=Confirm deletion -version.deletedBy=Deleted by -version.deletedFiles=Deleted files -version.download=Download -version.initialRevision=Initial version -version.name=File -version.noDeletedFiles=There are no deleted files with a change log. -version.noRevisions=There are no revisions of this file yet. -version.nr=Revision -version.restore=Restore -version.restore.comment=Version {0} restored -version.restore.failed=File could not be restored. diff --git a/src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_it.properties b/src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_it.properties deleted file mode 100644 index 690c93d8280e977742f206566b92486f7ef7b5a4..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_it.properties +++ /dev/null @@ -1,25 +0,0 @@ -#Sun Mar 14 12:57:54 CET 2010 -meta.comment.title=Bloccaggio -meta.locked=Bloccaggio file -meta.retainlock=Mantenere bloccato il file per altri utenti -meta.unlock=Sbloccare il file per altri utenti -version.author=Autore -version.comment=Commento -version.comment.alltitle=Commento / Bloccaggio -version.comment.description=Le modifiche a questo documento vengono registrate. Commenti le Sue modifiche, p.f. -version.comment.title=Commento -version.confirmDelete=Desidera veramente eliminare {0} revisione/i? -version.date=Data -version.del.confirm=Desidera veramente eliminare definitivamente questi file? -version.del.header=Confermare eliminazione -version.deletedBy=Eliminato da -version.deletedFiles=File eliminati -version.download=Scaricare -version.initialRevision=Versione iniziale -version.name=File -version.noDeletedFiles=Non ci sono file eliminati che avevano modifiche registrate. -version.noRevisions=Non ci sono ancora revisioni di questo file. -version.nr=Revisione -version.restore=Recuperare -version.restore.comment=Versione {0} recuperata -version.restore.failed=Il file non pu\u00F2 essere recuperato. diff --git a/src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_pt_BR.properties deleted file mode 100644 index c7e5bfd6c50b216a873f24e3ffcd6a91ab084a91..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_pt_BR.properties +++ /dev/null @@ -1,25 +0,0 @@ -#Sat Mar 20 15:19:50 CET 2010 -meta.comment.title=Bloquear -meta.locked=Arquivo bloqueado -meta.retainlock=Continue bloqueio de arquivo para outros usu\u00E1rios -meta.unlock=Desbloquear arquivo para outros usu\u00E1rios -version.author=Autor -version.comment=Coment\u00E1rio -version.comment.alltitle=Comentar/Bloquear -version.comment.description=As altera\u00E7\u00F5es s\u00E3o controladas neste documento. Por favor, comente suas modifica\u00E7\u00F5es. -version.comment.title=Comente -version.confirmDelete=Voc\u00EA realmente quer apagar {0} revis\u00E3o(\u00F5es)? -version.date=Data -version.del.confirm=Voc\u00EA realmente quer excluir os seguintes arquivos? -version.del.header=Confirme exclus\u00E3o -version.deletedBy=Exclu\u00EDdo por -version.deletedFiles=Arquivos exclu\u00EDdos -version.download=Baixar -version.initialRevision=Vers\u00E3o inicial -version.name=Arquivo -version.noDeletedFiles=N\u00E3o existem arquivos exclu\u00EDdos com um registo de altera\u00E7\u00F5es. -version.noRevisions=N\u00E3o h\u00E1 revis\u00F5es deste arquivo ainda. -version.nr=Revis\u00E3o -version.restore=Restaurar -version.restore.comment=Vers\u00E3o {0} restaurada -version.restore.failed=Arquivo n\u00E3o p\u00F4de ser restaurado. diff --git a/src/main/java/org/olat/core/commons/services/_spring/servicesCorecontext.xml b/src/main/java/org/olat/core/commons/services/_spring/servicesCorecontext.xml index e05ab2a6958644d3dcace37049164e65b49b35cb..60ec9aecc3c931e378f6a209ba86389b719ca28b 100644 --- a/src/main/java/org/olat/core/commons/services/_spring/servicesCorecontext.xml +++ b/src/main/java/org/olat/core/commons/services/_spring/servicesCorecontext.xml @@ -78,6 +78,26 @@ </property> </bean> + <!-- The version configuration --> + <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints" > + <property name="order" value="7204" /> + <property name="navigationKey" value="versioning" /> + <property name="actionController"> + <bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype"> + <property name="className" value="org.olat.core.commons.services.vfs.ui.version.VersionAdminController"/> + </bean> + </property> + <property name="translationPackage" value="org.olat.admin" /> + <property name="i18nActionKey" value="menu.versions"/> + <property name="i18nDescriptionKey" value="menu.versions.alt"/> + <property name="parentTreeNodeIdentifier" value="sysconfigParent" /> + <property name="extensionPoints"> + <list> + <value>org.olat.admin.SystemAdminMainController</value> + </list> + </property> + </bean> + <!-- Pdf service --> <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> <property name="order" value="8280" /> diff --git a/src/main/java/org/olat/core/commons/services/vfs/VFSMetadata.java b/src/main/java/org/olat/core/commons/services/vfs/VFSMetadata.java index d778f06ba3b71b003c0ec9fe01b999bfbf064263..601cc1d6c8409a62ddc25b07d492b577cfab316d 100644 --- a/src/main/java/org/olat/core/commons/services/vfs/VFSMetadata.java +++ b/src/main/java/org/olat/core/commons/services/vfs/VFSMetadata.java @@ -34,12 +34,23 @@ import org.olat.core.id.ModifiedInfo; */ public interface VFSMetadata extends VFSMetadataRef, ModifiedInfo, CreateInfo { + public boolean isDeleted(); + public String getUuid(); public void setUuid(String id); + /** + * The relative path in bcroot doesn't start with /. / is reserved + * for the bcroot directory itself. + * + * @return The relative path of the file without the filename + */ public String getRelativePath(); + /** + * @return The name of the file + */ public String getFilename(); public Date getFileLastModified(); @@ -52,6 +63,13 @@ public interface VFSMetadata extends VFSMetadataRef, ModifiedInfo, CreateInfo { public String getUri(); + /** + * Return the protocol used to save and retrive the file. + * "file" ist for the standard operations done by OpenOLAT + * VFS implementation. + * + * @return the procotole + */ public String getProtocol(); public Identity getAuthor(); @@ -67,6 +85,7 @@ public interface VFSMetadata extends VFSMetadataRef, ModifiedInfo, CreateInfo { public void setComment(String text); public int getDownloadCount(); + public String getCreator(); @@ -83,8 +102,7 @@ public interface VFSMetadata extends VFSMetadataRef, ModifiedInfo, CreateInfo { public String[] getPublicationDate(); public void setPublicationDate(String month, String year); - - + public String getUrl(); public void setUrl(String url); @@ -101,9 +119,14 @@ public interface VFSMetadata extends VFSMetadataRef, ModifiedInfo, CreateInfo { public void setPages(String pages); - + /** + * @return true if the thumbnails cannot be generated for this file. + */ public Boolean getCannotGenerateThumbnails(); + /** + * @param val true if the thumbnails cannot be generated for this file. + */ public void setCannotGenerateThumbnails(Boolean val); @@ -122,12 +145,17 @@ public interface VFSMetadata extends VFSMetadataRef, ModifiedInfo, CreateInfo { public String getLicensor(); public void setLicensor(String licensor); - - + + /** + * @return true if the file is locked (VFS). + */ public boolean isLocked(); public void setLocked(boolean locked); + /** + * @return The person who locked the file or null + */ public Identity getLockedBy(); public void setLockedBy(Identity lockedBy); @@ -136,6 +164,16 @@ public interface VFSMetadata extends VFSMetadataRef, ModifiedInfo, CreateInfo { public void setLockedDate(Date date); + + public int getRevisionNr(); + + public void setRevisionNr(int nr); + + public String getRevisionComment(); + + public void setRevisionComment(String text); + + public void copyValues(VFSMetadata metadata); } diff --git a/src/main/java/org/olat/core/commons/services/vfs/VFSRepositoryModule.java b/src/main/java/org/olat/core/commons/services/vfs/VFSRepositoryModule.java index 0e0a4874efd5fb35b60a0619a0eb56c279510178..49d5c501f2e1b3a98d272f0713c8f2530a855bff 100644 --- a/src/main/java/org/olat/core/commons/services/vfs/VFSRepositoryModule.java +++ b/src/main/java/org/olat/core/commons/services/vfs/VFSRepositoryModule.java @@ -34,6 +34,23 @@ import org.olat.core.util.vfs.VFSStatus; */ public class VFSRepositoryModule { + public static final VFSStatus canVersion(File file) { + VFSStatus canMeta = canMeta(file); + if(canMeta == VFSConstants.YES) { + // version only works with metadata but not in: portfolio, scorm, forum... + Path bFile = file.toPath(); + Path bcRoot = FolderConfig.getCanonicalRootPath(); + return !bFile.startsWith(bcRoot.resolve("forum")) + && !bFile.startsWith(bcRoot.resolve("portfolio")) + && !bFile.startsWith(bcRoot.resolve("scorm")) + && !bFile.startsWith(bcRoot.resolve("certificates")) + && !bFile.startsWith(bcRoot.resolve("qtiassessment")) + && !bFile.startsWith(bcRoot.resolve("transcodedVideos")) + ? VFSConstants.YES : VFSConstants.NO; + } + return canMeta; + } + public static final VFSStatus canMeta(File file) { Path bFile = file.toPath(); Path bcRoot = FolderConfig.getCanonicalRootPath(); @@ -42,8 +59,10 @@ public class VFSRepositoryModule { && !bFile.startsWith(FolderConfig.getCanonicalMetaRootPath()) && !bFile.startsWith(FolderConfig.getCanonicalVersionRootPath()) && !bFile.startsWith(FolderConfig.getCanonicalTmpPath()) + && !bFile.startsWith(bcRoot.resolve("bulkassessment")) && !file.isHidden() && !filename.startsWith("._oo_") + && !filename.equals("CourseConfig.xml") ? VFSConstants.YES : VFSConstants.NO; } diff --git a/src/main/java/org/olat/core/commons/services/vfs/VFSRepositoryService.java b/src/main/java/org/olat/core/commons/services/vfs/VFSRepositoryService.java index e8371ba910ef2a3ed10bb16aded6ec3b6c01366c..9cf80aab6b33203b83169acbacdaedf1e812f0c4 100644 --- a/src/main/java/org/olat/core/commons/services/vfs/VFSRepositoryService.java +++ b/src/main/java/org/olat/core/commons/services/vfs/VFSRepositoryService.java @@ -20,6 +20,7 @@ package org.olat.core.commons.services.vfs; import java.io.File; +import java.io.InputStream; import java.util.List; import java.util.Optional; @@ -67,6 +68,9 @@ public interface VFSRepositoryService { public VFSMetadata updateMetadata(VFSMetadata data); + + public void markAsDeleted(VFSItem item, Identity author); + public void deleteMetadata(VFSMetadata data); public void deleteMetadata(File file); @@ -80,7 +84,14 @@ public interface VFSRepositoryService { */ public void copyTo(VFSLeaf source, VFSLeaf target, VFSContainer parentTarget); - public VFSMetadata rename(VFSMetadata data, String newName); + /** + * This rename the metadata and the versions but not the file itself. + * + * @param item The item which is renamed. + * @param newName + * @return + */ + public VFSMetadata rename(VFSItem item, String newName); public void increaseDownloadCount(VFSItem item); @@ -129,6 +140,50 @@ public interface VFSRepositoryService { */ public void resetThumbnails(File file); + /** + * Get the list of revisions for a specific file. + * + * @param metadata The metadata object of the file. + * @return A list of revisions if the file is versioned. + */ + public List<VFSRevision> getRevisions(VFSMetadataRef metadata); + + public List<VFSRevision> getRevisions(List<VFSMetadataRef> metadatas); + + + public boolean addVersion(VFSLeaf currentFile, Identity identity, String comment, InputStream newFile); + + /** + * Restore the specified revision and replace the current file. If the + * current file doesn't exist, it will recreate it. + * + * @param identity The identity who make the operation + * @param revision The revision to restore + * @param comment A comment + * @return true if successful + */ + public boolean restoreRevision(Identity identity, VFSRevision revision, String comment); + + /** + * Delete definitively the revisions of a file. + * + * @param identity The identity who makes the operation + * @param revisions The revisions to delete + * @return true if ssuccessful + */ + public boolean deleteRevisions(Identity identity, List<VFSRevision> revisions); + + /** + * Move the metadata and revisions from a path to the other. + * + * @param currentFile The current file + * @param targetFile The target file where to move the metadata + * @param author The user which moved the data + * @return The merged metadata + */ + public VFSMetadata move(VFSLeaf currentFile, VFSLeaf targetFile, Identity author); + + public File getRevisionFile(VFSRevision revision); public License getLicense(VFSMetadata meta); diff --git a/src/main/java/org/olat/core/util/vfs/version/VFSRevision.java b/src/main/java/org/olat/core/commons/services/vfs/VFSRevision.java similarity index 81% rename from src/main/java/org/olat/core/util/vfs/version/VFSRevision.java rename to src/main/java/org/olat/core/commons/services/vfs/VFSRevision.java index 3cdfe67801cd2ab84af15ff554875299d626cae9..fa9866e6ed4fe6d6c0ca2942c588013641080f87 100644 --- a/src/main/java/org/olat/core/util/vfs/version/VFSRevision.java +++ b/src/main/java/org/olat/core/commons/services/vfs/VFSRevision.java @@ -17,9 +17,11 @@ * frentix GmbH, http://www.frentix.com * <p> */ -package org.olat.core.util.vfs.version; +package org.olat.core.commons.services.vfs; -import java.io.InputStream; +import java.util.Date; + +import org.olat.core.id.Identity; /** * @@ -36,22 +38,25 @@ public interface VFSRevision { /** * @return author of the revision */ - public String getAuthor(); + public Identity getAuthor(); /** * @return timestamp of the creation of this revision */ - public long getLastModified(); + public Date getFileLastModified(); /** * @return the revision number */ - public String getRevisionNr(); + public int getRevisionNr(); + + + public Date getCreationDate(); /** * @return comment */ - public String getComment(); + public String getRevisionComment(); /** * @return name of the file @@ -62,9 +67,7 @@ public interface VFSRevision { * @return size of the file */ public long getSize(); + + public VFSMetadata getMetadata(); - /** - * @return InputStream of the file - */ - public InputStream getInputStream(); } diff --git a/src/main/java/org/olat/core/commons/services/vfs/VFSVersionModule.java b/src/main/java/org/olat/core/commons/services/vfs/VFSVersionModule.java new file mode 100644 index 0000000000000000000000000000000000000000..7e0f1c5d503f96a28ee61f040b2468b610b8729b --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/vfs/VFSVersionModule.java @@ -0,0 +1,84 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.vfs; + +import org.olat.core.configuration.AbstractSpringModule; +import org.olat.core.configuration.ConfigOnOff; +import org.olat.core.util.StringHelper; +import org.olat.core.util.coordinate.CoordinatorManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +/** + * + * Description:<br> + * A very simple configuration bean for versioning. There is a default value for + * the maximum allowed number of revisions, this number can be overridden by an + * second value saved in the persisted properties. + * + * <P> + * Initial Date: 21 sept. 2009 <br> + * + * @author srosse, stephane.rosse@frentix.com, https://www.frentix.com + */ +@Service +public class VFSVersionModule extends AbstractSpringModule implements ConfigOnOff { + + private static final String MAX_NUMBER_OF_VERSIONS = "maxnumber.versions"; + + @Value("${maxnumber.versions:0}") + private int maxNumberOfVersions; + + @Autowired + public VFSVersionModule(CoordinatorManager coordinatorManager) { + super(coordinatorManager, "org.olat.core.util.vfs.version.SimpleVersionConfig", false); + } + + @Override + public boolean isEnabled() { + return maxNumberOfVersions > 0; + } + + @Override + public void init() { + String maxNumberOfVersionsObj = getStringPropertyValue(MAX_NUMBER_OF_VERSIONS, true); + if(StringHelper.containsNonWhitespace(maxNumberOfVersionsObj)) { + maxNumberOfVersions = Integer.parseInt(maxNumberOfVersionsObj); + } + } + + @Override + protected void initFromChangedProperties() { + init(); + } + + /** + * @return maximum number of revisions, defined in admin. of Olat + */ + public int getMaxNumberOfVersions() { + return maxNumberOfVersions; + } + + public void setMaxNumberOfVersions(int maxNumber) { + this.maxNumberOfVersions = maxNumber; + setStringProperty(MAX_NUMBER_OF_VERSIONS, Integer.toString(maxNumber), true); + } +} diff --git a/src/main/java/org/olat/core/commons/services/vfs/manager/VFSMetadataDAO.java b/src/main/java/org/olat/core/commons/services/vfs/manager/VFSMetadataDAO.java index 9ccc9c451fe511e8271fb401cafc6b0a2a302924..77037b70581787fdd8ddacf90966da84266f543f 100644 --- a/src/main/java/org/olat/core/commons/services/vfs/manager/VFSMetadataDAO.java +++ b/src/main/java/org/olat/core/commons/services/vfs/manager/VFSMetadataDAO.java @@ -209,13 +209,14 @@ public class VFSMetadataDAO { .executeUpdate(); } - public void updateMetadata(long fileSize, String relativePath, String filename) { - String updateQuery = "update vfsmetadatafilesaved set fileLastModified=now(), fileSize=:fileSize where filename=:filename and relativePath=:relativePath"; + public void updateMetadata(long fileSize, Date lastModified, String relativePath, String filename) { + String updateQuery = "update vfsmetadatafilesaved set fileLastModified=:lastModified, fileSize=:fileSize where filename=:filename and relativePath=:relativePath"; dbInstance.getCurrentEntityManager() .createQuery(updateQuery) .setParameter("filename", filename) .setParameter("relativePath", relativePath) .setParameter("fileSize", fileSize) + .setParameter("lastModified", lastModified) .executeUpdate(); } diff --git a/src/main/java/org/olat/core/commons/services/vfs/manager/VFSRepositoryServiceImpl.java b/src/main/java/org/olat/core/commons/services/vfs/manager/VFSRepositoryServiceImpl.java index d891217bf7ef0a254b9f67d73a6d9c25cff834ca..2c884c3a1ac5b2e86b6152d53da3c911c5c69c96 100644 --- a/src/main/java/org/olat/core/commons/services/vfs/manager/VFSRepositoryServiceImpl.java +++ b/src/main/java/org/olat/core/commons/services/vfs/manager/VFSRepositoryServiceImpl.java @@ -21,6 +21,7 @@ package org.olat.core.commons.services.vfs.manager; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; @@ -29,14 +30,20 @@ import java.nio.file.SimpleFileVisitor; import java.nio.file.StandardCopyOption; import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; +import java.util.Collections; import java.util.Date; import java.util.Deque; +import java.util.HashMap; +import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; +import java.util.zip.Adler32; +import java.util.zip.Checksum; import org.olat.basesecurity.BaseSecurity; import org.olat.core.commons.modules.bc.FolderConfig; @@ -55,9 +62,12 @@ import org.olat.core.commons.services.vfs.VFSLeafEditor; import org.olat.core.commons.services.vfs.VFSMetadata; import org.olat.core.commons.services.vfs.VFSMetadataRef; import org.olat.core.commons.services.vfs.VFSRepositoryService; +import org.olat.core.commons.services.vfs.VFSRevision; import org.olat.core.commons.services.vfs.VFSThumbnailMetadata; +import org.olat.core.commons.services.vfs.VFSVersionModule; import org.olat.core.commons.services.vfs.manager.MetaInfoReader.Thumbnail; import org.olat.core.commons.services.vfs.model.VFSMetadataImpl; +import org.olat.core.commons.services.vfs.model.VFSRevisionImpl; import org.olat.core.gui.control.Event; import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; @@ -67,6 +77,7 @@ import org.olat.core.util.FileUtils; import org.olat.core.util.StringHelper; import org.olat.core.util.coordinate.CoordinatorManager; import org.olat.core.util.event.GenericEventListener; +import org.olat.core.util.io.ShieldInputStream; import org.olat.core.util.resource.OresHelper; import org.olat.core.util.vfs.LocalFileImpl; import org.olat.core.util.vfs.LocalFolderImpl; @@ -75,6 +86,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.VFSManager; +import org.olat.core.util.vfs.version.RevisionFileImpl; +import org.olat.core.util.vfs.version.VersionsFileImpl; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -99,12 +112,16 @@ public class VFSRepositoryServiceImpl implements VFSRepositoryService, GenericEv @Autowired private FolderModule folderModule; @Autowired + private VFSRevisionDAO revisionDao; + @Autowired private VFSMetadataDAO metadataDao; @Autowired private VFSThumbnailDAO thumbnailDao; @Autowired private LicenseService licenseService; @Autowired + private VFSVersionModule versionModule; + @Autowired private FolderLicenseHandler licenseHandler; @Autowired private ThumbnailService thumbnailService; @@ -131,7 +148,8 @@ public class VFSRepositoryServiceImpl implements VFSRepositoryService, GenericEv File file = toFile(event.getRelativePath(), event.getFilename()); if(file.exists()) { try { - metadataDao.updateMetadata(file.length(), event.getRelativePath(), event.getFilename()); + Date lastModified = new Date(file.lastModified()); + metadataDao.updateMetadata(file.length(), lastModified, event.getRelativePath(), event.getFilename()); dbInstance.commit(); } catch (Exception e) { log.error("Cannot update file size of: " + event.getRelativePath() + " " + event.getFilename(), e); @@ -169,6 +187,7 @@ public class VFSRepositoryServiceImpl implements VFSRepositoryService, GenericEv AsyncFileSizeUpdateEvent event = new AsyncFileSizeUpdateEvent(relativePath, filename); coordinatorManager.getCoordinator().getEventBus().fireEventToListenersOf(event, fileSizeSubscription); } + dbInstance.commit(); return metadata; } @@ -211,7 +230,8 @@ public class VFSRepositoryServiceImpl implements VFSRepositoryService, GenericEv String filename = file.getName(); VFSMetadata metadata = metadataDao.getMetadata(relativePath, filename, file.isDirectory()); - if(metadata != null && !metadata.isDirectory() && metadata.getFileSize() != file.length()) { + if(metadata != null && !metadata.isDirectory() + && (metadata.getFileSize() != file.length() || file.lastModified() != metadata.getFileLastModified().getTime())) { AsyncFileSizeUpdateEvent event = new AsyncFileSizeUpdateEvent(relativePath, filename); coordinatorManager.getCoordinator().getEventBus().fireEventToListenersOf(event, fileSizeSubscription); } @@ -297,7 +317,8 @@ public class VFSRepositoryServiceImpl implements VFSRepositoryService, GenericEv if(leaf == null || leaf.canMeta() != VFSConstants.YES) return; // nothing to do String relativePath = getContainerRelativePath(leaf); - metadataDao.updateMetadata(leaf.getSize(), relativePath, leaf.getName()); + Date lastModified = new Date(leaf.getLastModified()); + metadataDao.updateMetadata(leaf.getSize(), lastModified, relativePath, leaf.getName()); } @Override @@ -310,6 +331,24 @@ public class VFSRepositoryServiceImpl implements VFSRepositoryService, GenericEv } thumbnailDao.removeThumbnail(thumbnail); } + + List<VFSRevision> revisions = getRevisions(data); + for(VFSRevision revision:revisions) { + File revFile = getRevisionFile(revision); + if(revFile != null && revFile.exists()) { + try { + Files.delete(revFile.toPath()); + } catch (IOException e) { + log.error("Cannot delete thumbnail: " + revFile, e); + } + } + revisionDao.deleteRevision(revision); + } + + List<VFSMetadata> children = getChildren(data); + for(VFSMetadata child:children) { + deleteMetadata(child); + } metadataDao.removeMetadata(data); } @@ -321,6 +360,18 @@ public class VFSRepositoryServiceImpl implements VFSRepositoryService, GenericEv } } + @Override + public void markAsDeleted(VFSItem item, Identity author) { + if(item.canMeta() != VFSConstants.YES) return; + + VFSMetadataImpl metadata = (VFSMetadataImpl)getMetadataFor(item); + metadata.setDeleted(true); + if(item instanceof VFSLeaf && item.canMeta() == VFSConstants.YES) { + addToRevisions((VFSLeaf)item, metadata, author, ""); + } + metadataDao.updateMetadata(metadata); + } + @Override public void copyBinaries(VFSMetadata metadata, byte[] binaries) { if(binaries == null || binaries.length == 0) return; @@ -340,23 +391,61 @@ public class VFSRepositoryServiceImpl implements VFSRepositoryService, GenericEv VFSMetadata targetMetadata = loadMetadata(targetFile); if(targetMetadata == null) { VFSMetadata parentMetadata = getMetadataFor(parentTarget); - String relativePath = this.getRelativePath(targetFile.getParentFile()); + String relativePath = getRelativePath(targetFile.getParentFile()); targetMetadata = metadataDao.createMetadata(UUID.randomUUID().toString(), relativePath, targetFile.getName(), new Date(), targetFile.length(), false, targetFile.toURI().toString(), "file", parentMetadata); } targetMetadata.copyValues(sourceMetadata); + if(source.canVersion() == VFSConstants.YES || target.canVersion() == VFSConstants.YES) { + targetMetadata.setRevisionComment(sourceMetadata.getRevisionComment()); + targetMetadata.setRevisionNr(sourceMetadata.getRevisionNr()); + copy(sourceMetadata, targetMetadata); + } metadataDao.updateMetadata(targetMetadata); } } } + + private boolean copy(VFSMetadata sourceMetadata, VFSMetadata targetMetadata) { + List<VFSRevision> sourceRevisions = getRevisions(sourceMetadata); + + boolean allOk = true; + for (VFSRevision sourceRevision : sourceRevisions) { + VFSLeaf sourceRevFile = getRevisionLeaf(sourceMetadata, (VFSRevisionImpl)sourceRevision); + if(sourceRevFile != null && sourceRevFile.exists()) { + VFSRevision targetRevision = revisionDao.createRevisionCopy(sourceRevision.getAuthor(), sourceRevision.getRevisionComment(), + sourceRevision, targetMetadata); + VFSLeaf targetRevFile = getRevisionLeaf(targetMetadata, (VFSRevisionImpl)targetRevision); + VFSManager.copyContent(sourceRevFile, targetRevFile, false); + } + } + return allOk; + } @Override - public VFSMetadata rename(VFSMetadata data, String newName) { - ((VFSMetadataImpl)data).setFilename(newName); - Path newFile = Paths.get(folderModule.getCanonicalRoot(), data.getRelativePath(), newName); + public VFSMetadata rename(VFSItem item, String newName) { + VFSMetadata metadata = getMetadataFor(item); + + ((VFSMetadataImpl)metadata).setFilename(newName); + Path newFile = Paths.get(folderModule.getCanonicalRoot(), metadata.getRelativePath(), newName); String uri = newFile.toFile().toURI().toString(); - ((VFSMetadataImpl)data).setUri(uri); - return metadataDao.updateMetadata(data); + ((VFSMetadataImpl)metadata).setUri(uri); + + if(item instanceof VFSContainer) { + //TODO rename container ??? + } + + List<VFSRevision> revisions = getRevisions(metadata); + for(VFSRevision revision:revisions) { + VFSLeaf revFile = getRevisionLeaf(metadata, (VFSRevisionImpl)revision); + if(revFile != null && revFile.exists()) { + String newRevFilename = generateFilenameForRevision(newName, revision.getRevisionNr()); + revFile.rename(newRevFilename); + ((VFSRevisionImpl)revision).setFilename(newRevFilename); + revisionDao.updateRevision(revision); + } + } + return metadataDao.updateMetadata(metadata); } @Override @@ -530,6 +619,283 @@ public class VFSRepositoryServiceImpl implements VFSRepositoryService, GenericEv } } + @Override + public List<VFSRevision> getRevisions(VFSMetadataRef metadata) { + return revisionDao.getRevisions(metadata); + } + + @Override + public List<VFSRevision> getRevisions(List<VFSMetadataRef> metadatas) { + return revisionDao.getRevisions(metadatas); + } + + @Override + public boolean restoreRevision(Identity identity, VFSRevision revision, String comment) { + VFSMetadata metadata = ((VFSRevisionImpl)revision).getMetadata(); + + File currentFile = toFile(metadata); + if(!currentFile.exists()) { + // restore a deleted file + metadata = metadataDao.loadMetadata(metadata.getKey()); + ((VFSMetadataImpl)metadata).setDeleted(false); + metadata = metadataDao.updateMetadata(metadata); + try { + VFSLeaf revFile = getRevisionLeaf(metadata, ((VFSRevisionImpl)revision)); + if (FileUtils.copyToFile(revFile.getInputStream(), currentFile, "Restore")) { + deleteRevisions(metadata, Collections.singletonList(revision)); + return true; + } + } catch (IOException e) { + log.error("", e); + } + } else { + + String fileRelativePath = getRelativePath(currentFile); + VFSLeaf currentLeaf = VFSManager.olatRootLeaf(fileRelativePath); + // add current version to versions file + if (addToRevisions(currentLeaf, metadata, identity, comment)) { + // copy the content of the new file to the old + VFSLeaf revFile = getRevisionLeaf(metadata, ((VFSRevisionImpl)revision)); + if (VFSManager.copyContent(revFile.getInputStream(), currentLeaf)) { + return true; + } + } + } + return false; + } + + @Override + public boolean addVersion(VFSLeaf currentFile, Identity identity, String comment, InputStream newFile) { + boolean allOk = false; + VFSMetadata metadata = getMetadataFor(currentFile); + if (addToRevisions(currentFile, metadata, identity, comment)) { + // copy the content of the new file to the old + if(newFile instanceof net.sf.jazzlib.ZipInputStream || newFile instanceof java.util.zip.ZipInputStream) { + newFile = new ShieldInputStream(newFile); + } + allOk = VFSManager.copyContent(newFile, currentFile); + } else { + log.error("Cannot create a version of this file: " + currentFile); + } + dbInstance.commit(); + return allOk; + } + + public boolean addToRevisions(VFSLeaf currentLeaf, VFSMetadata metadata, Identity identity, String comment) { + int maxNumOfVersions = versionModule.getMaxNumberOfVersions(); + if(maxNumOfVersions == 0) { + return true;//deactivated, return all ok + } + + File currentFile = toFile(currentLeaf); + VFSContainer versionContainer = currentLeaf.getParentContainer(); + + // read from the + List<VFSRevision> revisions = revisionDao.getRevisions(metadata); + VFSRevisionImpl lastRevision = (VFSRevisionImpl)getLastRevision(revisions); + int versionNr = getNextRevisionNr(revisions); + + boolean sameFile = isSameFile(currentLeaf, metadata, revisions); + String uuid = sameFile && lastRevision != null ? lastRevision.getFilename() + : generateFilenameForRevision(currentFile, versionNr); + + Date lastModifiedDate = metadata.getFileLastModified(); + if(lastModifiedDate == null) { + lastModifiedDate = new Date(currentFile.lastModified()); + } + long fileSize = metadata.getFileSize(); + if(fileSize <= 0l) { + fileSize = currentFile.length(); + } + + VFSRevision newRevision = revisionDao.createRevision(metadata.getAuthor(), uuid, versionNr, + fileSize, lastModifiedDate, metadata.getRevisionComment(), metadata); + revisions.add(newRevision); + + if(!sameFile) { + resetThumbnails(currentLeaf); + } + + if (sameFile || VFSManager.copyContent(currentLeaf, versionContainer.createChildLeaf(uuid), false)) { + if(maxNumOfVersions >= 0 && revisions.size() > maxNumOfVersions) { + int numOfVersionsToDelete = Math.min(revisions.size(), (revisions.size() - maxNumOfVersions)); + if(numOfVersionsToDelete > 0) { + List<VFSRevision> versionsToDelete = revisions.subList(0, numOfVersionsToDelete); + deleteRevisions(metadata, revisions, versionsToDelete); + } + } + metadata.setRevisionComment(comment); + metadata.setRevisionNr(getNextRevisionNr(revisions)); + metadata.setAuthor(identity);//TODO dedicated author + updateMetadata(metadata); + return true; + } else { + log.error("Cannot create a version of this file: " + currentLeaf); + } + return false; + } + + @Override + public boolean deleteRevisions(Identity identity, List<VFSRevision> revisions) { + if(revisions == null || revisions.isEmpty()) return true;// ok, nothing to do + + VFSMetadata metadata = ((VFSRevisionImpl)revisions.get(0)).getMetadata(); + List<VFSRevision> allRevisions = revisionDao.getRevisions(metadata); + return deleteRevisions(metadata, allRevisions, revisions); + } + + private boolean deleteRevisions(VFSMetadata metadata, List<VFSRevision> versionsToDelete) { + List<VFSRevision> allRevisions = revisionDao.getRevisions(metadata); + return deleteRevisions(metadata, allRevisions, versionsToDelete); + } + + private boolean deleteRevisions(VFSMetadata metadata, List<VFSRevision> allVersions, List<VFSRevision> versionsToDelete) { + List<VFSRevision> toDelete = new ArrayList<>(versionsToDelete); + Map<String,VFSRevisionImpl> filenamesToDelete = new HashMap<>(allVersions.size()); + for (VFSRevision versionToDelete : versionsToDelete) { + VFSRevisionImpl versionImpl = (VFSRevisionImpl) versionToDelete; + for (Iterator<VFSRevision> allVersionIt = allVersions.iterator(); allVersionIt.hasNext();) { + VFSRevisionImpl allVersionImpl = (VFSRevisionImpl) allVersionIt.next(); + if (allVersionImpl.getKey().equals(versionImpl.getKey())) { + allVersionIt.remove(); + break; + } + } + String fileToDelete = versionImpl.getFilename(); + if (fileToDelete != null) { + filenamesToDelete.put(fileToDelete, versionImpl); + } + } + + File directory = toFile(metadata).getParentFile(); + List<VFSRevisionImpl> missingFiles = new ArrayList<>(); + for(VFSRevision survivingVersion:allVersions) { + VFSRevisionImpl survivingVersionImpl = (VFSRevisionImpl)survivingVersion; + String revFilename = survivingVersionImpl.getFilename(); + if(revFilename == null || !new File(directory, revFilename).exists()) { + missingFiles.add(survivingVersionImpl);//file is missing + } else if(filenamesToDelete.containsKey(revFilename)) { + filenamesToDelete.remove(revFilename); + } + } + + toDelete.addAll(missingFiles); + for(VFSRevision versionToDelete:toDelete) { + revisionDao.deleteRevision(versionToDelete); + } + + for(String fileToDelete:filenamesToDelete.keySet()) { + try { + File file = new File(directory, fileToDelete); + Files.deleteIfExists(file.toPath()); + } catch (IOException e) { + log.error("Cannot the version of a file", e); + } + } + return true; + } + + private VFSRevision getLastRevision(List<VFSRevision> revisions) { + VFSRevision last = null; + for (VFSRevision version : revisions) { + if (last == null || version.getRevisionNr() > last.getRevisionNr()) { + last = version; + } + } + return last; + } + + private int getNextRevisionNr(List<VFSRevision> revisions) { + int maxNumber = 0; + for (VFSRevision version : revisions) { + int versionNr = version.getRevisionNr(); + if (versionNr > 0 && versionNr > maxNumber) { + maxNumber = versionNr; + } + } + return maxNumber + 1; + } + + private boolean isSameFile(VFSLeaf currentFile, VFSMetadata metadata, List<VFSRevision> revisions) { + boolean same = false; + if(!revisions.isEmpty()) { + VFSRevision lastRevision = getLastRevision(revisions); + if(lastRevision != null) { + long lastSize = lastRevision.getSize(); + long currentSize = currentFile.getSize(); + if(currentSize == lastSize && currentSize > 0 + && lastRevision instanceof VFSRevisionImpl + && currentFile instanceof LocalFileImpl) { + VFSRevisionImpl lastRev = ((VFSRevisionImpl)lastRevision); + LocalFileImpl current = (LocalFileImpl)currentFile; + //can be the same file + try { + VFSLeaf lastRevFile = getRevisionLeaf(metadata, lastRev); + Checksum cm1 = org.apache.commons.io.FileUtils.checksum(toFile(lastRevFile), new Adler32()); + Checksum cm2 = org.apache.commons.io.FileUtils.checksum(toFile(current) , new Adler32()); + same = cm1.getValue() == cm2.getValue(); + } catch (IOException e) { + log.debug("Error calculating the checksum of files"); + } + } + } + } + return same; + } + + private VFSLeaf getRevisionLeaf(VFSMetadata metadata, VFSRevisionImpl rev) { + return VFSManager.olatRootLeaf("/" + metadata.getRelativePath(), rev.getFilename()); + } + + private Path getRevisionPath(String relativePath, String revFilename) { + return Paths.get(folderModule.getCanonicalRoot(), relativePath, revFilename); + } + + @Override + public File getRevisionFile(VFSRevision revision) { + VFSRevisionImpl rev = (VFSRevisionImpl)revision; + return getRevisionPath(rev.getMetadata().getRelativePath(), rev.getFilename()).toFile(); + } + + @Override + public VFSMetadata move(VFSLeaf currentLeaf, VFSLeaf targetLeaf, Identity author) { + VFSMetadata metadata = getMetadataFor(currentLeaf); + + File currentFile = toFile(currentLeaf); + String currentRelativePath = getRelativePath(currentFile.getParentFile()); + + File targetFile = toFile(targetLeaf); + String targetRelativePath = getRelativePath(targetFile.getParentFile()); + String newTargetName = targetFile.getName(); + ((VFSMetadataImpl)metadata).setFilename(newTargetName); + ((VFSMetadataImpl)metadata).setRelativePath(targetRelativePath); + ((VFSMetadataImpl)metadata).setUri(targetFile.toURI().toString()); + VFSMetadata targetParent = getMetadataFor(targetFile.getParentFile()); + ((VFSMetadataImpl)metadata).setParent(targetParent); + ((VFSMetadataImpl)metadata).setAuthor(author); + + List<VFSRevision> revisions = getRevisions(metadata); + for(VFSRevision revision:revisions) { + VFSRevisionImpl revImpl = (VFSRevisionImpl)revision; + Path path = getRevisionPath(currentRelativePath, revImpl.getFilename()); + File revFile = path.toFile(); + if(revFile.exists()) { + String newRevFilename = generateFilenameForRevision(newTargetName, revision.getRevisionNr()); + Path targetRevPath = getRevisionPath(targetRelativePath, newRevFilename); + try { + Files.move(path, targetRevPath, StandardCopyOption.REPLACE_EXISTING); + } catch (IOException e) { + log.error("", e); + } + ((VFSRevisionImpl)revision).setFilename(newRevFilename); + revisionDao.updateRevision(revision); + } + } + + metadata = metadataDao.updateMetadata(metadata); + return metadata; + } + /** * Get the license of the MetaInfo * @@ -668,9 +1034,15 @@ public class VFSRepositoryServiceImpl implements VFSRepositoryService, GenericEv xmlMetadata = metaReader.getMetadata(); thumbnails = metaReader.getThumbnails(); } + metadata = metadataDao.createMetadata(xmlMetadata, relativePath, file.getName(), fileLastModified, size, directory, file.toURI().toString(), "file", parent); migrateThumbnails(metadata, file, thumbnails); + + File versionFile = getVersionFile(file); + if(versionFile != null) { + migrateVersions(file, versionFile, metadata); + } } } @@ -695,6 +1067,28 @@ public class VFSRepositoryServiceImpl implements VFSRepositoryService, GenericEv return sb.toString(); } + /** + * @param filename The original file + * @param revisionNr The version number + * @return A name like ._oo_vr_filename.ext + */ + private String generateFilenameForRevision(File file, int revisionNr) { + StringBuilder sb = new StringBuilder(128); + sb.append("._oo_vr_").append(revisionNr).append("_").append(file.getName()); + return sb.toString(); + } + + /** + * @param filename The original filename + * @param revisionNr The version number + * @return A name like ._oo_vr_filename.ext + */ + private String generateFilenameForRevision(String filename, int revisionNr) { + StringBuilder sb = new StringBuilder(128); + sb.append("._oo_vr_").append(revisionNr).append("_").append(filename); + return sb.toString(); + } + private void migrateThumbnails(VFSMetadata metadata, File file, List<Thumbnail> thumbnails) { if(thumbnails == null || thumbnails.isEmpty()) return; @@ -741,6 +1135,54 @@ public class VFSRepositoryServiceImpl implements VFSRepositoryService, GenericEv } return canonicalMetaPath; } + + private VFSMetadata migrateVersions(File file, File versionFile, VFSMetadata metadata) { + VersionsFileImpl versions = (VersionsFileImpl)VFSXStream.read(versionFile); + List<VFSRevision> revisions = versions.getRevisions(); + if(revisions == null || revisions.isEmpty()) { + return metadata; + } + + metadata.setRevisionComment(versions.getComment()); + metadata.setRevisionNr(versions.getRevisionNr()); + metadata = metadataDao.updateMetadata(metadata); + + for(VFSRevision revision:revisions) { + RevisionFileImpl revisionFile = (RevisionFileImpl)revision; + String filename = revisionFile.getFilename(); + File oldOne = new File(versionFile.getParentFile(), filename); + if(oldOne.exists()) { + try { + String newRevisionFilename = generateFilenameForRevision(file, revisionFile.getRevisionNr()); + revisionDao.createRevision(revisionFile.getAuthor(), newRevisionFilename, revisionFile.getRevisionNr(), + oldOne.length(), revisionFile.getFileLastModified(), revisionFile.getComment(), metadata); + File target = new File(file.getParentFile(), newRevisionFilename); + Files.move(oldOne.toPath(), target.toPath(), StandardCopyOption.REPLACE_EXISTING); + } catch (IOException e) { + log.error("", e); + } + } + } + return metadata; + } + + /** + * @param file The regular file + * @return The XML versions file + */ + private File getVersionFile(File file) { + if (file == null || !file.exists()) { + return null; + } + String relPath = getRelativePath(file); + if (relPath == null) {// cannot handle + return null; + } + + File versionFolder = new File(FolderConfig.getCanonicalVersionRoot(), relPath); + File fVersion = new File(versionFolder.getParentFile(), file.getName() + ".xml"); + return fVersion.exists() ? fVersion : null; + } @Override public boolean hasEditor(String suffix) { diff --git a/src/main/java/org/olat/core/commons/services/vfs/manager/VFSRevisionDAO.java b/src/main/java/org/olat/core/commons/services/vfs/manager/VFSRevisionDAO.java new file mode 100644 index 0000000000000000000000000000000000000000..d702ba9ae1f5ea3da6f37ffd4f7a174941d98635 --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/vfs/manager/VFSRevisionDAO.java @@ -0,0 +1,125 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.vfs.manager; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + +import org.olat.core.commons.persistence.DB; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSMetadataRef; +import org.olat.core.commons.services.vfs.VFSRevision; +import org.olat.core.commons.services.vfs.model.VFSRevisionImpl; +import org.olat.core.id.Identity; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * + * Initial date: 18 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +@Service +public class VFSRevisionDAO { + + @Autowired + private DB dbInstance; + + public VFSRevision createRevision(Identity author, String filename, int revisionNr, long size, Date fileLastModified, + String comment, VFSMetadata metadata) { + VFSRevisionImpl rev = new VFSRevisionImpl(); + rev.setCreationDate(new Date()); + rev.setLastModified(rev.getCreationDate()); + rev.setRevisionNr(revisionNr); + rev.setFilename(filename); + if(fileLastModified == null) { + rev.setFileLastModified(rev.getCreationDate()); + } else { + rev.setFileLastModified(fileLastModified); + } + rev.setSize(size); + rev.setRevisionComment(comment); + rev.copyValues(metadata); + rev.setAuthor(author); + rev.setMetadata(metadata); + dbInstance.getCurrentEntityManager().persist(rev); + return rev; + } + + public VFSRevision createRevisionCopy(Identity author, String revisionComment, VFSRevision revisionToCopy, VFSMetadata metadata) { + VFSRevisionImpl rev = new VFSRevisionImpl(); + VFSRevisionImpl revToCopy = (VFSRevisionImpl)revisionToCopy; + rev.setCreationDate(new Date()); + rev.setLastModified(rev.getCreationDate()); + rev.setRevisionNr(revToCopy.getRevisionNr()); + rev.setFilename(revToCopy.getFilename()); + rev.setFileLastModified(revToCopy.getFileLastModified()); + rev.setSize(revToCopy.getSize()); + rev.setRevisionComment(revisionComment); + rev.setAuthor(author); + rev.copyValues(revToCopy); + rev.setMetadata(metadata); + dbInstance.getCurrentEntityManager().persist(rev); + return rev; + } + + public List<VFSRevision> getRevisions(VFSMetadataRef metadata) { + StringBuilder sb = new StringBuilder(256); + sb.append("select rev from vfsrevision rev") + .append(" left join fetch rev.author as author") + .append(" left join fetch author.user as authorUser") + .append(" where rev.metadata.key=:metadataKey") + .append(" order by rev.revisionNr"); + return dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), VFSRevision.class) + .setParameter("metadataKey", metadata.getKey()) + .getResultList(); + } + + public List<VFSRevision> getRevisions(List<VFSMetadataRef> metadatas) { + if(metadatas == null || metadatas.isEmpty()) return new ArrayList<>(); + + List<Long> metadataKeys = metadatas.stream().map(VFSMetadataRef::getKey).collect(Collectors.toList()); + + StringBuilder sb = new StringBuilder(256); + sb.append("select rev from vfsrevision rev") + .append(" left join fetch rev.author as author") + .append(" left join fetch author.user as authorUser") + .append(" where rev.metadata.key in (:metadataKeys)"); + return dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), VFSRevision.class) + .setParameter("metadataKeys", metadataKeys) + .getResultList(); + } + + public VFSRevision updateRevision(VFSRevision revision) { + return dbInstance.getCurrentEntityManager().merge(revision); + } + + public void deleteRevision(VFSRevision revision) { + VFSRevision reloadedRev = dbInstance.getCurrentEntityManager() + .getReference(VFSRevisionImpl.class, ((VFSRevisionImpl)revision).getKey()); + dbInstance.getCurrentEntityManager().remove(reloadedRev); + } + +} diff --git a/src/main/java/org/olat/core/commons/services/vfs/manager/VFSXStream.java b/src/main/java/org/olat/core/commons/services/vfs/manager/VFSXStream.java index 870ab3505a25a881c74a17907c68fc14c82b9615..ea94e2f5b5ad325af5ec449b2d2712bade98da16 100644 --- a/src/main/java/org/olat/core/commons/services/vfs/manager/VFSXStream.java +++ b/src/main/java/org/olat/core/commons/services/vfs/manager/VFSXStream.java @@ -19,6 +19,7 @@ */ package org.olat.core.commons.services.vfs.manager; +import java.io.File; import java.io.InputStream; import org.olat.basesecurity.BaseSecurity; @@ -28,12 +29,12 @@ import org.olat.core.commons.services.license.LicenseService; import org.olat.core.commons.services.license.LicenseType; import org.olat.core.commons.services.license.model.LicenseTypeImpl; import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRevision; import org.olat.core.commons.services.vfs.model.VFSMetadataImpl; import org.olat.core.id.Identity; +import org.olat.core.util.StringHelper; import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.version.RevisionFileImpl; -import org.olat.core.util.vfs.version.VFSRevision; -import org.olat.core.util.vfs.version.Versions; import org.olat.core.util.vfs.version.VersionsFileImpl; import org.olat.core.util.xml.XStreamHelper; @@ -54,7 +55,7 @@ public class VFSXStream { mystream = XStreamHelper.createXStreamInstance(); XStream.setupDefaultSecurity(mystream); Class<?>[] types = new Class[] { - VersionsFileImpl.class, Versions.class, RevisionFileImpl.class, VFSRevision.class, + VersionsFileImpl.class, RevisionFileImpl.class, VFSRevision.class, VFSMetadata.class, VFSMetadataImpl.class, Identity.class, IdentityImpl.class, LicenseType.class, LicenseTypeImpl.class }; @@ -77,18 +78,23 @@ public class VFSXStream { mystream.omitField(VFSMetadataImpl.class, "thumbnails"); mystream.registerLocalConverter(VFSMetadataImpl.class, "licenseType", new LicenseTypeConverter()); - mystream.registerLocalConverter(VFSMetadataImpl.class, "author", new IdentityConverter()); + mystream.registerLocalConverter(VFSMetadataImpl.class, "author", new IdentityConverter()); + mystream.registerLocalConverter(RevisionFileImpl.class, "author", new IdentityConverter()); } public static final Object read(InputStream in) { return XStreamHelper.readObject(mystream, in); } + public static final Object read(File file) { + return XStreamHelper.readObject(mystream, file); + } + public static final Object read(VFSLeaf leaf) { return XStreamHelper.readObject(mystream, leaf); } - public static final void write(VFSLeaf leaf, Versions versions) { + public static final void write(VFSLeaf leaf, VersionsFileImpl versions) { XStreamHelper.writeObject(mystream, leaf, versions); } @@ -132,8 +138,15 @@ public class VFSXStream { @Override public Object fromString(String str) { - Long identityKey = Long.valueOf(str); - return CoreSpringFactory.getImpl(BaseSecurity.class).loadIdentityByKey(identityKey); + Identity identity = null; + if(StringHelper.isLong(str)) { + Long identityKey = Long.valueOf(str); + identity = CoreSpringFactory.getImpl(BaseSecurity.class).loadIdentityByKey(identityKey); + } + if(identity == null) { + identity = CoreSpringFactory.getImpl(BaseSecurity.class).findIdentityByName(str); + } + return identity; } } } diff --git a/src/main/java/org/olat/core/commons/services/vfs/model/VFSMetadataImpl.java b/src/main/java/org/olat/core/commons/services/vfs/model/VFSMetadataImpl.java index bc0e8993f125225f3c43e88c29dc3d2d86786340..eed8e40e873e52ea454c680a55a8345b310f6edf 100644 --- a/src/main/java/org/olat/core/commons/services/vfs/model/VFSMetadataImpl.java +++ b/src/main/java/org/olat/core/commons/services/vfs/model/VFSMetadataImpl.java @@ -67,6 +67,8 @@ public class VFSMetadataImpl implements Persistable, VFSMetadata { @Column(name="f_uuid", nullable=false, insertable=true, updatable=true) private String uuid; + @Column(name="f_deleted", nullable=false, insertable=true, updatable=true) + private boolean deleted; @Column(name="f_filename", nullable=false, insertable=true, updatable=true) private String filename; @Column(name="f_relative_path", nullable=false, insertable=true, updatable=true) @@ -129,6 +131,11 @@ public class VFSMetadataImpl implements Persistable, VFSMetadata { @Column(name="f_locked", nullable=true, insertable=true, updatable=true) private boolean locked; + @Column(name="f_revision_nr", nullable=true, insertable=true, updatable=true) + private int revisionNr; + @Column(name="f_revision_comment", nullable=true, insertable=true, updatable=true) + private String revisionComment; + @ManyToOne(targetEntity=IdentityImpl.class,fetch=FetchType.LAZY,optional=true) @JoinColumn(name="fk_author", nullable=true, insertable=true, updatable=true) private Identity author; @@ -168,6 +175,15 @@ public class VFSMetadataImpl implements Persistable, VFSMetadata { lastModified = date; } + @Override + public boolean isDeleted() { + return deleted; + } + + public void setDeleted(boolean deleted) { + this.deleted = deleted; + } + @Override public String getFilename() { return filename; @@ -457,10 +473,12 @@ public class VFSMetadataImpl implements Persistable, VFSMetadata { this.locked = locked; } + @Override public Boolean getCannotGenerateThumbnails() { return cannotGenerateThumbnails; } + @Override public void setCannotGenerateThumbnails(Boolean cannotGenerateThumbnails) { this.cannotGenerateThumbnails = cannotGenerateThumbnails; } @@ -473,6 +491,26 @@ public class VFSMetadataImpl implements Persistable, VFSMetadata { this.materializedPathKeys = materializedPathKeys; } + @Override + public int getRevisionNr() { + return revisionNr; + } + + @Override + public void setRevisionNr(int revisionNr) { + this.revisionNr = revisionNr; + } + + @Override + public String getRevisionComment() { + return revisionComment; + } + + @Override + public void setRevisionComment(String revisionComment) { + this.revisionComment = revisionComment; + } + public VFSMetadata getParent() { return parent; } diff --git a/src/main/java/org/olat/core/commons/services/vfs/model/VFSRevisionImpl.java b/src/main/java/org/olat/core/commons/services/vfs/model/VFSRevisionImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..d07dcff55f711419f18f2a97ec73817c4960e729 --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/vfs/model/VFSRevisionImpl.java @@ -0,0 +1,393 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.vfs.model; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import org.olat.basesecurity.IdentityImpl; +import org.olat.core.commons.services.license.LicenseType; +import org.olat.core.commons.services.license.model.LicenseTypeImpl; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRevision; +import org.olat.core.id.Identity; +import org.olat.core.id.Persistable; + +/** + * + * Initial date: 18 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +@Entity(name="vfsrevision") +@Table(name="o_vfs_revision") +public class VFSRevisionImpl implements Persistable, VFSRevision { + + private static final long serialVersionUID = 2868142296811338251L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name="id", nullable=false, unique=true, insertable=true, updatable=false) + private Long key; + + @Temporal(TemporalType.TIMESTAMP) + @Column(name="creationdate", nullable=false, insertable=true, updatable=false) + private Date creationDate; + @Temporal(TemporalType.TIMESTAMP) + @Column(name="lastmodified", nullable=false, insertable=true, updatable=true) + private Date lastModified; + + @Column(name="f_revision_nr", nullable=false, insertable=true, updatable=true) + private int revisionNr; + @Column(name="f_revision_filename", nullable=false, insertable=true, updatable=true) + private String filename; + @Column(name="f_revision_size", nullable=false, insertable=true, updatable=true) + private long size; + @Temporal(TemporalType.TIMESTAMP) + @Column(name="f_revision_lastmodified", nullable=false, insertable=true, updatable=true) + private Date fileLastModified; + @Column(name="f_revision_comment", nullable=true, insertable=true, updatable=true) + private String revisionComment; + + @Column(name="f_comment", nullable=true, insertable=true, updatable=true) + private String comment; + @Column(name="f_title", nullable=true, insertable=true, updatable=true) + private String title; + @Column(name="f_publisher", nullable=true, insertable=true, updatable=true) + private String publisher; + @Column(name="f_creator", nullable=true, insertable=true, updatable=true) + private String creator; + @Column(name="f_source", nullable=true, insertable=true, updatable=true) + private String source; + @Column(name="f_city", nullable=true, insertable=true, updatable=true) + private String city; + @Column(name="f_pages", nullable=true, insertable=true, updatable=true) + private String pages; + @Column(name="f_language", nullable=true, insertable=true, updatable=true) + private String language; + @Column(name="f_url", nullable=true, insertable=true, updatable=true) + private String url; + @Column(name="f_pub_month", nullable=true, insertable=true, updatable=true) + private String pubMonth; + @Column(name="f_pub_year", nullable=true, insertable=true, updatable=true) + private String pubYear; + + @ManyToOne(targetEntity=LicenseTypeImpl.class, optional=true) + @JoinColumn(name="fk_license_type", nullable=true, insertable=true, updatable=true) + private LicenseType licenseType; + @Column(name="f_license_type_name", nullable=true, insertable=true, updatable=true) + private String licenseTypeName; + @Column(name="f_license_text", nullable=true, insertable=true, updatable=true) + private String licenseText; + @Column(name="f_licensor", nullable=true, insertable=true, updatable=true) + private String licensor; + + + @ManyToOne(targetEntity=IdentityImpl.class,fetch=FetchType.LAZY,optional=true) + @JoinColumn(name="fk_author", nullable=true, insertable=true, updatable=true) + private Identity author; + @ManyToOne(targetEntity=VFSMetadataImpl.class,fetch=FetchType.LAZY,optional=false) + @JoinColumn(name="fk_metadata", nullable=false, insertable=true, updatable=false) + private VFSMetadata metadata; + + + @Override + public Long getKey() { + return key; + } + + public void setKey(Long key) { + this.key = key; + } + + @Override + public Date getCreationDate() { + return creationDate; + } + + public void setCreationDate(Date creationDate) { + this.creationDate = creationDate; + } + + public void setLastModified(Date lastModified) { + this.lastModified = lastModified; + } + + @Override + public Identity getAuthor() { + return author; + } + + public void setAuthor(Identity author) { + this.author = author; + } + + @Override + public Date getFileLastModified() { + return fileLastModified; + } + + public void setFileLastModified(Date date) { + this.fileLastModified = date; + } + + public String getFilename() { + return filename; + } + + public void setFilename(String filename) { + this.filename = filename; + } + + @Override + public int getRevisionNr() { + return revisionNr; + } + + public void setRevisionNr(int revision) { + this.revisionNr = revision; + } + + @Override + public String getRevisionComment() { + return revisionComment; + } + + public void setRevisionComment(String text) { + revisionComment = text; + } + + @Override + public String getName() { + return null; + } + + @Override + public long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } + + public String getComment() { + return comment; + } + + public void setComment(String comment) { + this.comment = comment; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getPublisher() { + return publisher; + } + + public void setPublisher(String publisher) { + this.publisher = publisher; + } + + public String getCreator() { + return creator; + } + + public void setCreator(String creator) { + this.creator = creator; + } + + public String getSource() { + return source; + } + + public void setSource(String source) { + this.source = source; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getPages() { + return pages; + } + + public void setPages(String pages) { + this.pages = pages; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getPubMonth() { + return pubMonth; + } + + public void setPubMonth(String pubMonth) { + this.pubMonth = pubMonth; + } + + public String getPubYear() { + return pubYear; + } + + public void setPubYear(String pubYear) { + this.pubYear = pubYear; + } + + public LicenseType getLicenseType() { + return licenseType; + } + + public void setLicenseType(LicenseType licenseType) { + this.licenseType = licenseType; + } + + public String getLicenseTypeName() { + return licenseTypeName; + } + + public void setLicenseTypeName(String licenseTypeName) { + this.licenseTypeName = licenseTypeName; + } + + public String getLicenseText() { + return licenseText; + } + + public void setLicenseText(String licenseText) { + this.licenseText = licenseText; + } + + public String getLicensor() { + return licensor; + } + + public void setLicensor(String licensor) { + this.licensor = licensor; + } + + public Date getLastModified() { + return lastModified; + } + + @Override + public VFSMetadata getMetadata() { + return metadata; + } + + public void setMetadata(VFSMetadata metadata) { + this.metadata = metadata; + } + + public void copyValues(VFSMetadata fromMeta) { + setComment(fromMeta.getComment()); + setCity(fromMeta.getCity()); + setCreator(fromMeta.getCreator()); + setLanguage(fromMeta.getLanguage()); + setPages(fromMeta.getPages()); + String[] pubDates = fromMeta.getPublicationDate(); + setPubYear(pubDates[0]); + setPubMonth(pubDates[1]); + setPublisher(fromMeta.getPublisher()); + setSource(fromMeta.getSource()); + setTitle(fromMeta.getTitle()); + setUrl(fromMeta.getUrl()); + setLicenseType(fromMeta.getLicenseType()); + setLicenseTypeName(fromMeta.getLicenseTypeName()); + setLicensor(fromMeta.getLicensor()); + setLicenseText(fromMeta.getLicenseText()); + } + + public void copyValues(VFSRevisionImpl fromMeta) { + setComment(fromMeta.getComment()); + setCity(fromMeta.getCity()); + setCreator(fromMeta.getCreator()); + setLanguage(fromMeta.getLanguage()); + setPages(fromMeta.getPages()); + setPubYear(fromMeta.getPubYear()); + setPubMonth(fromMeta.getPubMonth()); + setPublisher(fromMeta.getPublisher()); + setSource(fromMeta.getSource()); + setTitle(fromMeta.getTitle()); + setUrl(fromMeta.getUrl()); + setLicenseType(fromMeta.getLicenseType()); + setLicenseTypeName(fromMeta.getLicenseTypeName()); + setLicensor(fromMeta.getLicensor()); + setLicenseText(fromMeta.getLicenseText()); + } + + @Override + public int hashCode() { + return getKey() == null ? 221879 : getKey().hashCode(); + } + + @Override + public boolean equals(Object obj) { + if(obj == this) { + return true; + } + if(obj instanceof VFSRevisionImpl) { + VFSRevisionImpl rev = (VFSRevisionImpl)obj; + return getKey() != null && getKey().equals(rev.getKey()); + } + return super.equals(obj); + } + + @Override + public boolean equalsByPersistableKey(Persistable persistable) { + return equals(persistable); + } +} diff --git a/src/main/java/org/olat/core/util/vfs/restapi/VFSStreamingOutput.java b/src/main/java/org/olat/core/commons/services/vfs/restapi/VFSStreamingOutput.java similarity index 96% rename from src/main/java/org/olat/core/util/vfs/restapi/VFSStreamingOutput.java rename to src/main/java/org/olat/core/commons/services/vfs/restapi/VFSStreamingOutput.java index ba11edb7aa0c6d288e10cc80145749ccd5173bf0..8a82e1eb2d519a266295f52f0c8bb6f381984950 100644 --- a/src/main/java/org/olat/core/util/vfs/restapi/VFSStreamingOutput.java +++ b/src/main/java/org/olat/core/commons/services/vfs/restapi/VFSStreamingOutput.java @@ -17,7 +17,7 @@ * frentix GmbH, http://www.frentix.com * <p> */ -package org.olat.core.util.vfs.restapi; +package org.olat.core.commons.services.vfs.restapi; import java.io.InputStream; import java.io.OutputStream; diff --git a/src/main/java/org/olat/core/util/vfs/restapi/VFSWebServiceSecurityCallback.java b/src/main/java/org/olat/core/commons/services/vfs/restapi/VFSWebServiceSecurityCallback.java similarity index 97% rename from src/main/java/org/olat/core/util/vfs/restapi/VFSWebServiceSecurityCallback.java rename to src/main/java/org/olat/core/commons/services/vfs/restapi/VFSWebServiceSecurityCallback.java index 73e54f3de454b00141fb613fd4c1792e57943372..2e1c22917d40394a1aca27f3f351932d2839fa63 100644 --- a/src/main/java/org/olat/core/util/vfs/restapi/VFSWebServiceSecurityCallback.java +++ b/src/main/java/org/olat/core/commons/services/vfs/restapi/VFSWebServiceSecurityCallback.java @@ -17,7 +17,7 @@ * frentix GmbH, http://www.frentix.com * <p> */ -package org.olat.core.util.vfs.restapi; +package org.olat.core.commons.services.vfs.restapi; import org.olat.core.commons.services.notifications.SubscriptionContext; import org.olat.core.util.vfs.Quota; diff --git a/src/main/java/org/olat/core/util/vfs/restapi/VFSWebservice.java b/src/main/java/org/olat/core/commons/services/vfs/restapi/VFSWebservice.java similarity index 99% rename from src/main/java/org/olat/core/util/vfs/restapi/VFSWebservice.java rename to src/main/java/org/olat/core/commons/services/vfs/restapi/VFSWebservice.java index 3c70f9b15f1e2180e3f1da3810544177007d4df3..a4fd665ccebe04394c286bb64d09e8848491e684 100644 --- a/src/main/java/org/olat/core/util/vfs/restapi/VFSWebservice.java +++ b/src/main/java/org/olat/core/commons/services/vfs/restapi/VFSWebservice.java @@ -17,7 +17,7 @@ * frentix GmbH, http://www.frentix.com * <p> */ -package org.olat.core.util.vfs.restapi; +package org.olat.core.commons.services.vfs.restapi; import java.io.ByteArrayInputStream; import java.io.File; diff --git a/src/main/java/org/olat/core/commons/services/vfs/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/core/commons/services/vfs/ui/_i18n/LocalStrings_de.properties new file mode 100644 index 0000000000000000000000000000000000000000..bfbc7319fefb66d29e60477dee89a76dce024b7e --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/vfs/ui/_i18n/LocalStrings_de.properties @@ -0,0 +1 @@ +#Mon Jan 25 15:05:06 CET 2010 \ No newline at end of file diff --git a/src/main/java/org/olat/core/commons/services/vfs/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/core/commons/services/vfs/ui/_i18n/LocalStrings_en.properties new file mode 100644 index 0000000000000000000000000000000000000000..1121af75e3c608b1794e69a2cd8cea07577ba61a --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/vfs/ui/_i18n/LocalStrings_en.properties @@ -0,0 +1 @@ +#Mon Jan 25 15:05:06 CET 2010 diff --git a/src/main/java/org/olat/core/commons/services/vfs/ui/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/core/commons/services/vfs/ui/_i18n/LocalStrings_fr.properties new file mode 100644 index 0000000000000000000000000000000000000000..e41d2b6eaa109c20468bff62e73e4633b520ffd8 --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/vfs/ui/_i18n/LocalStrings_fr.properties @@ -0,0 +1 @@ +#Mon Feb 08 13:20:57 CET 2010 diff --git a/src/main/java/org/olat/core/util/vfs/VFSRevisionMediaResource.java b/src/main/java/org/olat/core/commons/services/vfs/ui/media/VFSRevisionMediaResource.java similarity index 73% rename from src/main/java/org/olat/core/util/vfs/VFSRevisionMediaResource.java rename to src/main/java/org/olat/core/commons/services/vfs/ui/media/VFSRevisionMediaResource.java index 7b8db8a6a79ac2713611d22acf7bf92a293b07a4..aefbcfbd77908c3841b9bb78c45c9398a5bb9263 100644 --- a/src/main/java/org/olat/core/util/vfs/VFSRevisionMediaResource.java +++ b/src/main/java/org/olat/core/commons/services/vfs/ui/media/VFSRevisionMediaResource.java @@ -17,21 +17,31 @@ * frentix GmbH, http://www.frentix.com * <p> */ -package org.olat.core.util.vfs; +package org.olat.core.commons.services.vfs.ui.media; +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; import java.io.InputStream; +import java.util.Date; import javax.servlet.http.HttpServletResponse; +import org.olat.core.CoreSpringFactory; +import org.olat.core.commons.services.vfs.VFSRepositoryService; +import org.olat.core.commons.services.vfs.VFSRevision; import org.olat.core.gui.media.MediaResource; import org.olat.core.gui.media.ServletUtil; +import org.olat.core.logging.OLog; +import org.olat.core.logging.Tracing; import org.olat.core.util.StringHelper; import org.olat.core.util.WebappHelper; -import org.olat.core.util.vfs.version.VFSRevision; +import org.olat.core.util.vfs.VFSConstants; public class VFSRevisionMediaResource implements MediaResource { private static final String MIME_TYPE_OCTET_STREAM = "application/octet-stream"; + private static final OLog log = Tracing.createLoggerFor(VFSRevisionMediaResource.class); private String encoding; private boolean forceDownload = false; @@ -75,19 +85,26 @@ public class VFSRevisionMediaResource implements MediaResource { @Override public InputStream getInputStream() { - return revision.getInputStream(); + File revFile = CoreSpringFactory.getImpl(VFSRepositoryService.class).getRevisionFile(revision); + InputStream in = null; + try { + in = new BufferedInputStream(new FileInputStream(revFile)); + } catch(Exception e) { + log.error("", e); + } + return in; } @Override public Long getLastModified() { - long lastModified = revision.getLastModified(); - return (lastModified == VFSConstants.UNDEFINED) ? null : new Long(lastModified); + Date lastModified = revision.getFileLastModified(); + return lastModified == null ? null : Long.valueOf(lastModified.getTime()); } @Override public Long getSize() { long size = revision.getSize(); - return (size == VFSConstants.UNDEFINED) ? null : new Long(size); + return (size == VFSConstants.UNDEFINED) ? null : Long.valueOf(size); } @Override diff --git a/src/main/java/org/olat/core/commons/services/vfs/ui/version/DeletedFileListController.java b/src/main/java/org/olat/core/commons/services/vfs/ui/version/DeletedFileListController.java new file mode 100644 index 0000000000000000000000000000000000000000..680decec509369b3a2e260f7b5d7a8d473939190 --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/vfs/ui/version/DeletedFileListController.java @@ -0,0 +1,286 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.vfs.ui.version; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.olat.core.commons.modules.bc.commands.FolderCommand; +import org.olat.core.commons.modules.bc.commands.FolderCommandStatus; +import org.olat.core.commons.persistence.SortKey; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRepositoryService; +import org.olat.core.commons.services.vfs.VFSRevision; +import org.olat.core.commons.services.vfs.ui.version.DeletedFileListDataModel.DeletedCols; +import org.olat.core.commons.services.vfs.ui.version.RevisionListDataModel.RevisionCols; +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.form.flexible.FormItem; +import org.olat.core.gui.components.form.flexible.FormItemContainer; +import org.olat.core.gui.components.form.flexible.elements.DownloadLink; +import org.olat.core.gui.components.form.flexible.elements.FlexiTableElement; +import org.olat.core.gui.components.form.flexible.elements.FlexiTableSortOptions; +import org.olat.core.gui.components.form.flexible.elements.FormLink; +import org.olat.core.gui.components.form.flexible.impl.FormBasicController; +import org.olat.core.gui.components.form.flexible.impl.FormEvent; +import org.olat.core.gui.components.form.flexible.impl.elements.table.BooleanCellRenderer; +import org.olat.core.gui.components.form.flexible.impl.elements.table.DateFlexiCellRenderer; +import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiColumnModel; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableDataModelFactory; +import org.olat.core.gui.components.form.flexible.impl.elements.table.SelectionEvent; +import org.olat.core.gui.components.form.flexible.impl.elements.table.StaticFlexiCellRenderer; +import org.olat.core.gui.components.link.Link; +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.control.generic.modal.DialogBoxController; +import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory; +import org.olat.core.util.vfs.VFSContainer; +import org.olat.core.util.vfs.VFSManager; +import org.olat.core.util.vfs.VFSMediaResource; +import org.olat.core.util.vfs.callbacks.VFSSecurityCallback; +import org.olat.user.UserManager; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * + * Initial date: 21 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class DeletedFileListController extends FormBasicController { + + private int status = FolderCommandStatus.STATUS_SUCCESS; + + private FormLink deleteButton; + private FormLink restoreButton; + private FlexiTableElement tableEl; + private DeletedFileListDataModel tableModel; + + private DialogBoxController dialogCtr; + + private int counter = 0; + private final VFSContainer container; + + @Autowired + private UserManager userManager; + @Autowired + private VFSRepositoryService vfsRepositoryService; + + public DeletedFileListController(UserRequest ureq, WindowControl wControl, VFSContainer container) { + super(ureq, wControl, "deleted_files"); + this.container = container; + initForm(ureq); + loadModel(); + } + + public int getStatus() { + return status; + } + + @Override + protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { + VFSSecurityCallback secCallback = VFSManager.findInheritedSecurityCallback(container); + + FlexiTableColumnModel columnsModel = FlexiTableDataModelFactory.createFlexiTableColumnModel(); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(false, DeletedCols.id)); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(DeletedCols.nr)); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(DeletedCols.filename)); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(DeletedCols.deletedBy, new IdentityCellRenderer(userManager))); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(DeletedCols.date, new DateFlexiCellRenderer(getLocale()))); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(DeletedCols.download)); + if (secCallback != null && secCallback.canWrite()) { + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(DeletedCols.restore, "restore", + new BooleanCellRenderer(new StaticFlexiCellRenderer(translate("version.restore"), "restore"), null))); + } + + tableModel = new DeletedFileListDataModel(columnsModel, getTranslator()); + tableEl = uifactory.addTableElement(getWindowControl(), "table", tableModel, 24, false, getTranslator(), formLayout); + tableEl.setEmtpyTableMessageKey(translate("version.noDeletedFiles")); + tableEl.setMultiSelect(true); + FlexiTableSortOptions sortOptions = new FlexiTableSortOptions(true); + sortOptions.setDefaultOrderBy(new SortKey(RevisionCols.nr.name(), false)); + tableEl.setSortSettings(sortOptions); + tableEl.setAndLoadPersistedPreferences(ureq, "deleted-file-list-v2"); + + if (secCallback != null) { + if (secCallback.canDeleteRevisionsPermanently()) { + deleteButton = uifactory.addFormLink("delete", formLayout, Link.BUTTON); + } + if (secCallback.canWrite()) { + restoreButton = uifactory.addFormLink("version.restore", formLayout, Link.BUTTON); + } + } + + uifactory.addFormCancelButton("cancel", formLayout, ureq, getWindowControl()); + } + + @Override + protected void event(UserRequest ureq, Controller source, Event event) { + if (source == dialogCtr) { + if (DialogBoxUIFactory.isYesEvent(event)) { + @SuppressWarnings("unchecked") + List<DeletedFileRow> rowsToDelete = (List<DeletedFileRow>)dialogCtr.getUserObject(); + doDelete(rowsToDelete); + fireEvent(ureq, FolderCommand.FOLDERCOMMAND_FINISHED); + } + } + super.event(ureq, source, event); + } + + @Override + protected void formOK(UserRequest ureq) { + // + } + + @Override + protected void formCancelled(UserRequest ureq) { + status = FolderCommandStatus.STATUS_CANCELED; + fireEvent(ureq, FolderCommand.FOLDERCOMMAND_FINISHED); + } + + @Override + protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { + if(restoreButton == source) { + doRestore(ureq); + } else if(deleteButton == source) { + doConfirmDelete(ureq); + } else if(tableEl == source) { + if(event instanceof SelectionEvent) { + SelectionEvent se = (SelectionEvent)event; + if("restore".equals(se.getCommand())) { + DeletedFileRow row = tableModel.getObject(se.getIndex()); + doRestore(ureq, row); + } + } + } + super.formInnerEvent(ureq, source, event); + } + + private void loadModel() { + VFSMetadata containerMetadata = vfsRepositoryService.getMetadataFor(container); + List<VFSMetadata> metadataList = vfsRepositoryService.getChildren(containerMetadata); + List<DeletedFileRow> rows = new ArrayList<>(); + Map<VFSMetadata,DeletedFileRow> metaToRows = new HashMap<>(); + for(VFSMetadata metadata:metadataList) { + if(metadata.isDeleted()) { + DeletedFileRow row = new DeletedFileRow(metadata); + rows.add(row); + metaToRows.put(metadata, row); + } + } + + List<VFSRevision> revisionList = vfsRepositoryService.getRevisions(new ArrayList<>(rows)); + for(VFSRevision revision:revisionList) { + DeletedFileRow row = metaToRows.get(revision.getMetadata()); + if(row != null) { + row.addRevision(revision); + } + } + + for(DeletedFileRow row:rows) { + if(row.getLastRevision() != null) { + VFSMediaResource resource = new VFSMediaResource(null); + resource.setDownloadable(true); + DownloadLink download = uifactory.addDownloadLink("download" + (counter++), translate("download"), null, resource, tableEl); + row.setDownloadLink(download); + } + } + + tableModel.setObjects(rows); + tableEl.reset(true, true, true); + } + + @Override + protected void doDispose() { + // + } + + private void doConfirmDelete(UserRequest ureq) { + List<DeletedFileRow> versionsToDelete = getSelectedRows(); + if (!versionsToDelete.isEmpty()) { + String msg = translate("version.del.confirm") + "<p>" + renderVersionsAsHtml(versionsToDelete) + "</p>"; + // create dialog controller + dialogCtr = activateYesNoDialog(ureq, translate("version.del.header"), msg, dialogCtr); + dialogCtr.setUserObject(versionsToDelete); + } + } + + private String renderVersionsAsHtml(List<DeletedFileRow> rows) { + StringBuilder sb = new StringBuilder(256); + sb.append("<ul>"); + for (DeletedFileRow row:rows) { + sb.append("<li>").append(row.getFilename()).append("</li>"); + } + sb.append("</ul>"); + return sb.toString(); + } + + private void doDelete(List<DeletedFileRow> rowsToDelete) { + List<VFSRevision> revisionsToDelete = new ArrayList<>(); + for(DeletedFileRow row:rowsToDelete) { + List<VFSRevision> rowRevisions = vfsRepositoryService.getRevisions(row.getMetadata()); + revisionsToDelete.addAll(rowRevisions); + } + vfsRepositoryService.deleteRevisions(getIdentity(), revisionsToDelete); + status = FolderCommandStatus.STATUS_SUCCESS; + } + + private List<DeletedFileRow> getSelectedRows() { + Set<Integer> selectedIndexes = tableEl.getMultiSelectedIndex(); + List<DeletedFileRow> selectedRows = new ArrayList<>(selectedIndexes.size()); + for(Integer selectedIndex:selectedIndexes) { + DeletedFileRow row = tableModel.getObject(selectedIndex.intValue()); + if(row != null) { + selectedRows.add(row); + } + } + return selectedRows; + } + + private void doRestore(UserRequest ureq, DeletedFileRow row) { + if (row.getLastRevision() != null && vfsRepositoryService.restoreRevision(getIdentity(), row.getLastRevision(), "")) { + status = FolderCommandStatus.STATUS_SUCCESS; + fireEvent(ureq, FolderCommand.FOLDERCOMMAND_FINISHED); + } else { + status = FolderCommandStatus.STATUS_FAILED; + // ERROR + } + } + + private void doRestore(UserRequest ureq) { + List<DeletedFileRow> selectedRows = getSelectedRows(); + boolean allOk = true; + for (DeletedFileRow selectedRow : selectedRows) { + if(selectedRow.getLastRevision() != null) { + allOk &= vfsRepositoryService.restoreRevision(getIdentity(), selectedRow.getLastRevision(), ""); + } + } + if (allOk) { + status = FolderCommandStatus.STATUS_SUCCESS; + fireEvent(ureq, FolderCommand.FOLDERCOMMAND_FINISHED); + } else { + status = FolderCommandStatus.STATUS_FAILED; + } + } +} diff --git a/src/main/java/org/olat/core/commons/services/vfs/ui/version/DeletedFileListDataModel.java b/src/main/java/org/olat/core/commons/services/vfs/ui/version/DeletedFileListDataModel.java new file mode 100644 index 0000000000000000000000000000000000000000..5be80561a36ea3c177929c615ffc857cd3e0f55c --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/vfs/ui/version/DeletedFileListDataModel.java @@ -0,0 +1,94 @@ +package org.olat.core.commons.services.vfs.ui.version; + +import java.util.List; + +import org.olat.core.commons.persistence.SortKey; +import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiTableDataModel; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiSortableColumnDef; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel; +import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFlexiTableDataModel; +import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFlexiTableModelDelegate; +import org.olat.core.gui.translator.Translator; + +/** + * + * Initial date: 21 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class DeletedFileListDataModel extends DefaultFlexiTableDataModel<DeletedFileRow> +implements SortableFlexiTableDataModel<DeletedFileRow> { + + private final Translator translator; + + public DeletedFileListDataModel(FlexiTableColumnModel columnModel, Translator translator) { + super(columnModel); + this.translator = translator; + } + + @Override + public void sort(SortKey orderBy) { + if(orderBy != null) { + List<DeletedFileRow> rows = new SortableFlexiTableModelDelegate<DeletedFileRow>(orderBy, this, translator.getLocale()).sort(); + super.setObjects(rows); + } + } + + @Override + public Object getValueAt(int row, int col) { + DeletedFileRow f = getObject(row); + return getValueAt(f, col); + } + + @Override + public Object getValueAt(DeletedFileRow row, int col) { + switch(DeletedCols.values()[col]) { + case id: return row.getMetadata().getKey(); + case nr: return row.getMetadata().getRevisionNr(); + case filename: return row.getFilename(); + case deletedBy: return row.getDeletedBy(); + case date: return row.getDate(); + case download: return row.getDownloadLink(); + case restore: return row.getLastRevision() != null; + default: return "ERROR"; + } + } + + @Override + public DefaultFlexiTableDataModel<DeletedFileRow> createCopyWithEmptyList() { + return new DeletedFileListDataModel(getTableColumnModel(), translator); + } + + public enum DeletedCols implements FlexiSortableColumnDef { + + id("table.header.id"), + nr("table.header.nr"), + filename("table.header.file"), + deletedBy("version.deletedBy"), + date("table.header.date"), + download("download"), + restore("version.restore"); + + private final String i18nKey; + + private DeletedCols(String i18nKey) { + this.i18nKey = i18nKey; + } + + @Override + public String i18nHeaderKey() { + return i18nKey; + } + + @Override + public boolean sortable() { + return true; + } + + @Override + public String sortKey() { + return name(); + } + } + +} diff --git a/src/main/java/org/olat/core/commons/services/vfs/ui/version/DeletedFileRow.java b/src/main/java/org/olat/core/commons/services/vfs/ui/version/DeletedFileRow.java new file mode 100644 index 0000000000000000000000000000000000000000..c23ba84424524ca1c77a07d9410c442dc759da22 --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/vfs/ui/version/DeletedFileRow.java @@ -0,0 +1,76 @@ +package org.olat.core.commons.services.vfs.ui.version; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSMetadataRef; +import org.olat.core.commons.services.vfs.VFSRevision; +import org.olat.core.gui.components.form.flexible.elements.DownloadLink; +import org.olat.core.id.Identity; + +/** + * + * Initial date: 21 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class DeletedFileRow implements VFSMetadataRef { + + private final VFSMetadata metadata; + private VFSRevision lastRevision; + private final List<VFSRevision> revisions = new ArrayList<>(); + + private DownloadLink downloadLink; + + public DeletedFileRow(VFSMetadata metadata) { + this.metadata = metadata; + } + + @Override + public Long getKey() { + return metadata.getKey(); + } + + public String getFilename() { + return metadata.getFilename(); + } + + public Identity getDeletedBy() { + return lastRevision == null ? null : lastRevision.getAuthor(); + } + + public Date getDate() { + return lastRevision == null ? null : lastRevision.getCreationDate(); + } + + public VFSMetadata getMetadata() { + return metadata; + } + + public DownloadLink getDownloadLink() { + return downloadLink; + } + + public void setDownloadLink(DownloadLink link) { + downloadLink = link; + } + + public VFSRevision getLastRevision() { + return lastRevision; + } + + public List<VFSRevision> getRevisions() { + return revisions; + } + + public void addRevision(VFSRevision revision) { + if(revision == null) return; + + if(lastRevision == null || lastRevision.getRevisionNr() < revision.getRevisionNr()) { + lastRevision = revision; + } + revisions.add(revision); + } +} diff --git a/src/main/java/org/olat/core/commons/services/vfs/ui/version/IdentityCellRenderer.java b/src/main/java/org/olat/core/commons/services/vfs/ui/version/IdentityCellRenderer.java new file mode 100644 index 0000000000000000000000000000000000000000..94404cd19164a68ffa2740cc819f9a7e224deb7c --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/vfs/ui/version/IdentityCellRenderer.java @@ -0,0 +1,36 @@ +package org.olat.core.commons.services.vfs.ui.version; + +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiCellRenderer; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableComponent; +import org.olat.core.gui.render.Renderer; +import org.olat.core.gui.render.StringOutput; +import org.olat.core.gui.render.URLBuilder; +import org.olat.core.gui.translator.Translator; +import org.olat.core.id.Identity; +import org.olat.user.UserManager; + +/** + * + * Initial date: 21 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class IdentityCellRenderer implements FlexiCellRenderer { + + private final UserManager userManager; + + public IdentityCellRenderer(UserManager userManager) { + this.userManager = userManager; + } + + @Override + public void render(Renderer renderer, StringOutput target, Object cellValue, int row, FlexiTableComponent source, + URLBuilder ubu, Translator translator) { + if(cellValue instanceof Identity) { + String fullName = userManager.getUserDisplayName((Identity)cellValue); + if(fullName != null) { + target.append(fullName); + } + } + } +} diff --git a/src/main/java/org/olat/core/commons/services/vfs/ui/version/RevisionListController.java b/src/main/java/org/olat/core/commons/services/vfs/ui/version/RevisionListController.java new file mode 100644 index 0000000000000000000000000000000000000000..90d44da895003f98c8328966bbef974c328da42c --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/vfs/ui/version/RevisionListController.java @@ -0,0 +1,264 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.vfs.ui.version; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + +import org.olat.basesecurity.BaseSecurity; +import org.olat.basesecurity.IdentityShort; +import org.olat.core.commons.modules.bc.commands.FolderCommand; +import org.olat.core.commons.modules.bc.commands.FolderCommandStatus; +import org.olat.core.commons.persistence.SortKey; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRepositoryService; +import org.olat.core.commons.services.vfs.VFSRevision; +import org.olat.core.commons.services.vfs.ui.media.VFSRevisionMediaResource; +import org.olat.core.commons.services.vfs.ui.version.RevisionListDataModel.RevisionCols; +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.form.flexible.FormItem; +import org.olat.core.gui.components.form.flexible.FormItemContainer; +import org.olat.core.gui.components.form.flexible.elements.DownloadLink; +import org.olat.core.gui.components.form.flexible.elements.FlexiTableElement; +import org.olat.core.gui.components.form.flexible.elements.FlexiTableSortOptions; +import org.olat.core.gui.components.form.flexible.impl.FormBasicController; +import org.olat.core.gui.components.form.flexible.impl.FormEvent; +import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer; +import org.olat.core.gui.components.form.flexible.impl.elements.table.BooleanCellRenderer; +import org.olat.core.gui.components.form.flexible.impl.elements.table.DateFlexiCellRenderer; +import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiColumnModel; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableDataModelFactory; +import org.olat.core.gui.components.form.flexible.impl.elements.table.SelectionEvent; +import org.olat.core.gui.components.form.flexible.impl.elements.table.StaticFlexiCellRenderer; +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.control.generic.modal.DialogBoxController; +import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory; +import org.olat.core.gui.media.MediaResource; +import org.olat.core.util.StringHelper; +import org.olat.core.util.vfs.VFSItem; +import org.olat.core.util.vfs.VFSLeaf; +import org.olat.core.util.vfs.VFSMediaResource; +import org.olat.user.UserManager; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * + * Initial date: 19 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class RevisionListController extends FormBasicController { + + private int status = FolderCommandStatus.STATUS_SUCCESS; + + private DialogBoxController confirmDeleteBoxCtr; + + private FlexiTableElement tableEl; + private RevisionListDataModel tableModel; + + private int counter = 0; + private final boolean readOnly; + private final VFSLeaf versionedFile; + + private final String title; + private final String description; + + @Autowired + private UserManager userManager; + @Autowired + private BaseSecurity securityManager; + @Autowired + private VFSRepositoryService vfsRepositoryService; + + public RevisionListController(UserRequest ureq, WindowControl wControl, VFSItem versionedFile, boolean readOnly) { + this(ureq, wControl, versionedFile, null, null, readOnly); + } + + public RevisionListController(UserRequest ureq, WindowControl wControl, VFSItem versionedFile, + String title, String description, boolean readOnly) { + super(ureq, wControl, "revisions"); + + this.readOnly = readOnly; + this.title = title; + this.description = description; + this.versionedFile = (VFSLeaf)versionedFile; + + initForm(ureq); + loadModel(this.versionedFile); + } + + @Override + protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { + if(formLayout instanceof FormLayoutContainer) { + FormLayoutContainer layoutCont = (FormLayoutContainer)formLayout; + if (StringHelper.containsNonWhitespace(title)) { + layoutCont.contextPut("title", title); + } + if (StringHelper.containsNonWhitespace(description)) { + layoutCont.contextPut("description", description); + } + } + + FlexiTableColumnModel columnsModel = FlexiTableDataModelFactory.createFlexiTableColumnModel(); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(false, RevisionCols.id)); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(RevisionCols.nr)); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(RevisionCols.author, new IdentityCellRenderer(userManager))); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(RevisionCols.comment)); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(RevisionCols.date, new DateFlexiCellRenderer(getLocale()))); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(RevisionCols.download)); + if(!readOnly) { + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(RevisionCols.restore, "restore", + new BooleanCellRenderer(new StaticFlexiCellRenderer(translate("version.restore"), "restore"), null))); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(RevisionCols.delete, "delete", + new BooleanCellRenderer(new StaticFlexiCellRenderer(translate("delete"), "delete"), null))); + } + + tableModel = new RevisionListDataModel(columnsModel, getTranslator()); + tableEl = uifactory.addTableElement(getWindowControl(), "table", tableModel, 24, false, getTranslator(), formLayout); + tableEl.setEmtpyTableMessageKey(translate("version.noRevisions")); + FlexiTableSortOptions sortOptions = new FlexiTableSortOptions(true); + sortOptions.setDefaultOrderBy(new SortKey(RevisionCols.nr.name(), false)); + tableEl.setSortSettings(sortOptions); + tableEl.setAndLoadPersistedPreferences(ureq, "revisions-list"); + + uifactory.addFormCancelButton("cancel", formLayout, ureq, getWindowControl()); + } + + @Override + protected void doDispose() { + // + } + + private void loadModel(VFSLeaf versionedLeaf) { + VFSMetadata metadata = vfsRepositoryService.getMetadataFor(versionedLeaf); + List<VFSRevision> revisions = vfsRepositoryService.getRevisions(metadata); + List<RevisionRow> rows = new ArrayList<>(revisions.size() + 2); + VFSMediaResource resource = new VFSMediaResource(versionedFile); + resource.setDownloadable(true); + DownloadLink download = uifactory.addDownloadLink("download" + (counter++), translate("download"), null, resource, tableEl); + rows.add(new RevisionRow(metadata, download)); + Collection<String> names = new HashSet<>(); + for(VFSRevision revision:revisions) { + MediaResource revResource = new VFSRevisionMediaResource(revision, true); + DownloadLink revDownload = uifactory.addDownloadLink("download" + (counter++), translate("download"), null, revResource, tableEl); + rows.add(new RevisionRow(revision, revDownload)); + } + + Map<String, IdentityShort> mappedIdentities = new HashMap<>(); + for(IdentityShort identity :securityManager.findShortIdentitiesByName(names)) { + mappedIdentities.put(identity.getName(), identity); + } + + tableModel.setObjects(rows); + tableEl.reset(true, true, true); + } + + public int getStatus() { + return status; + } + + @Override + protected void formOK(UserRequest ureq) { + // + } + + @Override + protected void formCancelled(UserRequest ureq) { + fireEvent(ureq, Event.CANCELLED_EVENT); + } + + @Override + protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { + if(tableEl == source) { + if(event instanceof SelectionEvent) { + SelectionEvent se = (SelectionEvent)event; + if("delete".equals(se.getCommand())) { + RevisionRow row = tableModel.getObject(se.getIndex()); + doConfirmDelete(ureq, Collections.singletonList(row)); + } else if("restore".equals(se.getCommand())) { + RevisionRow row = tableModel.getObject(se.getIndex()); + doRestore(ureq, row); + } + } + } + super.formInnerEvent(ureq, source, event); + } + + @Override + protected void event(UserRequest ureq, Controller source, Event event) { + if (source == confirmDeleteBoxCtr) { + doDeleteRevision(ureq, event); + } + } + + private void doRestore(UserRequest ureq, RevisionRow row) { + if(row.getRevision() == null) { + //restore current, do nothing + status = FolderCommandStatus.STATUS_SUCCESS; + fireEvent(ureq, FolderCommand.FOLDERCOMMAND_FINISHED); + } else { + VFSRevision version = row.getRevision(); + String comment = translate("version.restore.comment", new String[]{ Integer.toString(version.getRevisionNr()) }); + + boolean ok = vfsRepositoryService.restoreRevision(getIdentity(), version, comment); + if(ok) { + status = FolderCommandStatus.STATUS_SUCCESS; + fireEvent(ureq, FolderCommand.FOLDERCOMMAND_FINISHED); + } else { + status = FolderCommandStatus.STATUS_FAILED; + showError("version.restore.failed"); + fireEvent(ureq, FolderCommand.FOLDERCOMMAND_FINISHED); + } + } + } + + private void doConfirmDelete(UserRequest ureq, List<RevisionRow> selectedRevisions) { + String numOfVersionToDelete = Integer.toString(selectedRevisions.size()); + confirmDeleteBoxCtr = activateYesNoDialog(ureq, null, translate("version.confirmDelete", + new String[] { numOfVersionToDelete }), confirmDeleteBoxCtr); + confirmDeleteBoxCtr.setUserObject(selectedRevisions); + } + + private void doDeleteRevision(UserRequest ureq, Event event) { + if (DialogBoxUIFactory.isYesEvent(event)) { + @SuppressWarnings("unchecked") + List<RevisionRow> selectedVersions = (List<RevisionRow>) confirmDeleteBoxCtr.getUserObject(); + List<VFSRevision> revisions = new ArrayList<>(selectedVersions.size()); + for(RevisionRow selectedVersion:selectedVersions) { + if(selectedVersion.getRevision() != null) { + revisions.add(selectedVersion.getRevision()); + } + } + vfsRepositoryService.deleteRevisions(getIdentity(), revisions); + status = FolderCommandStatus.STATUS_SUCCESS; + } else { + status = FolderCommandStatus.STATUS_CANCELED; + } + fireEvent(ureq, FolderCommand.FOLDERCOMMAND_FINISHED); + } +} \ No newline at end of file diff --git a/src/main/java/org/olat/core/commons/services/vfs/ui/version/RevisionListDataModel.java b/src/main/java/org/olat/core/commons/services/vfs/ui/version/RevisionListDataModel.java new file mode 100644 index 0000000000000000000000000000000000000000..ebe1fe77ab4fae0d36ac8dd64a76f3c9c2e27ba7 --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/vfs/ui/version/RevisionListDataModel.java @@ -0,0 +1,121 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.vfs.ui.version; + +import java.util.List; + +import org.olat.core.commons.persistence.SortKey; +import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiTableDataModel; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiSortableColumnDef; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel; +import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFlexiTableDataModel; +import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFlexiTableModelDelegate; +import org.olat.core.gui.translator.Translator; +import org.olat.core.util.StringHelper; + +/** + * + * Initial date: 19 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class RevisionListDataModel extends DefaultFlexiTableDataModel<RevisionRow> +implements SortableFlexiTableDataModel<RevisionRow> { + + private final Translator translator; + + public RevisionListDataModel(FlexiTableColumnModel columnModel, Translator translator) { + super(columnModel); + this.translator = translator; + } + + @Override + public void sort(SortKey orderBy) { + if(orderBy != null) { + List<RevisionRow> rows = new SortableFlexiTableModelDelegate<RevisionRow>(orderBy, this, translator.getLocale()).sort(); + super.setObjects(rows); + } + } + + @Override + public Object getValueAt(int row, int col) { + RevisionRow rev = getObject(row); + return getValueAt(rev, col); + } + + @Override + public Object getValueAt(RevisionRow row, int col) { + switch(RevisionCols.values()[col]) { + case id: return row.getKey(); + case nr: return row.getRevisionNr(); + case author: return row.getAuthor(); + case comment: { + String comment = row.getComment(); + if(!StringHelper.containsNonWhitespace(comment) && row.getRevisionNr() <= 1) { + comment = translator.translate("version.initialRevision"); + } + return comment; + } + case date: return row.getRevisionDate(); + case download: return row.getDownloadLink(); + case restore: + case delete: return Boolean.valueOf(!row.isCurrent()); + default: return "ERROR"; + } + } + + @Override + public RevisionListDataModel createCopyWithEmptyList() { + return new RevisionListDataModel(getTableColumnModel(), translator); + } + + public enum RevisionCols implements FlexiSortableColumnDef { + + id("table.header.id"), + nr("table.header.nr"), + author("table.header.author"), + comment("table.header.comment"), + date("table.header.date"), + download("download"), + restore("version.restore"), + delete("delete"); + + private final String i18nKey; + + private RevisionCols(String i18nKey) { + this.i18nKey = i18nKey; + } + + @Override + public String i18nHeaderKey() { + return i18nKey; + } + + @Override + public boolean sortable() { + return true; + } + + @Override + public String sortKey() { + return name(); + } + } +} diff --git a/src/main/java/org/olat/core/commons/services/vfs/ui/version/RevisionRow.java b/src/main/java/org/olat/core/commons/services/vfs/ui/version/RevisionRow.java new file mode 100644 index 0000000000000000000000000000000000000000..77c8ee2c785a866563b94815749880894fceaa8f --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/vfs/ui/version/RevisionRow.java @@ -0,0 +1,102 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.vfs.ui.version; + +import java.util.Date; + +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRevision; +import org.olat.core.gui.components.form.flexible.elements.DownloadLink; +import org.olat.core.id.Identity; +import org.olat.core.id.Persistable; + +/** + * + * Initial date: 19 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class RevisionRow { + + private boolean current; + + private int revisionNr; + private Identity author; + private String comment; + + private VFSRevision revision; + private VFSMetadata metadata; + private final DownloadLink downloadLink; + + public RevisionRow(VFSMetadata metadata, DownloadLink downloadLink) { + current = true; + this.metadata = metadata; + author = metadata.getAuthor(); + this.downloadLink = downloadLink; + } + + public RevisionRow(VFSRevision revision, DownloadLink downloadLink) { + current = false; + revisionNr = revision.getRevisionNr(); + author = revision.getAuthor(); + comment = revision.getRevisionComment(); + this.revision = revision; + this.downloadLink = downloadLink; + } + + public boolean isCurrent() { + return current; + } + + public void setCurrent(boolean current) { + this.current = current; + } + + public Long getKey() { + if(isCurrent()) { + return metadata.getKey(); + } + return revision instanceof Persistable ? ((Persistable)revision).getKey() : null; + } + + public int getRevisionNr() { + return current ? metadata.getRevisionNr() : revisionNr; + } + + public Identity getAuthor() { + return author; + } + + public String getComment() { + return comment; + } + + public Date getRevisionDate() { + return current ? metadata.getFileLastModified() : revision.getFileLastModified(); + } + + public VFSRevision getRevision() { + return revision; + } + + public DownloadLink getDownloadLink() { + return downloadLink; + } +} diff --git a/src/main/java/org/olat/admin/version/VersionAdminController.java b/src/main/java/org/olat/core/commons/services/vfs/ui/version/VersionAdminController.java similarity index 97% rename from src/main/java/org/olat/admin/version/VersionAdminController.java rename to src/main/java/org/olat/core/commons/services/vfs/ui/version/VersionAdminController.java index dc4ef0ee98e9ea51b7434d57fedba04203bce8e0..26d036de5cd93091ff77862021b90bed7875f413 100644 --- a/src/main/java/org/olat/admin/version/VersionAdminController.java +++ b/src/main/java/org/olat/core/commons/services/vfs/ui/version/VersionAdminController.java @@ -17,7 +17,7 @@ * frentix GmbH, http://www.frentix.com * <p> */ -package org.olat.admin.version; +package org.olat.core.commons.services.vfs.ui.version; import org.olat.admin.SystemAdminMainController; import org.olat.core.gui.UserRequest; diff --git a/src/main/java/org/olat/core/commons/modules/bc/version/VersionCommentController.java b/src/main/java/org/olat/core/commons/services/vfs/ui/version/VersionCommentController.java similarity index 98% rename from src/main/java/org/olat/core/commons/modules/bc/version/VersionCommentController.java rename to src/main/java/org/olat/core/commons/services/vfs/ui/version/VersionCommentController.java index 4db3d33c1223da7bf2f8fae6692ac6e6d1393467..83f14c7533cf13cbe2070741c7a0143a794499d0 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/version/VersionCommentController.java +++ b/src/main/java/org/olat/core/commons/services/vfs/ui/version/VersionCommentController.java @@ -17,7 +17,7 @@ * frentix GmbH, http://www.frentix.com * <p> */ -package org.olat.core.commons.modules.bc.version; +package org.olat.core.commons.services.vfs.ui.version; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItemContainer; diff --git a/src/main/java/org/olat/admin/version/VersionMaintenanceForm.java b/src/main/java/org/olat/core/commons/services/vfs/ui/version/VersionMaintenanceForm.java similarity index 86% rename from src/main/java/org/olat/admin/version/VersionMaintenanceForm.java rename to src/main/java/org/olat/core/commons/services/vfs/ui/version/VersionMaintenanceForm.java index af67f3dac6064c0f2e07f1540da1232a6aba2fed..efc41d49e02592cd32ba47d636382fd7cca0e3e9 100644 --- a/src/main/java/org/olat/admin/version/VersionMaintenanceForm.java +++ b/src/main/java/org/olat/core/commons/services/vfs/ui/version/VersionMaintenanceForm.java @@ -17,16 +17,16 @@ * frentix GmbH, http://www.frentix.com * <p> */ -package org.olat.admin.version; +package org.olat.core.commons.services.vfs.ui.version; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; -import java.util.List; import java.util.Locale; import org.olat.admin.SystemAdminMainController; -import org.olat.core.CoreSpringFactory; import org.olat.core.commons.services.taskexecutor.TaskExecutorManager; +import org.olat.core.commons.services.vfs.VFSRepositoryService; +import org.olat.core.commons.services.vfs.VFSVersionModule; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItemContainer; @@ -45,10 +45,7 @@ import org.olat.core.gui.control.generic.modal.DialogBoxController; import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory; import org.olat.core.util.Util; import org.olat.core.util.async.ProgressDelegate; -import org.olat.core.util.vfs.version.OrphanVersion; -import org.olat.core.util.vfs.version.SimpleVersionConfig; -import org.olat.core.util.vfs.version.VFSRevision; -import org.olat.core.util.vfs.version.VersionsManager; +import org.springframework.beans.factory.annotation.Autowired; /** * @@ -61,26 +58,26 @@ import org.olat.core.util.vfs.version.VersionsManager; * * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com */ - //fxdiff FXOLAT-127: file versions maintenance tool public class VersionMaintenanceForm extends FormBasicController implements ProgressDelegate { private FormLink cleanUpLink, pruneLink, showOrphanLink, orphanSize; private StaticTextElement orphanSizeEl; private CloseableModalController cmc; - private OrphanVersionsController orphansController; private DialogBoxController confirmPrunehistoryBox; private DialogBoxController confirmDeleteOrphansBox; private ProgressController progressCtrl; - private final VersionsManager versionsManager; - private final TaskExecutorManager taskExecutorManager; + @Autowired + private VFSVersionModule versionsModule; + @Autowired + private VFSRepositoryService versionsManager; + @Autowired + private TaskExecutorManager taskExecutorManager; public VersionMaintenanceForm(UserRequest ureq, WindowControl wControl) { super(ureq, wControl); // use combined translator from system admin main setTranslator(Util.createPackageTranslator(SystemAdminMainController.class, ureq.getLocale(), getTranslator())); - versionsManager = CoreSpringFactory.getImpl(VersionsManager.class); - taskExecutorManager = CoreSpringFactory.getImpl(TaskExecutorManager.class); initForm(ureq); } @@ -113,10 +110,10 @@ public class VersionMaintenanceForm extends FormBasicController implements Progr @Override protected void event(UserRequest ureq, Controller source, Event event) { - if(source == orphansController) { + /* if(source == orphansController) { cmc.deactivate(); cleanup(); - } else if(source == confirmDeleteOrphansBox) { + } else */ if(source == confirmDeleteOrphansBox) { if (DialogBoxUIFactory.isYesEvent(event)) { doDeleteOrphans(ureq); } @@ -131,9 +128,7 @@ public class VersionMaintenanceForm extends FormBasicController implements Progr } private void cleanup() { - removeAsListenerAndDispose(orphansController); removeAsListenerAndDispose(cmc); - orphansController = null; cmc = null; } @@ -145,11 +140,13 @@ public class VersionMaintenanceForm extends FormBasicController implements Progr @Override protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { if(source == showOrphanLink) { - List<OrphanVersion> orphans = versionsManager.orphans(); + /* + List<OrphanVersion> orphans = new ArrayList<>();//TODO metadata versions versionsManager.orphans(); orphansController = new OrphanVersionsController(ureq, getWindowControl(), orphans); listenTo(orphansController); cmc = new CloseableModalController(getWindowControl(), "close", orphansController.getInitialComponent()); cmc.activate(); + */ } else if(source == cleanUpLink) { String text = translate("confirm.delete.orphans"); confirmDeleteOrphansBox = activateYesNoDialog(ureq, null, text, confirmDeleteOrphansBox); @@ -179,7 +176,8 @@ public class VersionMaintenanceForm extends FormBasicController implements Progr taskExecutorManager.execute(new Runnable() { public void run() { waitASecond(); - versionsManager.deleteOrphans(VersionMaintenanceForm.this); + //TODO metadata versions + //versionsManager.deleteOrphans(VersionMaintenanceForm.this); } }); @@ -197,14 +195,16 @@ public class VersionMaintenanceForm extends FormBasicController implements Progr progressCtrl.setMessage(translate("version.prune.history")); progressCtrl.setPercentagesEnabled(false); progressCtrl.setUnitLabel(""); - progressCtrl.setMax(versionsManager.countDirectories()); + //TODO metadata versions + //progressCtrl.setMax(versionsManager.countDirectories()); listenTo(progressCtrl); taskExecutorManager.execute(new Runnable() { public void run() { waitASecond(); int numOfVersions = getNumOfVersions(); - versionsManager.pruneHistory(numOfVersions, VersionMaintenanceForm.this); + //TODO metadata versions + // versionsManager.pruneHistory(numOfVersions, VersionMaintenanceForm.this); } }); @@ -226,13 +226,14 @@ public class VersionMaintenanceForm extends FormBasicController implements Progr } public int getNumOfVersions() { - SimpleVersionConfig config = (SimpleVersionConfig) CoreSpringFactory.getBean(SimpleVersionConfig.class); - return config.getMaxNumberOfVersionsProperty(); + return versionsModule.getMaxNumberOfVersions(); } public final void calculateOrphanSize() { long size = 0l; - List<OrphanVersion> orphans = versionsManager.orphans(); + //TODO metadata versions + /* + List<OrphanVersion> orphans = new ArrayList<> ();//versionsManager.orphans(); for(OrphanVersion orphan:orphans) { List<VFSRevision> revisions = orphan.getVersions().getRevisions(); if(revisions != null) { @@ -241,6 +242,7 @@ public class VersionMaintenanceForm extends FormBasicController implements Progr } } } + */ String unit = "KB"; double humanSize = size / 1024.0d; diff --git a/src/main/java/org/olat/admin/version/VersionSettingsForm.java b/src/main/java/org/olat/core/commons/services/vfs/ui/version/VersionSettingsForm.java similarity index 89% rename from src/main/java/org/olat/admin/version/VersionSettingsForm.java rename to src/main/java/org/olat/core/commons/services/vfs/ui/version/VersionSettingsForm.java index 69dac4b6af731196061717160b43e71c74ce8c38..ad7770410a8179ba2dc887028ed0c61fc7f0200f 100644 --- a/src/main/java/org/olat/admin/version/VersionSettingsForm.java +++ b/src/main/java/org/olat/core/commons/services/vfs/ui/version/VersionSettingsForm.java @@ -17,10 +17,10 @@ * frentix GmbH, http://www.frentix.com * <p> */ -package org.olat.admin.version; +package org.olat.core.commons.services.vfs.ui.version; import org.olat.admin.SystemAdminMainController; -import org.olat.core.CoreSpringFactory; +import org.olat.core.commons.services.vfs.VFSVersionModule; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItemContainer; import org.olat.core.gui.components.form.flexible.elements.SingleSelection; @@ -30,7 +30,7 @@ import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.WindowControl; import org.olat.core.util.Util; -import org.olat.core.util.vfs.version.SimpleVersionConfig; +import org.springframework.beans.factory.annotation.Autowired; /** * @@ -43,7 +43,6 @@ import org.olat.core.util.vfs.version.SimpleVersionConfig; * * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com */ -//fxdiff FXOLAT-127: file versions maintenance tool public class VersionSettingsForm extends FormBasicController { private SingleSelection numOfVersions; @@ -55,6 +54,9 @@ public class VersionSettingsForm extends FormBasicController { private String[] values = new String[] { "0","2","3","4","5","10","25","50","-1" }; + + @Autowired + private VFSVersionModule versionsModule; public VersionSettingsForm(UserRequest ureq, WindowControl wControl) { super(ureq, wControl); @@ -125,12 +127,10 @@ public class VersionSettingsForm extends FormBasicController { } public int getNumOfVersions() { - SimpleVersionConfig config = CoreSpringFactory.getImpl(SimpleVersionConfig.class); - return config.getMaxNumberOfVersionsProperty(); + return versionsModule.getMaxNumberOfVersions(); } public void setNumOfVersions(int maxNumber) { - SimpleVersionConfig config = (SimpleVersionConfig) CoreSpringFactory.getBean(SimpleVersionConfig.class); - config.setMaxNumberOfVersionsProperty(maxNumber); + versionsModule.setMaxNumberOfVersions(maxNumber); } } diff --git a/src/main/java/org/olat/admin/version/_content/admin.html b/src/main/java/org/olat/core/commons/services/vfs/ui/version/_content/admin.html similarity index 100% rename from src/main/java/org/olat/admin/version/_content/admin.html rename to src/main/java/org/olat/core/commons/services/vfs/ui/version/_content/admin.html diff --git a/src/main/java/org/olat/core/commons/services/vfs/ui/version/_content/deleted_files.html b/src/main/java/org/olat/core/commons/services/vfs/ui/version/_content/deleted_files.html new file mode 100644 index 0000000000000000000000000000000000000000..633452cabb3cc5568bc14b6cb542d9b5441efa23 --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/vfs/ui/version/_content/deleted_files.html @@ -0,0 +1,10 @@ +$r.render("table") +<div class="o_button_group"> + $r.render("cancel") + #if($r.available("version.restore")) + $r.render("version.restore") + #end + #if($r.available("delete")) + $r.render("delete") + #end +</div> \ No newline at end of file diff --git a/src/main/java/org/olat/core/commons/modules/bc/version/_content/revisions.html b/src/main/java/org/olat/core/commons/services/vfs/ui/version/_content/revisions.html similarity index 55% rename from src/main/java/org/olat/core/commons/modules/bc/version/_content/revisions.html rename to src/main/java/org/olat/core/commons/services/vfs/ui/version/_content/revisions.html index cf46480a75b14198b8676913f93d6399a5d78f75..a186da0e3442b3d7fc4dae564d99b08856fcb814 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/version/_content/revisions.html +++ b/src/main/java/org/olat/core/commons/services/vfs/ui/version/_content/revisions.html @@ -4,4 +4,7 @@ #if ($description) <p class="o_info">$description</p> #end -$r.render("revisionList") \ No newline at end of file +$r.render("table") +<div class="o_button_group"> + $r.render("cancel") +</div> \ No newline at end of file diff --git a/src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_ar.properties b/src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_ar.properties similarity index 73% rename from src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_ar.properties rename to src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_ar.properties index 51ad38e5a05215c83f921baae510cbde3bb2b39a..bca4ce4026d6e0239a75ae3a32f08e533c543601 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_ar.properties +++ b/src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_ar.properties @@ -1,4 +1,17 @@ -#Mon Feb 15 09:33:55 CET 2010 +#Mon Feb 22 14:19:03 CET 2010 + + + + + +form.version=\u0627\u0644\u0625\u0635\u062F\u0627\u0631\u0627\u062A + +version.intro=\u064A\u0631\u062C\u0649 \u0648\u0636\u0639 \u0627\u0644\u0639\u062F\u062F \u0627\u0644\u0623\u0642\u0635\u0649 \u0645\u0646 \u0627\u0644\u0625\u0635\u062F\u0627\u0631\u0627\u062A \u0641\u0649 \u0627\u0644\u0645\u062C\u0644\u062F (\u0645\u062C\u0644\u062F \u0627\u0644\u0645\u062C\u0645\u0648\u0639\u0629\u060C \u0645\u062C\u0644\u062F \u0627\u0644\u0645\u0642\u0631\u0631\u060C \u0625\u0627\u0644\u062E). +version.notANumber=\u0644\u0645 \u064A\u062A\u0645 \u062A\u062D\u062F\u064A\u062F \u0631\u0642\u0645 +version.numOfVersions=\u0631\u0642\u0645 \u0627\u0644\u0625\u0635\u062F\u0627\u0631\u0627\u062A +version.off=\u062A\u0639\u0637\u064A\u0644 \u0627\u0644\u0625\u0635\u062F\u0627\u0631\u0627\u062A +version.title=\u0627\u0644\u0625\u0635\u062F\u0627\u0631\u0627\u062A +version.unlimited=\u063A\u064A\u0631 \u0645\u062D\u062F\u0648\u062F meta.comment.title=\u0625\u063A\u0644\u0627\u0642 meta.locked=\u0627\u0644\u0645\u0644\u0641 \u0645\u063A\u0644\u0642 meta.retainlock=\u0645\u062A\u0627\u0628\u0639\u0629 \u0625\u063A\u0644\u0627\u0642 \u0627\u0644\u0645\u0644\u0641 \u0639\u0646 \u0627\u0644\u0645\u0633\u062A\u062E\u062F\u0645\u064A\u0646 \u0627\u0644\u0623\u062E\u0631\u064A\u064A\u0646 @@ -23,3 +36,4 @@ version.nr=\u0645\u0631\u0627\u062C\u0639\u0629 version.restore=\u0627\u0633\u062A\u0631\u062C\u0627\u0639 version.restore.comment={0} \u062A\u0645 \u0627\u0633\u062A\u0631\u062C\u0627\u0639 \u0627\u0644\u0625\u0635\u062F\u0627\u0631 version.restore.failed=\u0644\u0627 \u064A\u0645\u0643\u0646 \u0627\u0633\u062A\u0639\u0627\u062F\u0629 \u0627\u0644\u0645\u0644\u0641. + diff --git a/src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_de.properties new file mode 100644 index 0000000000000000000000000000000000000000..99ea6277d072b6984e7a2c9884624b159a591f5e --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_de.properties @@ -0,0 +1,60 @@ +#Mon Mar 02 09:54:03 CET 2009 +form.version=Versionierung +version.intro=Stellen Sie die maximale Anzahl von Versionen f\u00fcr eine Datei einer Ordnerkomponente (Gruppenordner, Kursordner etc.) ein. +version.title=Versionierung +version.numOfVersions=Anzahl Versionen +version.notANumber=Keine Zahl gew\u00e4hlt +version.unlimited=Unlimitiert +version.off=Versionierung ausgeschaltet +version.clean.up=Orphan Versionen l\u00f6schen +version.orphan.size=Orphan Versionen Gr\u00f6sse +version.orphan.size.calc=Gr\u00f6sse rechnen +version.orphan.size.calculating=Gr\u00f6sse am rechnen... +version.show.orphans=Orphan Versionen auflisten +version.prune.history=Versionen aufr\u00e4umen +version.maintenance.title=Verwaltung +version.maintenance.intro=Verwaltung von Versionen +table.header.file=Datei +table.header.versions=Anzhal Versionen +table.header.size=Gr\u00f6sse +table.empty=Keine orphan Versionen \u00fcbrig +table.header.author=Autor +table.header.comment=Kommentar +table.header.date=Datum +download=Herunterladen +table.header.id=Id +version.name=Datei +version.noDeletedFiles=Es gibt keine gel\u00F6schten Dateien unter der Dokument-Kontrolle. +version.noRevisions=Es gibt noch keine Revision dieser Datei. +table.header.nr=Revision +version.initialRevision=Initiale Version +version.restore=Wiederherstellen +version.confirmDelete=Wollen Sie wirklich {0} Revision(en) l\u00F6schen? +dx=dr +confirm.delete.orphans=Wollen Sie wirklich alle Orphan Versionen l\u00f6schen? +confirm.prune.history=Wollen Sie wirklich die \u00fcberfl\u00fcssige Versionen l\u00f6schen? +version.author=Autor +version.comment=Kommentar +version.date=Datum +version.deletedBy=Gel\u00F6scht von +version.deletedFiles=Gel\u00F6schte Dateien +version.download=Herunterladen +version.name=Datei +version.noDeletedFiles=Es gibt keine gel\u00F6schten Dateien unter der Dokument-Kontrolle. +version.noRevisions=Es gibt noch keine Revision dieser Datei. +version.nr=Revision +version.initialRevision=Initiale Version +version.restore=Wiederherstellen +version.confirmDelete=Wollen Sie wirklich {0} Revision(en) l\u00F6schen? +version.comment=Kommentar +version.comment.title=Kommentar +version.comment.alltitle=Kommentar / Sperre +version.comment.description=Dieses Dokument steht unter Dokument-Kontrolle. Bitte kommentieren Sie die gemachten \u00c4nderungen. +version.del.confirm=Wollen Sie folgende Dateien wirklich endg\u00FCltig l\u00F6schen? +version.del.header=L\u00F6schen best\u00E4tigen +version.restore.failed=Datei konnte nicht wiederhergestellt werden. +version.restore.comment=Version {0} wiederhergestellt +meta.comment.title=Sperre +meta.locked=Dateisperre +meta.retainlock=Die Datei f\u00FCr andere Benutzer gesperrt lassen +meta.unlock=Die Datei f\u00FCr andere Benutzer frei geben diff --git a/src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_el.properties b/src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_el.properties similarity index 74% rename from src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_el.properties rename to src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_el.properties index 9f17c8a7cd302d865de57dd18cd2395f0b22c807..f3e56e5911a0dda68cb29f31cda6a5bd2517f66d 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_el.properties +++ b/src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_el.properties @@ -1,4 +1,5 @@ -#Thu Mar 11 13:39:32 CET 2010 +#Fri Mar 12 16:12:40 CET 2010 +form.version=\u0395\u03BA\u03B4\u03CC\u03C3\u03B5\u03B9\u03C2 meta.comment.title=\u039A\u03BB\u03B5\u03AF\u03B4\u03C9\u03BC\u03B1 meta.locked=\u0391\u03C1\u03C7\u03B5\u03AF\u03BF \u03BA\u03BB\u03B5\u03B9\u03B4\u03C9\u03BC\u03AD\u03BD\u03BF meta.retainlock=\u03A3\u03C5\u03BD\u03AD\u03C7\u03B5\u03B9\u03B1 \u03BA\u03BB\u03B5\u03B9\u03B4\u03CE\u03BC\u03B1\u03C4\u03BF\u03C2 \u03C4\u03BF\u03C5 \u03B1\u03C1\u03C7\u03B5\u03AF\u03BF\u03C5 \u03B3\u03B9\u03B1 \u03C4\u03BF\u03C5\u03C2 \u03AC\u03BB\u03BB\u03BF\u03C5\u03C2 \u03C7\u03C1\u03AE\u03C3\u03C4\u03B5\u03C2 @@ -23,3 +24,9 @@ version.nr=\u0391\u03BD\u03B1\u03B8\u03B5\u03CE\u03C1\u03B7\u03C3\u03B7 version.restore=\u0391\u03C0\u03BF\u03BA\u03B1\u03C4\u03AC\u03C3\u03C4\u03B1\u03C3\u03B7 version.restore.comment=\u0388\u03BA\u03B4\u03BF\u03C3\u03B7 {0} \u03B1\u03C0\u03BF\u03BA\u03B1\u03C4\u03B1\u03C3\u03C4\u03AC\u03B8\u03B7\u03BA\u03B5 version.restore.failed=\u03A4\u03BF \u03B1\u03C1\u03C7\u03B5\u03AF\u03BF \u03B4\u03B5\u03BD \u03B8\u03B1 \u03BC\u03C0\u03BF\u03C1\u03BF\u03CD\u03C3\u03B5 \u03BD\u03B1 \u03B1\u03C0\u03BF\u03BA\u03B1\u03C4\u03B1\u03C3\u03C4\u03B1\u03B8\u03B5\u03AF. +version.intro=\u03A0\u03B1\u03C1\u03B1\u03BA\u03B1\u03BB\u03CE \u03C1\u03C5\u03B8\u03BC\u03AF\u03C3\u03C4\u03B5 \u03C4\u03BF \u03BC\u03AD\u03B3\u03B9\u03C3\u03C4\u03BF \u03B1\u03C1\u03B9\u03B8\u03BC\u03CC \u03C4\u03C9\u03BD \u03B5\u03BA\u03B4\u03CC\u03C3\u03B5\u03C9\u03BD \u03B3\u03B9\u03B1 \u03AD\u03BD\u03B1 \u03C3\u03C4\u03BF\u03B9\u03C7\u03B5\u03AF\u03BF \u03C4\u03BF\u03C5 \u03C6\u03B1\u03BA\u03AD\u03BB\u03BF\u03C5 (\u03C6\u03AC\u03BA\u03B5\u03BB\u03BF\u03C2 \u03BF\u03BC\u03AC\u03B4\u03B1\u03C2, \u03C6\u03AC\u03BA\u03B5\u03BB\u03BF\u03C2 \u03BC\u03B1\u03B8\u03AE\u03BC\u03B1\u03C4\u03BF\u03C2 \u03BA\u03C4\u03BB.) +version.notANumber=\u0394\u03B5\u03BD \u03B5\u03C0\u03B9\u03BB\u03AD\u03C7\u03B8\u03B7\u03BA\u03B5 \u03B1\u03C1\u03B9\u03B8\u03BC\u03CC\u03C2 +version.numOfVersions=\u0391\u03C1\u03B9\u03B8\u03BC\u03CC\u03C2 \u03B5\u03BA\u03B4\u03CC\u03C3\u03B5\u03C9\u03BD +version.off=\u039F\u03B9 \u03B5\u03BA\u03B4\u03CC\u03C3\u03B5\u03B9\u03C2 \u03AD\u03C7\u03BF\u03C5\u03BD \u03B1\u03C0\u03B5\u03BD\u03B5\u03C1\u03B3\u03BF\u03C0\u03BF\u03B9\u03B7\u03B8\u03B5\u03AF +version.title=\u0395\u03BA\u03B4\u03CC\u03C3\u03B5\u03B9\u03C2 +version.unlimited=\u0391\u03C0\u03B5\u03C1\u03B9\u03CC\u03C1\u03B9\u03C3\u03C4\u03BF\u03C2 diff --git a/src/main/java/org/olat/admin/version/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_en.properties similarity index 50% rename from src/main/java/org/olat/admin/version/_i18n/LocalStrings_en.properties rename to src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_en.properties index 67a8beefbd7fbc189741283a92f8d75ab1d80c7e..3c999ef2934e55acb7345ffdf1ba6602d37e3126 100644 --- a/src/main/java/org/olat/admin/version/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_en.properties @@ -1,15 +1,31 @@ #Tue Dec 18 22:46:41 CET 2012 - - - - - - - confirm.delete.orphans=Do you really want to delete all orphan versions? confirm.prune.history=Do you really want to delete all versions that exceed the configured version limit? form.version=Versioning - +meta.comment.title=Lock +meta.locked=File locked +meta.retainlock=Continue locking of file for other users +meta.unlock=Unlock file for other users +version.author=Author +version.comment=Comment +version.comment.alltitle=Comment/lock +version.comment.description=Changes are tracked in this document. Please comment your modifications. +version.comment.title=Comment +version.confirmDelete=Do you really want to delete {0} revision(s)? +version.date=Date +version.del.confirm=Do you really want to delete the following files for good? +version.del.header=Confirm deletion +version.deletedBy=Deleted by +version.deletedFiles=Deleted files +version.download=Download +version.initialRevision=Initial version +version.name=File +version.noDeletedFiles=There are no deleted files with a change log. +version.noRevisions=There are no revisions of this file yet. +version.nr=Revision +version.restore=Restore +version.restore.comment=Version {0} restored +version.restore.failed=File could not be restored. table.empty=No orphan version left table.header.file=File table.header.size=Size diff --git a/src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_fr.properties similarity index 51% rename from src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_fr.properties rename to src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_fr.properties index fc353b3b3354542293313783c729d04bb4dc2064..43afa6031d06ded34ae8bc83939750d9109b6e1d 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_fr.properties @@ -1,4 +1,8 @@ -#Mon Feb 08 13:20:57 CET 2010 +#Sat Nov 02 20:59:58 CET 2013 + +confirm.delete.orphans=Voulez-vous vraiment effacer toutes les versions orphelines? +confirm.prune.history=Voulez-vous vraiment effacer toutes les versions qui d\u00E9passent la limite configur\u00E9e? +form.version=V\u00E9rification des version meta.comment.title=Blocage meta.locked=Blocage fichier meta.retainlock=Maintenir le blocage du fichier pour d'autres utilisateurs @@ -23,3 +27,22 @@ version.nr=R\u00E9vision version.restore=Restaurer version.restore.comment=Version {0} restaur\u00E9e version.restore.failed=Le fichier n'a pas pu \u00EAtre restaur\u00E9. + +table.empty=Aucune version orpheline ne reste +table.header.file=Fichier +table.header.size=Taille +table.header.versions=Nombre de versions +version.clean.up=Supprimer les versions orphelines +version.intro=Etablir le nombre maximal de versions pour un fichier d'un dossier (dossier de groupe, dossier de cours etc.). +version.maintenance.intro=Administration des versions +version.maintenance.title=Administration +version.notANumber=Aucun nombre choisi +version.numOfVersions=Nombre de versions +version.off=V\u00E9rification des versions d\u00E9sactiv\u00E9s +version.orphan.size=Taille des versions orphelines +version.orphan.size.calc=Calculer la taille +version.orphan.size.calculating=Taille en cours de calcul +version.prune.history=Nettoyer les versions +version.show.orphans=Liste des versions orphelines +version.title=V\u00E9rification des versions +version.unlimited=Illimit\u00E9 diff --git a/src/main/java/org/olat/admin/version/_i18n/LocalStrings_it.properties b/src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_it.properties similarity index 50% rename from src/main/java/org/olat/admin/version/_i18n/LocalStrings_it.properties rename to src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_it.properties index ae5ba0f4d95db0e99e08df301f41cbec34f9e3b5..c452e4adf1a545ad3d6766d6afeb0de7e8731456 100644 --- a/src/main/java/org/olat/admin/version/_i18n/LocalStrings_it.properties +++ b/src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_it.properties @@ -1,4 +1,29 @@ #Mon Feb 13 14:15:30 CET 2017 +meta.comment.title=Bloccaggio +meta.locked=Bloccaggio file +meta.retainlock=Mantenere bloccato il file per altri utenti +meta.unlock=Sbloccare il file per altri utenti +version.author=Autore +version.comment=Commento +version.comment.alltitle=Commento / Bloccaggio +version.comment.description=Le modifiche a questo documento vengono registrate. Commenti le Sue modifiche, p.f. +version.comment.title=Commento +version.confirmDelete=Desidera veramente eliminare {0} revisione/i? +version.date=Data +version.del.confirm=Desidera veramente eliminare definitivamente questi file? +version.del.header=Confermare eliminazione +version.deletedBy=Eliminato da +version.deletedFiles=File eliminati +version.download=Scaricare +version.initialRevision=Versione iniziale +version.name=File +version.noDeletedFiles=Non ci sono file eliminati che avevano modifiche registrate. +version.noRevisions=Non ci sono ancora revisioni di questo file. +version.nr=Revisione +version.restore=Recuperare +version.restore.comment=Versione {0} recuperata +version.restore.failed=Il file non pu\u00F2 essere recuperato. + confirm.delete.orphans=Vuoi veramente eliminare tutte le versioni orfane? confirm.prune.history=Vuoi veramente eliminare tutte le versioni che eccedono il limite di versione configurato? form.version=Controllo delle versioni diff --git a/src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_jp.properties b/src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_jp.properties similarity index 75% rename from src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_jp.properties rename to src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_jp.properties index 9cd24cfa9232c3db4bd9f8c317cdade6794c1ee2..1d97958702f8e247db20d3c807c521a41f007498 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_jp.properties +++ b/src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_jp.properties @@ -1,4 +1,5 @@ -#Fri Apr 09 21:02:51 CEST 2010 +#Thu Sep 23 20:31:41 CEST 2010 +form.version=\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0 meta.comment.title=\u30ED\u30C3\u30AF meta.locked=\u30D5\u30A1\u30A4\u30EB\u304C\u30ED\u30C3\u30AF\u3055\u308C\u307E\u3057\u305F\u3002 meta.retainlock=\u4ED6\u306E\u30E6\u30FC\u30B6\u306B\u5BFE\u3057\u3066\u3001\u30D5\u30A1\u30A4\u30EB\u30ED\u30C3\u30AF\u3092\u7D9A\u3051\u308B @@ -23,3 +24,9 @@ version.nr=\u30EA\u30D3\u30B8\u30E7\u30F3 version.restore=\u30EA\u30B9\u30C8\u30A2 version.restore.comment=\u30D0\u30FC\u30B8\u30E7\u30F3 {0} \u304C\u30EA\u30B9\u30C8\u30A2\u3055\u308C\u307E\u3057\u305F\u3002 version.restore.failed=\u30D5\u30A1\u30A4\u30EB\u3092\u30EA\u30B9\u30C8\u30A2\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002 +version.intro=\u30D5\u30A9\u30EB\u30C0\u69CB\u6210\u30D5\u30A1\u30A4\u30EB (\u30B0\u30EB\u30FC\u30D7\u30D5\u30A9\u30EB\u30C0\u3001\u30B3\u30FC\u30B9\u30D5\u30A9\u30EB\u30C0\u7B49) \u306E\u6700\u5927\u30D0\u30FC\u30B8\u30E7\u30F3\u6570\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002 +version.notANumber=\u6570\u304C\u9078\u629E\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002 +version.numOfVersions=\u30D0\u30FC\u30B8\u30E7\u30F3\u6570 +version.off=\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0\u7121\u52B9 +version.title=\u30D0\u30FC\u30B8\u30E7\u30CB\u30F3\u30B0 +version.unlimited=\u7121\u5236\u9650 diff --git a/src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_nl_NL.properties b/src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_nl_NL.properties similarity index 76% rename from src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_nl_NL.properties rename to src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_nl_NL.properties index 146f381d62aa846fa471dd91d161e759d3947699..b21ac99ae65f2d26da5100f5ffa4837498bd2a8b 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_nl_NL.properties +++ b/src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_nl_NL.properties @@ -1,4 +1,5 @@ -#Thu Feb 04 13:41:35 CET 2010 +#Thu Sep 08 16:42:42 CEST 2011 +form.version=Versionering meta.comment.title=Vergrendeld meta.locked=Bestand vergrendeld meta.retainlock=Bestand vergrendeld laten voor andere gebruikers @@ -23,3 +24,9 @@ version.nr=Revisie version.restore=Terugzetten version.restore.comment=versie {0} teruggezet. version.restore.failed=Bestand kon niet worden teruggezet. +version.intro=Gelieve het maximum aantal versies voor een maponderdeel in te stellen (groepmap, cursusmap, etc.). +version.notANumber=Geen nummer geselecteerd +version.numOfVersions=Aantal versies +version.off=Versionering gedeactiveerd +version.title=Versionering +version.unlimited=Ongelimiteerd diff --git a/src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_pl.properties b/src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_pl.properties similarity index 65% rename from src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_pl.properties rename to src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_pl.properties index 5c03da2ee25226df383768e8cdf5255c9dee1618..9ee4917d56a1e4fa6ee3b6932a1b423c6c27162b 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_pl.properties +++ b/src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_pl.properties @@ -1,4 +1,5 @@ -#Mon Feb 15 01:13:42 CET 2010 +#Sun Dec 23 19:39:03 CET 2012 +form.version=Wersjonowanie meta.comment.title=Blokada meta.locked=Plik zablokowany meta.retainlock=Kontynuuj blokowanie pliku dla innych u\u017Cytkownik\u00F3w @@ -23,3 +24,16 @@ version.nr=Edycja version.restore=Przywr\u00F3\u0107 version.restore.comment=Wersja {0} zosta\u0142a przywr\u00F3cona version.restore.failed=Plik nie mo\u017Ce zosta\u0107 przywr\u00F3cony. +table.header.file=Plik +table.header.size=Rozmiar +table.header.versions=Liczba wersji +version.intro=Podaj maksymaln\u0105 liczb\u0119 wersji dla folder\u00F3w (folder grupy, folder kursu, itd.). +version.maintenance.intro=Zarz\u0105dzanie wersjami +version.maintenance.title=Zarz\u0105dzanie +version.notANumber=Nie wybrano liczby +version.numOfVersions=Liczba wersji +version.off=Wersjonowanie wy\u0142\u0105czone +version.orphan.size.calc=Oblicz rozmiar +version.orphan.size.calculating=Trwa obliczanie... +version.title=Wersjonowanie +version.unlimited=Brak limitu diff --git a/src/main/java/org/olat/admin/version/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_pt_BR.properties similarity index 50% rename from src/main/java/org/olat/admin/version/_i18n/LocalStrings_pt_BR.properties rename to src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_pt_BR.properties index 6cd0d455d9b63b3bcc7937c21436066abc318e98..51d5284f3472840b31f2499d2227fe56267cf4e3 100644 --- a/src/main/java/org/olat/admin/version/_i18n/LocalStrings_pt_BR.properties +++ b/src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_pt_BR.properties @@ -1,15 +1,31 @@ #Fri Sep 06 17:41:15 CEST 2013 - - - - - - - confirm.delete.orphans=Voc\u00EA realmente quer apagar todas as vers\u00F5es \u00F3rf\u00E3s? confirm.prune.history=Voc\u00EA realmente quer apagar todas as vers\u00F5es que excedam o limite da vers\u00E3o configurada? form.version=Controle de Vers\u00E3o - +meta.comment.title=Bloquear +meta.locked=Arquivo bloqueado +meta.retainlock=Continue bloqueio de arquivo para outros usu\u00E1rios +meta.unlock=Desbloquear arquivo para outros usu\u00E1rios +version.author=Autor +version.comment=Coment\u00E1rio +version.comment.alltitle=Comentar/Bloquear +version.comment.description=As altera\u00E7\u00F5es s\u00E3o controladas neste documento. Por favor, comente suas modifica\u00E7\u00F5es. +version.comment.title=Comente +version.confirmDelete=Voc\u00EA realmente quer apagar {0} revis\u00E3o(\u00F5es)? +version.date=Data +version.del.confirm=Voc\u00EA realmente quer excluir os seguintes arquivos? +version.del.header=Confirme exclus\u00E3o +version.deletedBy=Exclu\u00EDdo por +version.deletedFiles=Arquivos exclu\u00EDdos +version.download=Baixar +version.initialRevision=Vers\u00E3o inicial +version.name=Arquivo +version.noDeletedFiles=N\u00E3o existem arquivos exclu\u00EDdos com um registo de altera\u00E7\u00F5es. +version.noRevisions=N\u00E3o h\u00E1 revis\u00F5es deste arquivo ainda. +version.nr=Revis\u00E3o +version.restore=Restaurar +version.restore.comment=Vers\u00E3o {0} restaurada +version.restore.failed=Arquivo n\u00E3o p\u00F4de ser restaurado. table.empty=Nenhuma vers\u00E3o \u00F3rf\u00E3 table.header.file=Arquivo table.header.size=Tamanho diff --git a/src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_ru.properties b/src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_ru.properties similarity index 100% rename from src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_ru.properties rename to src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_ru.properties diff --git a/src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_zh_CN.properties b/src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_zh_CN.properties similarity index 61% rename from src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_zh_CN.properties rename to src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_zh_CN.properties index d4ed25ce83436acbe8598d8b5d66debf40d111ec..6ba1098fba43a61a62e3c0255c6b545943494ae5 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_zh_CN.properties +++ b/src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_zh_CN.properties @@ -1,4 +1,5 @@ -#Sun Feb 07 10:37:58 CET 2010 +#Mon Nov 10 00:41:46 CET 2014 +form.version=\u7248\u672C meta.comment.title=\u9501\u5B9A meta.locked=\u6587\u4EF6\u9501\u5B9A meta.retainlock=\u7EE7\u7EED\u4E3A\u5176\u4ED6\u7528\u6237\u9501\u5B9A\u6587\u4EF6 @@ -23,3 +24,18 @@ version.nr=\u4FEE\u8BA2 version.restore=\u91CD\u65B0\u4FDD\u5B58 version.restore.comment=\u7248\u672C{0}\u5DF2\u88AB\u91CD\u65B0\u4FDD\u5B58 version.restore.failed=\u6587\u4EF6\u4E0D\u80FD\u88AB\u91CD\u65B0\u4FDD\u5B58\u3002 + +version.clean.up=\u5220\u9664Orphan\u7248\u672C +version.intro=\u8BF7\u4E3A\u7EC4\u6210\u6587\u4EF6\u5939\uFF08\u7FA4\u7EC4\u6587\u4EF6\u5939\uFF0C\u5B66\u7A0B\u6587\u4EF6\u5939\uFF0C\u7B49\uFF09\u7684\u6587\u4EF6\u8BBE\u7F6E\u7248\u672C\u7684\u6700\u5927\u6570\u76EE\u3002 +version.maintenance.intro=\u7248\u672C\u7BA1\u7406 +version.maintenance.title=\u7BA1\u7406 +version.notANumber=\u672A\u9009\u62E9\u4EFB\u4F55\u6570\u5B57 +version.numOfVersions=\u7248\u672C\u7684\u6570\u76EE +version.off=\u5DF2\u5173\u95ED\u7248\u672C +version.orphan.size=Orphan\u7248\u672C\u5927\u5C0F +version.orphan.size.calc=\u5927\u5C0F\u8BA1\u7B97 +version.orphan.size.calculating=\u6B63\u5728\u8BA1\u7B97\u5927\u5C0F +version.prune.history=\u7248\u672C\u6E05\u7406 +version.show.orphans=\u5217\u51FAOrphan\u7248\u672C +version.title=\u7248\u672C +version.unlimited=\u65E0\u9650 diff --git a/src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_zh_TW.properties b/src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_zh_TW.properties similarity index 73% rename from src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_zh_TW.properties rename to src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_zh_TW.properties index 470d5f9f9f777f777a11792108d9f1fee4b73623..7cef5bd910f95ab3438dce3ba8c5d6df74013890 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/version/_i18n/LocalStrings_zh_TW.properties +++ b/src/main/java/org/olat/core/commons/services/vfs/ui/version/_i18n/LocalStrings_zh_TW.properties @@ -1,4 +1,5 @@ -#Sun Jan 24 11:40:40 CET 2010 +#Sat Sep 18 15:10:48 CEST 2010 +form.version=\u7248\u672C meta.comment.title=\u9396\u5B9A meta.locked=\u6A94\u6848\u88AB\u9396\u5B9A meta.retainlock=\u7E7C\u7E8C\u5C0D\u5176\u4ED6\u4F7F\u7528\u8005\u9396\u5B9A\u6A94\u6848 @@ -23,3 +24,9 @@ version.nr=\u4FEE\u8A02 version.restore=\u56DE\u5B58 version.restore.comment=\u7248\u672C {0} \u56DE\u5B58 version.restore.failed=\u6A94\u6848\u7121\u6CD5\u88AB\u56DE\u5B58\u3002 +version.intro=\u8ACB\u8A2D\u5B9A\u8CC7\u6599\u593E\u7D44\u6210\u7684\u6A94\u6848\uFF08\u5B58\u53D6\u8CC7\u6599\u593E\u3001\u8AB2\u7A0B\u8CC7\u6599\u593E\uFF0C\u7B49\uFF09\u7684\u6700\u5927\u7248\u672C\u6578\u3002 +version.notANumber=\u672A\u9078\u64C7\u4EFB\u4F55\u6578\u5B57 +version.numOfVersions=\u7248\u672C\u6578 +version.off=\u505C\u7528\u7248\u672C\u63A7\u5236 +version.title=\u7248\u672C +version.unlimited=\u7121\u9650 diff --git a/src/main/java/org/olat/core/commons/services/webdav/manager/VFSResourceRoot.java b/src/main/java/org/olat/core/commons/services/webdav/manager/VFSResourceRoot.java index c63fbe62ded5c1c34bc5852a5cdde4934518720f..cda6761701896b5d31b1450361840b03ac4e0184 100644 --- a/src/main/java/org/olat/core/commons/services/webdav/manager/VFSResourceRoot.java +++ b/src/main/java/org/olat/core/commons/services/webdav/manager/VFSResourceRoot.java @@ -49,8 +49,6 @@ import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSManager; import org.olat.core.util.vfs.VFSStatus; import org.olat.core.util.vfs.callbacks.VFSSecurityCallback; -import org.olat.core.util.vfs.version.Versionable; -import org.olat.core.util.vfs.version.VersionsManager; /** @@ -173,11 +171,11 @@ public class VFSResourceRoot implements WebResourceRoot { childLeaf = (VFSLeaf)file; //versioning - if(childLeaf instanceof Versionable && ((Versionable)childLeaf).getVersions().isVersioned()) { - if(childLeaf.getSize() == 0) { - CoreSpringFactory.getImpl(VersionsManager.class).createVersionsFor(childLeaf, true); - } else { - CoreSpringFactory.getImpl(VersionsManager.class).addToRevisions((Versionable)childLeaf, identity, ""); + if(childLeaf.canVersion() == VFSConstants.YES) { + try(InputStream in=childLeaf.getInputStream()) { + CoreSpringFactory.getImpl(VFSRepositoryService.class).addVersion(childLeaf, identity, "", in); + } catch(IOException e) { + log.error("", e); } } } else { @@ -223,35 +221,28 @@ public class VFSResourceRoot implements WebResourceRoot { } if(identity != null && childLeaf.canMeta() == VFSConstants.YES) { - VFSMetadata infos = childLeaf.getMetaInfo(); - if(infos != null && infos.getAuthor() != null) { - infos.setAuthor(identity); - addLicense(infos, identity); - - VFSRepositoryService vfsRepositoryService = CoreSpringFactory.getImpl(VFSRepositoryService.class); - vfsRepositoryService.updateMetadata(infos); - vfsRepositoryService.resetThumbnails(childLeaf); - } - } - - if(movedFrom instanceof VFSResource) { - VFSResource vfsResource = (VFSResource)movedFrom; - if(vfsResource.getItem() instanceof Versionable - && ((Versionable)vfsResource.getItem()).getVersions().isVersioned()) { - VFSLeaf currentVersion = (VFSLeaf)vfsResource.getItem(); - CoreSpringFactory.getImpl(VersionsManager.class).move(currentVersion, childLeaf, identity); + VFSRepositoryService vfsRepositoryService = CoreSpringFactory.getImpl(VFSRepositoryService.class); + VFSMetadata metadata; + if(movedFrom instanceof VFSResource && ((VFSResource)movedFrom).getItem() instanceof VFSLeaf) { + VFSLeaf from = (VFSLeaf)((VFSResource)movedFrom).getItem(); + metadata = CoreSpringFactory.getImpl(VFSRepositoryService.class).move(from, childLeaf, identity); + } else { + metadata = vfsRepositoryService.getMetadataFor(childLeaf); + metadata.setAuthor(identity); + metadata = vfsRepositoryService.updateMetadata(metadata); } + addLicense(metadata, identity); + vfsRepositoryService.resetThumbnails(childLeaf); } - return true; } - private void addLicense(VFSMetadata meta, Identity identity) { + private void addLicense(VFSMetadata meta, Identity id) { LicenseService licenseService = CoreSpringFactory.getImpl(LicenseService.class); LicenseModule licenseModule = CoreSpringFactory.getImpl(LicenseModule.class); FolderLicenseHandler licenseHandler = CoreSpringFactory.getImpl(FolderLicenseHandler.class); if (licenseModule.isEnabled(licenseHandler)) { - License license = licenseService.createDefaultLicense(licenseHandler, identity); + License license = licenseService.createDefaultLicense(licenseHandler, id); meta.setLicenseType(license.getLicenseType()); meta.setLicenseTypeName(license.getLicenseType().getName()); meta.setLicensor(license.getLicensor()); diff --git a/src/main/java/org/olat/core/configuration/AbstractSpringModule.java b/src/main/java/org/olat/core/configuration/AbstractSpringModule.java index 95c2ae07896f02ce46e5d8b789905caded5c0868..a30a6ea4d11d4535bfa41ebe02a965f301369871 100644 --- a/src/main/java/org/olat/core/configuration/AbstractSpringModule.java +++ b/src/main/java/org/olat/core/configuration/AbstractSpringModule.java @@ -294,10 +294,7 @@ public abstract class AbstractSpringModule implements GenericEventListener, Init // delegate to new property based config style moduleConfigProperties.setIntPropertyDefault(key, value); } - - /** - * @see org.olat.core.util.event.GenericEventListener#event(org.olat.core.gui.control.Event) - */ + @Override public void event(Event event) { if (event instanceof PersistedPropertiesChangedEvent) { diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/FormUIFactory.java b/src/main/java/org/olat/core/gui/components/form/flexible/FormUIFactory.java index 702cfbe3e8f20289c5d5f86db4d7188a2f183a68..a99584bbb4bdb1538016030fcce3e698e581f58c 100644 --- a/src/main/java/org/olat/core/gui/components/form/flexible/FormUIFactory.java +++ b/src/main/java/org/olat/core/gui/components/form/flexible/FormUIFactory.java @@ -92,6 +92,7 @@ import org.olat.core.gui.components.tree.MenuTreeItem; import org.olat.core.gui.components.tree.TreeModel; import org.olat.core.gui.control.WindowBackOffice; import org.olat.core.gui.control.WindowControl; +import org.olat.core.gui.media.MediaResource; import org.olat.core.gui.themes.Theme; import org.olat.core.gui.translator.Translator; import org.olat.core.util.StringHelper; @@ -1127,6 +1128,17 @@ public class FormUIFactory { } return fte; } + + public DownloadLink addDownloadLink(String name, String linkTitle, String i18nLabel, MediaResource resource, FlexiTableElement formLayout) { + DownloadLinkImpl fte = new DownloadLinkImpl(name); + fte.setLinkText(linkTitle); + fte.setDownloadMedia(resource); + setLabelIfNotNull(i18nLabel, fte); + if(formLayout != null) { + ((FlexiTableElementImpl)formLayout).addFormItem(fte); + } + return fte; + } /** * add a toggle which handles on/off state itself and can be asked for status diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/elements/DownloadLink.java b/src/main/java/org/olat/core/gui/components/form/flexible/elements/DownloadLink.java index 508226d47046e69003a12e826a9a459293e11d8a..2c4243dc22740dd2969cd129db5b6bdc78c32827 100644 --- a/src/main/java/org/olat/core/gui/components/form/flexible/elements/DownloadLink.java +++ b/src/main/java/org/olat/core/gui/components/form/flexible/elements/DownloadLink.java @@ -22,6 +22,7 @@ package org.olat.core.gui.components.form.flexible.elements; import java.io.File; import org.olat.core.gui.components.form.flexible.FormItem; +import org.olat.core.gui.media.MediaResource; import org.olat.core.util.vfs.VFSLeaf; /** @@ -43,5 +44,7 @@ public interface DownloadLink extends FormItem { public void setDownloadItem(File downloadItem); public void setDownloadItem(VFSLeaf downloadItem); + + public void setDownloadMedia(MediaResource mediaResource); } diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/DownloadLinkImpl.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/DownloadLinkImpl.java index 1f6f08019cc8266c047eedf96109c3b5510ef117..5412bc059745b906308c65d51c6a9b38dc1a74ea 100644 --- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/DownloadLinkImpl.java +++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/DownloadLinkImpl.java @@ -26,6 +26,7 @@ import org.olat.core.gui.components.Component; import org.olat.core.gui.components.download.DownloadComponent; import org.olat.core.gui.components.form.flexible.elements.DownloadLink; import org.olat.core.gui.components.form.flexible.impl.FormItemImpl; +import org.olat.core.gui.media.MediaResource; import org.olat.core.util.vfs.VFSLeaf; /** @@ -75,6 +76,11 @@ public class DownloadLinkImpl extends FormItemImpl implements DownloadLink { downloadCmp.setDownloadItem(downloadItem, true); } + @Override + public void setDownloadMedia(MediaResource mediaResource) { + downloadCmp.setMediaResource(mediaResource); + } + @Override protected Component getFormItemComponent() { return downloadCmp; diff --git a/src/main/java/org/olat/core/util/ZipUtil.java b/src/main/java/org/olat/core/util/ZipUtil.java index eabb4c6bfc8ef37c045c121a837b7dc5f58d9ae4..ca61935ea00b3e41b515fab127c2292f20bd3762 100644 --- a/src/main/java/org/olat/core/util/ZipUtil.java +++ b/src/main/java/org/olat/core/util/ZipUtil.java @@ -70,7 +70,6 @@ import org.olat.core.util.vfs.VFSLockApplicationType; import org.olat.core.util.vfs.VFSLockManager; import org.olat.core.util.vfs.VFSManager; import org.olat.core.util.vfs.filters.VFSSystemItemFilter; -import org.olat.core.util.vfs.version.Versionable; /** * Initial Date: 04.12.2002 @@ -214,11 +213,8 @@ public class ZipUtil { if (!copy(oZip, newEntry)) { return false; } - } else if (newEntry instanceof Versionable) { - Versionable versionable = (Versionable)newEntry; - if(versionable.getVersions().isVersioned()) { - versionable.getVersions().addVersion(identity, "", oZip); - } + } else if (newEntry.canVersion() == VFSConstants.YES) { + vfsRepositoryService.addVersion(newEntry, identity, "", oZip); } if(newEntry != null && identity != null && newEntry.canMeta() == VFSConstants.YES) { VFSMetadata info = newEntry.getMetaInfo(); @@ -305,6 +301,8 @@ public class ZipUtil { */ private static boolean unzipNonStrict(InputStream in, VFSContainer targetDir, Identity identity, boolean versioning) { try(net.sf.jazzlib.ZipInputStream oZip = new net.sf.jazzlib.ZipInputStream(in)) { + VFSRepositoryService vfsRepositoryService = CoreSpringFactory.getImpl(VFSRepositoryService.class); + // unzip files net.sf.jazzlib.ZipEntry oEntr = oZip.getNextEntry(); while (oEntr != null) { @@ -343,11 +341,8 @@ public class ZipUtil { if (!copyShielded(oZip, newEntry)) { return false; } - } else if (newEntry instanceof Versionable) { - Versionable versionable = (Versionable)newEntry; - if(versionable.getVersions().isVersioned()) { - versionable.getVersions().addVersion(identity, "", oZip); - } + } else if (newEntry.canVersion() == VFSConstants.YES) { + vfsRepositoryService.addVersion(newEntry, identity, "", oZip); } unzipMetadata(identity, extra, newEntry); } else { diff --git a/src/main/java/org/olat/core/util/vfs/AbstractVirtualContainer.java b/src/main/java/org/olat/core/util/vfs/AbstractVirtualContainer.java index 3fb6e3653944102612d23a1487bc23bf83d9d70d..695758bd307bf53fb5d3fdfdf661ab3de5e58139 100644 --- a/src/main/java/org/olat/core/util/vfs/AbstractVirtualContainer.java +++ b/src/main/java/org/olat/core/util/vfs/AbstractVirtualContainer.java @@ -119,6 +119,11 @@ public abstract class AbstractVirtualContainer implements VFSContainer { public VFSStatus canMeta() { return VFSConstants.NO; } + + @Override + public VFSStatus canVersion() { + return VFSConstants.NO; + } @Override public VFSMetadata getMetaInfo() { diff --git a/src/main/java/org/olat/core/util/vfs/LocalFileImpl.java b/src/main/java/org/olat/core/util/vfs/LocalFileImpl.java index c2f68241d8fea393ef305dab56ff3493c047b01f..dde02732c5d5f69236e5321317a363a178999a1e 100644 --- a/src/main/java/org/olat/core/util/vfs/LocalFileImpl.java +++ b/src/main/java/org/olat/core/util/vfs/LocalFileImpl.java @@ -39,13 +39,13 @@ import java.nio.file.Path; import org.olat.core.CoreSpringFactory; import org.olat.core.commons.modules.bc.FolderConfig; +import org.olat.core.commons.services.vfs.VFSRepositoryModule; import org.olat.core.commons.services.vfs.VFSRepositoryService; +import org.olat.core.id.Identity; import org.olat.core.logging.AssertException; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; -import org.olat.core.util.vfs.version.Versionable; -import org.olat.core.util.vfs.version.Versions; -import org.olat.core.util.vfs.version.VersionsManager; +import org.olat.core.logging.activity.ThreadLocalUserActivityLogger; /** * Description:<br> @@ -56,10 +56,8 @@ import org.olat.core.util.vfs.version.VersionsManager; * * @author Felix Jost */ -public class LocalFileImpl extends LocalImpl implements VFSLeaf, Versionable { +public class LocalFileImpl extends LocalImpl implements VFSLeaf { private static final OLog log = Tracing.createLoggerFor(LocalFileImpl.class); - - private Versions versions; private LocalFileImpl() { super(null, null); @@ -108,6 +106,11 @@ public class LocalFileImpl extends LocalImpl implements VFSLeaf, Versionable { return null; } + @Override + public VFSStatus canVersion() { + return VFSRepositoryModule.canVersion(getBasefile()); + } + @Override public OutputStream getOutputStream(boolean append) { OutputStream os = null; @@ -119,14 +122,6 @@ public class LocalFileImpl extends LocalImpl implements VFSLeaf, Versionable { return os; } - @Override - public Versions getVersions() { - if(versions == null) { - versions = CoreSpringFactory.getImpl(VersionsManager.class).createVersionsFor(this); - } - return versions; - } - @Override public VFSStatus rename(String newname) { File f = getBasefile(); @@ -134,15 +129,12 @@ public class LocalFileImpl extends LocalImpl implements VFSLeaf, Versionable { return VFSConstants.NO; } - File par = f.getParentFile(); - File nf = new File(par, newname); - if(getVersions().isVersioned()) { - //rename the versions - CoreSpringFactory.getImpl(VersionsManager.class).rename(this, newname); - } if(canMeta() == VFSConstants.YES) { - CoreSpringFactory.getImpl(VFSRepositoryService.class).rename(getMetaInfo(), newname); + CoreSpringFactory.getImpl(VFSRepositoryService.class).rename(this, newname); } + + File par = f.getParentFile(); + File nf = new File(par, newname); boolean ren = f.renameTo(nf); if (ren) { // f.renameTo() does NOT modify the path contained in the object f!! @@ -158,12 +150,9 @@ public class LocalFileImpl extends LocalImpl implements VFSLeaf, Versionable { @Override public VFSStatus delete() { - if(getVersions().isVersioned()) { - CoreSpringFactory.getImpl(VersionsManager.class).delete(this, false); - } - // Versioning makes a copy of the metadata, delete metadata after it if(canMeta() == VFSConstants.YES) { - CoreSpringFactory.getImpl(VFSRepositoryService.class).deleteMetadata(getMetaInfo()); + Identity identity = ThreadLocalUserActivityLogger.getLoggedIdentity(); + CoreSpringFactory.getImpl(VFSRepositoryService.class).markAsDeleted(this, identity); } return deleteBasefile(); } @@ -173,7 +162,6 @@ public class LocalFileImpl extends LocalImpl implements VFSLeaf, Versionable { if(canMeta() == VFSConstants.YES) { CoreSpringFactory.getImpl(VFSRepositoryService.class).deleteMetadata(getMetaInfo()); } - CoreSpringFactory.getImpl(VersionsManager.class).delete(this, true); return deleteBasefile(); } diff --git a/src/main/java/org/olat/core/util/vfs/LocalFolderImpl.java b/src/main/java/org/olat/core/util/vfs/LocalFolderImpl.java index a2c60cbb42b26006762c8b60e7208c3bb1c1ffa3..b1ba217635ceb984d99435fd92e312545ba7e1c2 100644 --- a/src/main/java/org/olat/core/util/vfs/LocalFolderImpl.java +++ b/src/main/java/org/olat/core/util/vfs/LocalFolderImpl.java @@ -36,15 +36,16 @@ import java.util.List; import org.olat.core.CoreSpringFactory; import org.olat.core.commons.modules.bc.FolderConfig; +import org.olat.core.commons.services.vfs.VFSRepositoryModule; import org.olat.core.commons.services.vfs.VFSRepositoryService; +import org.olat.core.id.Identity; import org.olat.core.logging.AssertException; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; +import org.olat.core.logging.activity.ThreadLocalUserActivityLogger; import org.olat.core.util.FileUtils; -import org.olat.core.util.vfs.filters.VFSSystemItemFilter; import org.olat.core.util.vfs.filters.VFSItemFilter; -import org.olat.core.util.vfs.version.Versionable; -import org.olat.core.util.vfs.version.VersionsManager; +import org.olat.core.util.vfs.filters.VFSSystemItemFilter; /** * Description:<br> @@ -201,14 +202,10 @@ public class LocalFolderImpl extends LocalImpl implements VFSContainer { } catch (Exception e) { return VFSConstants.ERROR_FAILED; } - - if(s instanceof Versionable && ((Versionable)s).getVersions().isVersioned()) { - ((Versionable)s).getVersions().copy(this); - } - if(s.canMeta() == VFSConstants.YES) { + if(s.canMeta() == VFSConstants.YES || s.canVersion() == VFSConstants.YES) { VFSItem target = resolve(sourcename); - if(target instanceof VFSLeaf && target.canMeta() == VFSConstants.YES) { + if(target instanceof VFSLeaf && (target.canMeta() == VFSConstants.YES || s.canVersion() == VFSConstants.YES)) { CoreSpringFactory.getImpl(VFSRepositoryService.class).copyTo(s, (VFSLeaf)target, this); } } @@ -225,13 +222,19 @@ public class LocalFolderImpl extends LocalImpl implements VFSContainer { return VFSConstants.NO_SECURITY_DENIED; return VFSConstants.YES; } + + @Override + public VFSStatus canVersion() { + return VFSRepositoryModule.canVersion(getBasefile()); + } @Override public VFSStatus rename(String newname) { + CoreSpringFactory.getImpl(VFSRepositoryService.class).rename(this, newname); + File f = getBasefile(); File par = f.getParentFile(); File nf = new File(par, newname); - CoreSpringFactory.getImpl(VersionsManager.class).rename(this, newname); boolean ren = f.renameTo(nf); if (ren) { // f.renameTo() does NOT modify the path contained in the object f!! @@ -256,15 +259,11 @@ public class LocalFolderImpl extends LocalImpl implements VFSContainer { child.delete(); } - VersionsManager versionsManager = CoreSpringFactory.getImpl(VersionsManager.class); - if(versionsManager.isEnabled()) { - versionsManager.delete(this, false); - } // Versioning makes a copy of the metadata, delete metadata after it if(canMeta() == VFSConstants.YES) { - CoreSpringFactory.getImpl(VFSRepositoryService.class).deleteMetadata(getMetaInfo()); + Identity identity = ThreadLocalUserActivityLogger.getLoggedIdentity(); + CoreSpringFactory.getImpl(VFSRepositoryService.class).markAsDeleted(this, identity); } - // now delete the directory itself return deleteBasefile(); } @@ -283,7 +282,6 @@ public class LocalFolderImpl extends LocalImpl implements VFSContainer { if(canMeta() == VFSConstants.YES) { CoreSpringFactory.getImpl(VFSRepositoryService.class).deleteMetadata(getMetaInfo()); } - CoreSpringFactory.getImpl(VersionsManager.class).delete(this, true); // now delete the directory itself return deleteBasefile(); } diff --git a/src/main/java/org/olat/core/util/vfs/LocalImpl.java b/src/main/java/org/olat/core/util/vfs/LocalImpl.java index d8cce3d498352b8342da0a30a39d8350e0c2a376..9d8f8db263f087d8e39c24bc8d6192a531f4cd09 100644 --- a/src/main/java/org/olat/core/util/vfs/LocalImpl.java +++ b/src/main/java/org/olat/core/util/vfs/LocalImpl.java @@ -143,6 +143,11 @@ public abstract class LocalImpl implements VFSItem, JavaIOItem { public VFSStatus canMeta() { return VFSRepositoryModule.canMeta(getBasefile()); } + + @Override + public VFSStatus canVersion() { + return VFSConstants.NO; + } @Override public VFSMetadata getMetaInfo() { diff --git a/src/main/java/org/olat/core/util/vfs/MergeSource.java b/src/main/java/org/olat/core/util/vfs/MergeSource.java index 2b8ae24b7992e557e6d92d07f02e36ba78c0bfa8..6bfc7b4def60c7cc66c8a85b3c007c8288419e08 100644 --- a/src/main/java/org/olat/core/util/vfs/MergeSource.java +++ b/src/main/java/org/olat/core/util/vfs/MergeSource.java @@ -140,34 +140,22 @@ public class MergeSource extends AbstractVirtualContainer { public boolean isContainersChild(VFSContainer container) { return mergedContainersChildren.contains(container); } - - /** - * @see org.olat.core.util.vfs.VFSItem#getParent() - */ + @Override public VFSContainer getParentContainer() { return parentContainer; } - /** - * @see org.olat.core.util.vfs.VFSItem#setParentContainer(org.olat.core.util.vfs.VFSContainer) - */ @Override public void setParentContainer(VFSContainer parentContainer) { this.parentContainer = parentContainer; } - - /** - * @see org.olat.core.util.vfs.VFSContainer#getItems() - */ + @Override public List<VFSItem> getItems() { return getItems(null); } - /** - * @see org.olat.core.util.vfs.VFSContainer#getItems(org.olat.core.util.vfs.filters.VFSItemFilter) - */ @Override public List<VFSItem> getItems(VFSItemFilter filter) { // remember: security callback and parent was already set during add to this MergeSource @@ -194,18 +182,12 @@ public class MergeSource extends AbstractVirtualContainer { return all; } - /** - * @see org.olat.core.util.vfs.VFSItem#canCopyTo() - */ @Override public VFSStatus canWrite() { if (rootWriteContainer == null) return VFSConstants.NO; return rootWriteContainer.canWrite(); } - /** - * @see org.olat.core.util.vfs.VFSContainer#createChildContainer(java.lang.String) - */ @Override public VFSContainer createChildContainer(String name) { if (canWrite() != VFSConstants.YES) return null; @@ -314,12 +296,17 @@ public class MergeSource extends AbstractVirtualContainer { @Override public VFSStatus canMeta() { - return VFSConstants.NO; + return rootWriteContainer == null ? VFSConstants.NO : rootWriteContainer.canVersion(); + } + + @Override + public VFSStatus canVersion() { + return rootWriteContainer == null ? VFSConstants.NO: rootWriteContainer.canVersion(); } @Override public VFSMetadata getMetaInfo() { - return null; + return rootWriteContainer == null ? null : rootWriteContainer.getMetaInfo(); } @Override diff --git a/src/main/java/org/olat/core/util/vfs/NamedContainerImpl.java b/src/main/java/org/olat/core/util/vfs/NamedContainerImpl.java index 92afdf2678182515fb4d0357983447d220287fc3..036ed3e4b2267ba029486a1d036010e4bcd0f194 100644 --- a/src/main/java/org/olat/core/util/vfs/NamedContainerImpl.java +++ b/src/main/java/org/olat/core/util/vfs/NamedContainerImpl.java @@ -165,6 +165,11 @@ public class NamedContainerImpl extends AbstractVirtualContainer { return getDelegate().canMeta(); } + @Override + public VFSStatus canVersion() { + return getDelegate().canVersion(); + } + @Override public VFSMetadata getMetaInfo() { return getDelegate().getMetaInfo(); diff --git a/src/main/java/org/olat/core/util/vfs/NamedLeaf.java b/src/main/java/org/olat/core/util/vfs/NamedLeaf.java index e17690cb10599a0b2a3b3f5da6118723fbc1b6f1..68877974acbf9a5987133d131c424af9a525c18b 100644 --- a/src/main/java/org/olat/core/util/vfs/NamedLeaf.java +++ b/src/main/java/org/olat/core/util/vfs/NamedLeaf.java @@ -151,6 +151,11 @@ public class NamedLeaf implements VFSLeaf { public VFSItem resolve(String path) { return delegate.resolve(delegate.getName()); } + + @Override + public VFSStatus canVersion() { + return delegate.canVersion(); + } @Override public VFSStatus canMeta() { diff --git a/src/main/java/org/olat/core/util/vfs/VFSItem.java b/src/main/java/org/olat/core/util/vfs/VFSItem.java index 5524ded206783b35fd996d299074ad8780b26a0c..a0578b222e020d4b41337e58c34dabfe8ab20259 100644 --- a/src/main/java/org/olat/core/util/vfs/VFSItem.java +++ b/src/main/java/org/olat/core/util/vfs/VFSItem.java @@ -137,6 +137,11 @@ public interface VFSItem { */ public VFSStatus canMeta(); + /** + * @return true if the file can be versioned + */ + public VFSStatus canVersion(); + /** * @return The metadata if the item can metadata or null if not */ diff --git a/src/main/java/org/olat/core/util/vfs/VFSLeafHandler.java b/src/main/java/org/olat/core/util/vfs/VFSLeafHandler.java deleted file mode 100644 index 83ef1aacba208b5f2f535c3af3112478a3ae4e6e..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/core/util/vfs/VFSLeafHandler.java +++ /dev/null @@ -1,71 +0,0 @@ -/** -* OLAT - Online Learning and Training<br> -* http://www.olat.org -* <p> -* Licensed under the Apache License, Version 2.0 (the "License"); <br> -* you may not use this file except in compliance with the License.<br> -* You may obtain a copy of the License at -* <p> -* http://www.apache.org/licenses/LICENSE-2.0 -* <p> -* Unless required by applicable law or agreed to in writing,<br> -* software distributed under the License is distributed on an "AS IS" BASIS, <br> -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> -* See the License for the specific language governing permissions and <br> -* limitations under the License. -* <p> -* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br> -* University of Zurich, Switzerland. -* <hr> -* <a href="http://www.openolat.org"> -* OpenOLAT - Online Learning and Training</a><br> -* This file has been modified by the OpenOLAT community. Changes are licensed -* under the Apache 2.0 license as the original file. -* <p> -*/ - -package org.olat.core.util.vfs; - -import java.io.UnsupportedEncodingException; -import java.util.logging.Formatter; -import java.util.logging.LogRecord; -import java.util.logging.StreamHandler; - -import org.olat.core.logging.OLATRuntimeException; - -/** - * Description:<br> - * Log handler that logs to a virtual file system leaf. The handler opens the file - * for each log entry and closes it after that immediately. (in order to not waste too many unix filehandles) - * <P> - * Initial Date: Aug 30, 2005 <br> - * @author gnaegi - */ -public class VFSLeafHandler extends StreamHandler { - private VFSLeaf vfsLeaf; - - /** - * @param vfsLeaf The logfile - * @param formatter - */ - public VFSLeafHandler(VFSLeaf vfsLeaf, Formatter formatter) { - setFormatter(formatter); - try { - setEncoding("utf8"); - } catch (SecurityException e) { - throw new OLATRuntimeException(this.getClass(), "Error when setting encoding of to 'utf8' ",e); - } catch (UnsupportedEncodingException e) { - throw new OLATRuntimeException(this.getClass(), "Error when setting encoding of to 'utf8' ",e); - } - this.vfsLeaf = vfsLeaf; - } - - /** - * @see java.util.logging.Handler#publish(java.util.logging.LogRecord) - */ - public synchronized void publish(LogRecord arg0) { //o_clusterOK by:fj, as long as file is written to from one vm only - setOutputStream(vfsLeaf.getOutputStream(true)); - super.publish(arg0); - close(); - } -} diff --git a/src/main/java/org/olat/core/util/vfs/VFSLockApplicationType.java b/src/main/java/org/olat/core/util/vfs/VFSLockApplicationType.java index ef687a0490089e117a26364d789f9a761793e346..9030304b66ee65faeefbc6e3bca22b29855d0501 100644 --- a/src/main/java/org/olat/core/util/vfs/VFSLockApplicationType.java +++ b/src/main/java/org/olat/core/util/vfs/VFSLockApplicationType.java @@ -1,3 +1,22 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ package org.olat.core.util.vfs; /** diff --git a/src/main/java/org/olat/core/util/vfs/lock/VFSLockManagerImpl.java b/src/main/java/org/olat/core/util/vfs/lock/VFSLockManagerImpl.java index 0de43417eea34c118230d063240d2c93e53b9ffd..c3ed15af32f5968fdb1ec13e30c2b7824256dff1 100644 --- a/src/main/java/org/olat/core/util/vfs/lock/VFSLockManagerImpl.java +++ b/src/main/java/org/olat/core/util/vfs/lock/VFSLockManagerImpl.java @@ -113,7 +113,7 @@ public class VFSLockManagerImpl implements VFSLockManager { * @return true If the lock owner is someone else or if it's a WebDAV lock */ @Override - public boolean isLockedForMe(VFSItem item, VFSMetadata loadedInfo, Identity me, Roles roles, VFSLockApplicationType type) { + public boolean isLockedForMe(VFSItem item, VFSMetadata loadedInfo, Identity me, Roles roles, VFSLockApplicationType type) {//TODO metadata need the name/instance of the collaboration app. File file = extractFile(item); if(file != null && fileLocks.containsKey(file)) { LockInfo lock = fileLocks.get(file); 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 deleted file mode 100644 index dff8415f7ef566493174d0fc5c4e53f12ec8cf93..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/core/util/vfs/version/FolderVersioningConfigurator.java +++ /dev/null @@ -1,55 +0,0 @@ -/** - * <a href="http://www.openolat.org"> - * OpenOLAT - Online Learning and Training</a><br> - * <p> - * Licensed under the Apache License, Version 2.0 (the "License"); <br> - * you may not use this file except in compliance with the License.<br> - * You may obtain a copy of the License at the - * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> - * <p> - * Unless required by applicable law or agreed to in writing,<br> - * software distributed under the License is distributed on an "AS IS" BASIS, <br> - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> - * See the License for the specific language governing permissions and <br> - * limitations under the License. - * <p> - * Initial code contributed and copyrighted by<br> - * frentix GmbH, http://www.frentix.com - * <p> - */ -package org.olat.core.util.vfs.version; - -import org.olat.core.configuration.ConfigOnOff; -import org.olat.core.util.vfs.VFSContainer; - -/** - * - * Description:<br> - * Interface for the configuration of versioning. - * - * <P> - * Initial Date: 21 sept. 2009 <br> - * - * @author srosse - */ -public interface FolderVersioningConfigurator extends ConfigOnOff { - - /** - * The absolut limit for this instance - * @return -1 for versioning without limit, 0 for no versioning, 1 - n is the maximum number of revision per file - */ - public int getMaxNumOfVersionsAllowed(); - - /** - * @param relPath - * @return -1 for versioning without limit, 0 for no versioning, 1 - n is the maximum number of revision per file - */ - public int versionAllowed(String relPath); - - /** - * @param container - * @return true if versioning is enabled for the container given as parameter - */ - public boolean versionEnabled(VFSContainer container); - -} diff --git a/src/main/java/org/olat/core/util/vfs/version/NotVersioned.java b/src/main/java/org/olat/core/util/vfs/version/NotVersioned.java deleted file mode 100644 index 9a8d94c5e332dbf8f3601ea88d32d160161a2571..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/core/util/vfs/version/NotVersioned.java +++ /dev/null @@ -1,95 +0,0 @@ -/** - * <a href="http://www.openolat.org"> - * OpenOLAT - Online Learning and Training</a><br> - * <p> - * Licensed under the Apache License, Version 2.0 (the "License"); <br> - * you may not use this file except in compliance with the License.<br> - * You may obtain a copy of the License at the - * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> - * <p> - * Unless required by applicable law or agreed to in writing,<br> - * software distributed under the License is distributed on an "AS IS" BASIS, <br> - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> - * See the License for the specific language governing permissions and <br> - * limitations under the License. - * <p> - * Initial code contributed and copyrighted by<br> - * frentix GmbH, http://www.frentix.com - * <p> - */ -package org.olat.core.util.vfs.version; - -import java.io.InputStream; -import java.util.Collections; -import java.util.List; - -import org.olat.core.id.Identity; -import org.olat.core.util.vfs.VFSContainer; - -/** - * Description:<br> - * This class implements the @see org.olat.core.util.vfs.version.Versions interface for a file - * which is not versioned and will never be. - * - * <P> - * Initial Date: 21 sept. 2009 <br> - * - * @author srosse - */ -public class NotVersioned implements Versions { - - @Override - public boolean isVersioned() { - return false; - } - - @Override - public List<VFSRevision> getRevisions() { - return Collections.emptyList(); - } - - @Override - public String getAuthor() { - return ""; - } - - @Override - public String getCreator() { - return ""; - } - - @Override - public String getComment() { - return ""; - } - - @Override - public String getRevisionNr() { - return ""; - } - - @Override - public boolean addVersion(Identity identity, String comment, InputStream newVersion) { - return false; - } - - @Override - public boolean move(VFSContainer container) { - return false; - } - - @Override - public boolean copy(VFSContainer container) { - return false; - } - - @Override - public boolean delete(Identity identity, List<VFSRevision> versionsToDelete) { - return false; - } - - @Override - public boolean restore(Identity identity, VFSRevision version, String comment) { - return false; - } -} diff --git a/src/main/java/org/olat/core/util/vfs/version/OrphanVersion.java b/src/main/java/org/olat/core/util/vfs/version/OrphanVersion.java deleted file mode 100644 index 4019229b03698bd7559d7268f1ae39e1cef17d6b..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/core/util/vfs/version/OrphanVersion.java +++ /dev/null @@ -1,65 +0,0 @@ -/** - * <a href="http://www.openolat.org"> - * OpenOLAT - Online Learning and Training</a><br> - * <p> - * Licensed under the Apache License, Version 2.0 (the "License"); <br> - * you may not use this file except in compliance with the License.<br> - * You may obtain a copy of the License at the - * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> - * <p> - * Unless required by applicable law or agreed to in writing,<br> - * software distributed under the License is distributed on an "AS IS" BASIS, <br> - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> - * See the License for the specific language governing permissions and <br> - * limitations under the License. - * <p> - * Initial code contributed and copyrighted by<br> - * frentix GmbH, http://www.frentix.com - * <p> - */ -package org.olat.core.util.vfs.version; - -import org.olat.core.util.vfs.LocalImpl; -import org.olat.core.util.vfs.VFSLeaf; - -/** - * - * Description:<br> - * TODO: srosse Class Description for OrphanVersion - * - * <P> - * Initial Date: 5 mai 2011 <br> - * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com - */ -//fxdiff FXOLAT-127: file versions maintenance tool -public class OrphanVersion { - - private final VFSLeaf orphan; - private final VFSLeaf versionsLeaf; - private final Versions versions; - - public OrphanVersion(VFSLeaf orphan, VFSLeaf versionsLeaf, Versions versions) { - this.orphan = orphan; - this.versionsLeaf = versionsLeaf; - this.versions = versions; - } - - public VFSLeaf getOrphan() { - return orphan; - } - - public VFSLeaf getVersionsLeaf() { - return versionsLeaf; - } - - public Versions getVersions() { - return versions; - } - - public String getOriginalFilePath() { - if(orphan instanceof LocalImpl) { - return ((LocalImpl)orphan).getBasefile().toString(); - } - return orphan.toString(); - } -} \ No newline at end of file diff --git a/src/main/java/org/olat/core/util/vfs/version/RevisionFileImpl.java b/src/main/java/org/olat/core/util/vfs/version/RevisionFileImpl.java index df713e6f7c1458c0ce2bbb43df5da6781a829d72..31cd59963bd4d97565dd4d566004e833c9777a82 100644 --- a/src/main/java/org/olat/core/util/vfs/version/RevisionFileImpl.java +++ b/src/main/java/org/olat/core/util/vfs/version/RevisionFileImpl.java @@ -19,9 +19,10 @@ */ package org.olat.core.util.vfs.version; -import java.io.InputStream; +import java.util.Date; import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.id.Identity; import org.olat.core.util.vfs.VFSContainer; import org.olat.core.util.vfs.VFSLeaf; @@ -36,9 +37,9 @@ import org.olat.core.util.vfs.VFSLeaf; * * @author srosse */ -public class RevisionFileImpl implements VFSRevision { +public class RevisionFileImpl { - private String author; + private Identity author; private String comment; private String name; private String uuid; @@ -46,7 +47,7 @@ public class RevisionFileImpl implements VFSRevision { private VFSLeaf file; private VFSContainer container; - private String revisionNr; + private int revisionNr; private String filename; private VFSMetadata metadata; @@ -83,12 +84,11 @@ public class RevisionFileImpl implements VFSRevision { this.container = container; } - @Override - public String getAuthor() { + public Identity getAuthor() { return author; } - public void setAuthor(String author) { + public void setAuthor(Identity author) { this.author = author; } @@ -100,7 +100,6 @@ public class RevisionFileImpl implements VFSRevision { this.filename = filename; } - @Override public String getComment() { return comment; } @@ -109,28 +108,23 @@ public class RevisionFileImpl implements VFSRevision { this.comment = comment; } - @Override public long getSize() { VFSLeaf f = getFile(); return f == null ? -1l : f.getSize(); } - @Override - public InputStream getInputStream() { - VFSLeaf f = getFile(); - return f == null ? null : f.getInputStream(); + public Date getFileLastModified() { + return new Date(lastModified); } - - @Override - public long getLastModified() { - return lastModified; + + public void setFileLastModified(Date date) { + lastModified = date == null ? -1l : date.getTime(); } public void setLastModified(long lastModified) { this.lastModified = lastModified; } - @Override public String getName() { if (name == null || name.length() == 0) { return getFilename(); } return name; @@ -148,12 +142,11 @@ public class RevisionFileImpl implements VFSRevision { this.metadata = metadata; } - @Override - public String getRevisionNr() { + public int getRevisionNr() { return revisionNr; } - public void setRevisionNr(String revisionNr) { + public void setRevisionNr(int revisionNr) { this.revisionNr = revisionNr; } 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 deleted file mode 100644 index ddae1f004ef4321d7e10694ca5de418d03b5550b..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/core/util/vfs/version/SimpleVersionConfig.java +++ /dev/null @@ -1,192 +0,0 @@ -/** - * <a href="http://www.openolat.org"> - * OpenOLAT - Online Learning and Training</a><br> - * <p> - * Licensed under the Apache License, Version 2.0 (the "License"); <br> - * you may not use this file except in compliance with the License.<br> - * You may obtain a copy of the License at the - * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> - * <p> - * Unless required by applicable law or agreed to in writing,<br> - * software distributed under the License is distributed on an "AS IS" BASIS, <br> - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> - * See the License for the specific language governing permissions and <br> - * limitations under the License. - * <p> - * Initial code contributed and copyrighted by<br> - * frentix GmbH, http://www.frentix.com - * <p> - */ -package org.olat.core.util.vfs.version; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import org.olat.core.commons.modules.bc.FolderConfig; -import org.olat.core.configuration.AbstractSpringModule; -import org.olat.core.util.StringHelper; -import org.olat.core.util.coordinate.CoordinatorManager; -import org.olat.core.util.event.GenericEventListener; -import org.olat.core.util.vfs.LocalFolderImpl; -import org.olat.core.util.vfs.MergeSource; -import org.olat.core.util.vfs.NamedContainerImpl; -import org.olat.core.util.vfs.VFSContainer; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; - -/** - * - * Description:<br> - * A very simple configuration bean for versioning. There is a default value for - * the maximum allowed number of revisions, this number can be overridden by an - * second value saved in the persisted properties. - * - * <P> - * Initial Date: 21 sept. 2009 <br> - * - * @author srosse - */ -@Service("versioningConfigurator") -public class SimpleVersionConfig extends AbstractSpringModule implements GenericEventListener, FolderVersioningConfigurator { - - private static final String MAX_NUMBER_OF_VERSIONS = "maxnumber.versions"; - private static final String COURSE_PATH = "/course/"; - private static final String SOLUTIONS_PATH = "/solutions/"; - private static final String RETURNBOXES_PATH = "/returnboxes/"; - private static final String DROPBOXES = "/dropboxes/"; - private static final String TASKFOLDERS = "/taskfolders/"; - - private static final String[] EXCLUSIONS_IN_COURSE_PATH = {SOLUTIONS_PATH, RETURNBOXES_PATH, DROPBOXES, TASKFOLDERS}; - - @Value("${maxnumber.versions:0}") - private int maxNumberOfVersions; - - private String courseRoot; - private List<String> excludedRoots; - - /** - * [used by spring] - */ - @Autowired - public SimpleVersionConfig(CoordinatorManager coordinatorManager) { - super(coordinatorManager); - } - - @Override - public boolean isEnabled() { - return maxNumberOfVersions > 0; - } - - @Override - public void init() { - String maxNumberOfVersionsObj = getStringPropertyValue(MAX_NUMBER_OF_VERSIONS, true); - if(StringHelper.containsNonWhitespace(maxNumberOfVersionsObj)) { - maxNumberOfVersions = Integer.parseInt(maxNumberOfVersionsObj); - } - } - - @Override - protected void initFromChangedProperties() { - init(); - } - - /** - * @return maximum number of revisions, defined in admin. of Olat - */ - public int getMaxNumberOfVersionsProperty() { - return maxNumberOfVersions; - } - - public void setMaxNumberOfVersionsProperty(int maxNumber) { - this.maxNumberOfVersions = maxNumber; - setStringProperty(MAX_NUMBER_OF_VERSIONS, Integer.toString(maxNumber), true); - } - - @Override - public int getMaxNumOfVersionsAllowed() { - return getVersionAllowed(); - } - - @Override - public int versionAllowed(String relPath) { - if(relPath == null) { - return 0; - } - if(StringHelper.containsNonWhitespace(relPath)) { - if(relPath.startsWith("/tmp/")//no versioning in tmp - || relPath.startsWith("/scorm/")//there is already a versioning in assessment tool - || relPath.startsWith("/portfolio/")//portfolio is not a folder - || relPath.startsWith("/forum/")) {//forum is not a folder - return 0; - } - } - return getVersionAllowed() ; - } - - @Override - public boolean versionEnabled(VFSContainer container) { - int versionsAllowed = getVersionAllowed(); - if(versionsAllowed == 0) { - return false; - } - - if (container instanceof NamedContainerImpl) { - container = ((NamedContainerImpl) container).getDelegate(); - } - if (container instanceof MergeSource) { - container = ((MergeSource)container).getRootWriteContainer(); - } - - if (container instanceof LocalFolderImpl) { - try { - LocalFolderImpl folderImpl = (LocalFolderImpl)container; - String path = folderImpl.getBasefile().getCanonicalPath(); - List<String> exRoots = getExcludedRoots(); - for(String excludedRoot:exRoots) { - if(path.startsWith(excludedRoot)) { - return false; - } - } - - String root = getCourseRoot(); - if (path.startsWith(root)) { - for(String exclusion:EXCLUSIONS_IN_COURSE_PATH) { - if(path.indexOf(exclusion) > 0) { - return false; - } - } - } - return getVersionAllowed() != 0; - } catch (IOException e) { - //fail silently - } - } - return false; - } - - private int getVersionAllowed() { - return getMaxNumberOfVersionsProperty(); - } - - private String getCourseRoot() { - if(courseRoot == null) { - courseRoot = FolderConfig.getCanonicalRoot(); - courseRoot += COURSE_PATH; - } - return courseRoot; - } - - private List<String> getExcludedRoots() { - if(excludedRoots == null) { - excludedRoots = new ArrayList<>(); - excludedRoots.add(FolderConfig.getCanonicalTmpDir()); - String bcroot = FolderConfig.getCanonicalRoot(); - excludedRoots.add(bcroot + "/forum"); - excludedRoots.add(bcroot + "/portfolio"); - excludedRoots.add(bcroot + "/scorm"); - } - return excludedRoots; - } -} diff --git a/src/main/java/org/olat/core/util/vfs/version/Versionable.java b/src/main/java/org/olat/core/util/vfs/version/Versionable.java deleted file mode 100644 index 913212851334d8e167c23eedef087043a465877f..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/core/util/vfs/version/Versionable.java +++ /dev/null @@ -1,36 +0,0 @@ -/** - * <a href="http://www.openolat.org"> - * OpenOLAT - Online Learning and Training</a><br> - * <p> - * Licensed under the Apache License, Version 2.0 (the "License"); <br> - * you may not use this file except in compliance with the License.<br> - * You may obtain a copy of the License at the - * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> - * <p> - * Unless required by applicable law or agreed to in writing,<br> - * software distributed under the License is distributed on an "AS IS" BASIS, <br> - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> - * See the License for the specific language governing permissions and <br> - * limitations under the License. - * <p> - * Initial code contributed and copyrighted by<br> - * frentix GmbH, http://www.frentix.com - * <p> - */ -package org.olat.core.util.vfs.version; - -/** - * - * Description:<br> - * A VFSItem which want to be versioned must implements this interface. - * - * <P> - * Initial Date: 21 sept. 2009 <br> - * - * @author srosse - */ -public interface Versionable { - - public Versions getVersions(); - -} diff --git a/src/main/java/org/olat/core/util/vfs/version/Versions.java b/src/main/java/org/olat/core/util/vfs/version/Versions.java deleted file mode 100644 index 8de0d815927446a2f241bc0f3d1abb1658966c85..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/core/util/vfs/version/Versions.java +++ /dev/null @@ -1,107 +0,0 @@ -/** - * <a href="http://www.openolat.org"> - * OpenOLAT - Online Learning and Training</a><br> - * <p> - * Licensed under the Apache License, Version 2.0 (the "License"); <br> - * you may not use this file except in compliance with the License.<br> - * You may obtain a copy of the License at the - * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> - * <p> - * Unless required by applicable law or agreed to in writing,<br> - * software distributed under the License is distributed on an "AS IS" BASIS, <br> - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> - * See the License for the specific language governing permissions and <br> - * limitations under the License. - * <p> - * Initial code contributed and copyrighted by<br> - * frentix GmbH, http://www.frentix.com - * <p> - */ -package org.olat.core.util.vfs.version; - -import java.io.InputStream; -import java.util.List; - -import org.olat.core.id.Identity; -import org.olat.core.util.vfs.VFSContainer; - -/** - * - * Description:<br> - * The interface which enabled the versioning - * <P> - * Initial Date: 21 sept. 2009 <br> - * - * @author srosse - */ -public interface Versions { - - /** - * @return true if the file is versioned - */ - public boolean isVersioned(); - - /** - * @return the current version number - */ - public String getRevisionNr(); - - /** - * @return the current author of the file - */ - public String getAuthor(); - - /** - * @return creator of the file - */ - public String getCreator(); - - /** - * @return comment on the current version - */ - public String getComment(); - - /** - * @return the list of revisions - */ - public List<VFSRevision> getRevisions(); - - /** - * add a new version of the file - * @param identity - * @param comment - * @param newVersion - * @return - */ - public boolean addVersion(Identity identity, String comment, InputStream newVersion); - - /** - * move the file - * @param container - * @return true if successful - */ - public boolean move(VFSContainer container); - - /** - * Copy the file - * @param container - * @return true if successful - */ - public boolean copy(VFSContainer container); - - /** - * restore the file to the revision given as parameter - * @param identity - * @param revision - * @return - */ - public boolean restore(Identity identity, VFSRevision revision, String comment); - - /** - * Delete the list of revisions given as parameter - * @param identity - * @param revisionsToDelete - * @return - */ - public boolean delete(Identity identity, List<VFSRevision> revisionsToDelete); -} diff --git a/src/main/java/org/olat/core/util/vfs/version/VersionsFileImpl.java b/src/main/java/org/olat/core/util/vfs/version/VersionsFileImpl.java index d725a54651ef1d4f91a9723c0a2be09e65c42c27..6b53323ef48635e136a1fea0a20c4a7eea8c5317 100644 --- a/src/main/java/org/olat/core/util/vfs/version/VersionsFileImpl.java +++ b/src/main/java/org/olat/core/util/vfs/version/VersionsFileImpl.java @@ -19,13 +19,10 @@ */ package org.olat.core.util.vfs.version; -import java.io.InputStream; import java.util.ArrayList; import java.util.List; -import org.olat.core.CoreSpringFactory; -import org.olat.core.id.Identity; -import org.olat.core.util.vfs.VFSContainer; +import org.olat.core.commons.services.vfs.VFSRevision; import org.olat.core.util.vfs.VFSLeaf; /** @@ -40,14 +37,14 @@ import org.olat.core.util.vfs.VFSLeaf; * * @author srosse */ -public class VersionsFileImpl implements Versions { +public class VersionsFileImpl { private boolean versioned; private String author; private String creator; - private String revisionNr; + private int revisionNr; private String comment; - private Versionable currentVersion; + private Object currentVersion; private VFSLeaf versionFile; private List<VFSRevision> revisions; @@ -55,12 +52,11 @@ public class VersionsFileImpl implements Versions { // } - @Override - public String getRevisionNr() { + public int getRevisionNr() { return revisionNr; } - public void setRevisionNr(String revisionNr) { + public void setRevisionNr(int revisionNr) { this.revisionNr = revisionNr; } @@ -72,40 +68,14 @@ public class VersionsFileImpl implements Versions { this.versionFile = versionFile; } - public Versionable getCurrentVersion() { + public Object getCurrentVersion() { return currentVersion; } - public void setCurrentVersion(Versionable currentVersion) { + public void setCurrentVersion(Object currentVersion) { this.currentVersion = currentVersion; } - @Override - public boolean addVersion(Identity identity, String comments, InputStream newVersion) { - return CoreSpringFactory.getImpl(VersionsManager.class).addVersion(getCurrentVersion(), identity, comments, newVersion); - } - - @Override - public boolean move(VFSContainer container) { - return CoreSpringFactory.getImpl(VersionsManager.class).move(getCurrentVersion(), container); - } - - @Override - public boolean copy(VFSContainer container) { - return CoreSpringFactory.getImpl(VersionsManager.class).copy(getCurrentVersion(), container); - } - - @Override - public boolean restore(Identity identity, VFSRevision version, String comments) { - return CoreSpringFactory.getImpl(VersionsManager.class).restore(getCurrentVersion(), version, comments); - } - - @Override - public boolean delete(Identity identity, List<VFSRevision> revisionsToDelete) { - return CoreSpringFactory.getImpl(VersionsManager.class).deleteRevisions(getCurrentVersion(), revisionsToDelete); - } - - @Override public List<VFSRevision> getRevisions() { if (revisions == null) { revisions = new ArrayList<>(); @@ -117,7 +87,6 @@ public class VersionsFileImpl implements Versions { this.revisions = revisions; } - @Override public boolean isVersioned() { return versioned; } @@ -126,7 +95,6 @@ public class VersionsFileImpl implements Versions { this.versioned = versioned; } - @Override public String getAuthor() { return author; } @@ -135,7 +103,6 @@ public class VersionsFileImpl implements Versions { this.author = author; } - @Override public String getCreator() { return creator; } @@ -144,7 +111,6 @@ public class VersionsFileImpl implements Versions { this.creator = creator; } - @Override public String getComment() { return comment; } @@ -152,18 +118,4 @@ public class VersionsFileImpl implements Versions { public void setComment(String comment) { this.comment = comment; } - - protected void update(Versions newVersions) { - if (newVersions instanceof VersionsFileImpl) { - VersionsFileImpl newVersionsImpl = (VersionsFileImpl) newVersions; - author = newVersionsImpl.getAuthor(); - creator = newVersionsImpl.getCreator(); - currentVersion = newVersionsImpl.getCurrentVersion(); - revisionNr = newVersionsImpl.getRevisionNr(); - comment = newVersionsImpl.getComment(); - } - - revisions = new ArrayList<>(); - revisions.addAll(newVersions.getRevisions()); - } } 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 deleted file mode 100644 index 83c44b8877b91b5b473df29f3a2cf05c493dd73e..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/core/util/vfs/version/VersionsFileManager.java +++ /dev/null @@ -1,1062 +0,0 @@ -/** - * <a href="http://www.openolat.org"> - * OpenOLAT - Online Learning and Training</a><br> - * <p> - * Licensed under the Apache License, Version 2.0 (the "License"); <br> - * you may not use this file except in compliance with the License.<br> - * You may obtain a copy of the License at the - * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> - * <p> - * Unless required by applicable law or agreed to in writing,<br> - * software distributed under the License is distributed on an "AS IS" BASIS, <br> - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> - * See the License for the specific language governing permissions and <br> - * limitations under the License. - * <p> - * Initial code contributed and copyrighted by<br> - * frentix GmbH, http://www.frentix.com - * <p> - */ -package org.olat.core.util.vfs.version; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Scanner; -import java.util.Set; -import java.util.UUID; -import java.util.regex.Pattern; -import java.util.zip.Adler32; -import java.util.zip.Checksum; - -import org.apache.commons.io.FileUtils; -import org.olat.core.commons.modules.bc.FolderConfig; -import org.olat.core.commons.services.vfs.VFSMetadata; -import org.olat.core.commons.services.vfs.VFSRepositoryService; -import org.olat.core.commons.services.vfs.manager.VFSXStream; -import org.olat.core.id.Identity; -import org.olat.core.logging.OLog; -import org.olat.core.logging.Tracing; -import org.olat.core.logging.activity.ThreadLocalUserActivityLogger; -import org.olat.core.util.StringHelper; -import org.olat.core.util.async.ProgressDelegate; -import org.olat.core.util.io.ShieldInputStream; -import org.olat.core.util.vfs.JavaIOItem; -import org.olat.core.util.vfs.LocalFileImpl; -import org.olat.core.util.vfs.LocalFolderImpl; -import org.olat.core.util.vfs.LocalImpl; -import org.olat.core.util.vfs.MergeSource; -import org.olat.core.util.vfs.NamedContainerImpl; -import org.olat.core.util.vfs.VFSConstants; -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.VFSManager; -import org.olat.core.util.vfs.filters.VFSSystemItemFilter; -import org.olat.core.util.vfs.filters.VFSItemSuffixFilter; -import org.olat.core.util.vfs.filters.VFSLeafFilter; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -/** - * - * Description:<br> - * This implementation of the VersionsManager saved the revisions of a file in a - * file with the same name as the original + ".xml". This xml file is saved in - * a parallel folder .version under the root defined in FolderConfig. Every revision'file - * have a name made of a generated unique id + the name of the original file. - * - * <P> - * Initial Date: 21 sept. 2009 <br> - * - * @author srosse - */ -@Service("versionsManager") -public class VersionsFileManager implements VersionsManager { - private static final OLog log = Tracing.createLoggerFor(VersionsFileManager.class); - - private static final Versions NOT_VERSIONED = new NotVersioned(); - private static final Pattern TAG_PATTERN = Pattern.compile("\\s*[<>]\\s*"); - - private File rootFolder; - private File rootVersionFolder; - private VFSContainer rootVersionsContainer; - - @Autowired - private VFSRepositoryService vfsRepositoryService; - @Autowired - private FolderVersioningConfigurator versioningConfigurator; - - @Override - public boolean isEnabled() { - return versioningConfigurator.isEnabled(); - } - - @Override - public Versions createVersionsFor(VFSLeaf leaf) { - return createVersionsFor(leaf, false); - } - - @Override - public Versions createVersionsFor(VFSLeaf leaf, boolean force) { - if (!(leaf instanceof Versionable) || isVersionFile(leaf)) { - return NOT_VERSIONED; - } - - return readVersions(leaf, false); - } - - @Override - public List<Versions> getDeletedFiles(VFSContainer container) { - List<Versions> deletedRevisions = new ArrayList<>(); - - VFSContainer versionContainer = getCanonicalVersionFolder(container, false); - if (versionContainer != null) { - Set<String> currentNames = new HashSet<>(); - for (VFSItem item : container.getItems(new VFSLeafFilter())) { - currentNames.add(item.getName() + ".xml"); - } - - List<VFSItem> versionItems = versionContainer.getItems(new VFSItemSuffixFilter(new String[] { "xml" })); - for (VFSItem versionItem : versionItems) { - String name = versionItem.getName(); - if (versionItem instanceof VFSLeaf && !currentNames.contains(name) && isVersionsXmlFile((VFSLeaf)versionItem)) { - Versions versions = readVersions(null, (VFSLeaf) versionItem); - if(versions != null) { - List<VFSRevision> revisions = versions.getRevisions(); - if (!revisions.isEmpty()) { - deletedRevisions.add(versions); - } - } - } - } - } - return deletedRevisions; - } - - private Versions readVersions(VFSLeaf leaf, boolean create) { - VFSLeaf fVersions = getCanonicalVersionXmlFile(leaf, create); - if (!create && fVersions == null) { - VersionsFileImpl versions = new VersionsFileImpl(); - versions.setCurrentVersion((Versionable) leaf); - versions.setVersioned(isVersioned(leaf)); - versions.setRevisionNr(getNextRevisionNr(versions)); - return versions; - } - return readVersions(leaf, fVersions); - } - - private boolean isVersionsXmlFile(VFSLeaf fVersions) { - if (fVersions == null || !fVersions.exists()) { - return false; - } - - boolean foundVersionsTag = false; - try(InputStream in = fVersions.getInputStream()) { - if (in == null) { - return false; - } - - Scanner scanner = new Scanner(in); - scanner.useDelimiter(TAG_PATTERN); - while (scanner.hasNext()) { - String tag = scanner.next(); - if ("versions".equals(tag)) { - foundVersionsTag = true; - break; - } - } - - scanner.close(); - } catch(IOException e) { - log.error("", e); - } - return foundVersionsTag; - } - - private Versions readVersions(VFSLeaf leaf, VFSLeaf fVersions) { - if (fVersions == null) { return new NotVersioned(); } - - try { - VFSContainer fVersionContainer = fVersions.getParentContainer(); - VersionsFileImpl versions = (VersionsFileImpl) VFSXStream.read(fVersions); - versions.setVersionFile(fVersions); - versions.setCurrentVersion((Versionable) leaf); - if (versions.getRevisionNr() == null || versions.getRevisionNr().length() == 0) { - versions.setRevisionNr(getNextRevisionNr(versions)); - } - - for (VFSRevision revision : versions.getRevisions()) { - RevisionFileImpl revisionImpl = (RevisionFileImpl) revision; - revisionImpl.setContainer(fVersionContainer); - } - return versions; - } catch (Exception e) { - log.warn("This file is not a versions XML file: " + fVersions, e); - fVersions.delete(); - VersionsFileImpl versions = new VersionsFileImpl(); - versions.setCurrentVersion((Versionable) leaf); - versions.setVersioned(isVersioned(leaf)); - versions.setRevisionNr(getNextRevisionNr(versions)); - log.warn("Deleted corrupt version XML file and created new version XML file: " + versions); - // the old revisions can not be restored automatically. They are still on disk, you could recover them - // manually. This is not a perfect solution, but at least the user does not get an RS - return versions; - } - } - - @Override - public boolean addVersion(Versionable currentVersion, Identity identity, String comment, InputStream newFile) { - VFSLeaf currentFile = (VFSLeaf) currentVersion; - if (addToRevisions(currentVersion, identity, comment)) { - // copy the content of the new file to the old - if(newFile instanceof net.sf.jazzlib.ZipInputStream || newFile instanceof java.util.zip.ZipInputStream) { - newFile = new ShieldInputStream(newFile); - } - return VFSManager.copyContent(newFile, currentFile); - } else { - log.error("Cannot create a version of this file: " + currentVersion); - } - return false; - } - - @Override - public boolean move(VFSLeaf currentFile, VFSLeaf targetFile, Identity author) { - VFSLeaf fCurrentVersions = getCanonicalVersionXmlFile(currentFile, true); - Versions currentVersions = readVersions(currentFile, fCurrentVersions); - - boolean brandNewVersionFile = false; - VFSLeaf fTargetVersions = getCanonicalVersionXmlFile(targetFile, false); - if(fTargetVersions == null) { - brandNewVersionFile = true; - fTargetVersions = getCanonicalVersionXmlFile(targetFile, true); - } - - Versions targetVersions = readVersions(targetFile, fTargetVersions); - if(!(currentVersions instanceof VersionsFileImpl) || !(targetVersions instanceof VersionsFileImpl)) { - return false; - } - - VersionsFileImpl targetVersionsImpl = (VersionsFileImpl)targetVersions; - if(author != null) { - targetVersionsImpl.setAuthor(author.getName()); - } - if(brandNewVersionFile) { - targetVersionsImpl.setCreator(currentVersions.getCreator()); - targetVersionsImpl.setComment(currentVersions.getComment()); - } - - boolean allOk = true; - for(VFSRevision revision:currentVersions.getRevisions()) { - allOk &= copyRevision(revision, fTargetVersions, targetVersionsImpl); - } - - targetVersionsImpl.setRevisionNr(getNextRevisionNr(targetVersionsImpl)); - VFSXStream.write(fTargetVersions, targetVersionsImpl); - - return allOk; - } - - private boolean copyRevision(VFSRevision revision, VFSLeaf fNewVersions, VersionsFileImpl targetVersions) { - if(!(revision instanceof RevisionFileImpl)) { - log.warn("Copy only copy persisted revisions", null); - } - - RevisionFileImpl revisionImpl = (RevisionFileImpl)revision; - String revUuid = revisionImpl.getUuid(); - for(VFSRevision rev:targetVersions.getRevisions()) { - if(rev instanceof RevisionFileImpl) { - RevisionFileImpl fRev = (RevisionFileImpl)rev; - if(StringHelper.containsNonWhitespace(fRev.getUuid()) && fRev.getUuid().equals(revUuid)) { - return true; - } - } - } - - String uuid = UUID.randomUUID().toString().replace("-", "") + "_" + revision.getName(); - - RevisionFileImpl newRevision = new RevisionFileImpl(); - newRevision.setName(revision.getName()); - newRevision.setFilename(uuid); - newRevision.setRevisionNr(getNextRevisionNr(targetVersions)); - newRevision.setComment(revision.getComment()); - newRevision.setAuthor(revision.getAuthor()); - newRevision.setLastModified(revision.getLastModified()); - newRevision.setUuid(revUuid); - - //copy -> the files revision - try(InputStream revisionIn = revision.getInputStream()) { - VFSLeaf target = fNewVersions.getParentContainer().createChildLeaf(uuid); - if (VFSManager.copyContent(revisionIn, target)) { - targetVersions.setComment(revision.getComment()); - targetVersions.getRevisions().add(newRevision); - targetVersions.setRevisionNr(getNextRevisionNr(targetVersions)); - targetVersions.setAuthor(revision.getAuthor()); - return true; - } - } catch(Exception e) { - log.error("", e); - } - return false; - } - - @Override - public boolean copy(Versionable currentVersion, VFSContainer container) { - VFSLeaf currentFile = (VFSLeaf) currentVersion; - VFSLeaf fVersions = getCanonicalVersionXmlFile(currentFile, true); - Versions versions = readVersions(currentFile, fVersions); - - VFSContainer versionContainer = getCanonicalVersionFolder(container, true); - return copy(versionContainer, fVersions, versions); - } - - @Override - public boolean move(Versionable currentVersion, VFSContainer container) { - VFSLeaf currentFile = (VFSLeaf) currentVersion; - VFSLeaf fVersions = getCanonicalVersionXmlFile(currentFile, true); - Versions versions = readVersions(currentFile, fVersions); - - VFSContainer versionContainer = getCanonicalVersionFolder(container, true); - boolean allOk = copy(versionContainer, fVersions, versions); - - allOk &= VFSConstants.YES.equals(fVersions.delete()); - for (VFSRevision revision : versions.getRevisions()) { - VFSLeaf revisionFile = ((RevisionFileImpl) revision).getFile(); - if (revisionFile != null) { - allOk &= VFSConstants.YES.equals(revisionFile.delete()); - } - } - return allOk; - } - - private boolean copy(VFSContainer versionContainer, VFSLeaf fVersions, Versions versions) { - boolean allOk = VFSConstants.YES.equals(versionContainer.copyFrom(fVersions)); - for (VFSRevision revision : versions.getRevisions()) { - RevisionFileImpl revisionImpl = (RevisionFileImpl) revision; - VFSLeaf revisionFile = revisionImpl.getFile(); - if (revisionFile != null) { - allOk &= VFSConstants.YES.equals(versionContainer.copyFrom(revisionFile)); - } - } - return allOk; - } - - @Override - public boolean restore(Versionable currentVersion, VFSRevision version, String comment) { - VFSLeaf currentFile = (VFSLeaf) currentVersion; - if(!VFSManager.exists(currentFile)) { - return false; - } - - // add current version to versions file - if (addToRevisions(currentVersion, null, comment)) { - // copy the content of the new file to the old - if (VFSManager.copyContent(version.getInputStream(), currentFile)) { return true; } - } else { - log.error("Cannot create a version of this file: " + currentVersion); - } - - return false; - } - - @Override - public boolean restore(VFSContainer container, VFSRevision revision) { - String filename = revision.getName(); - VFSItem restoredItem = container.resolve(filename); - boolean restoreDeletedFile = restoredItem == null; - if (restoredItem == null) { - restoredItem = container.createChildLeaf(filename); - } - - if (restoredItem instanceof VFSLeaf) { - VFSLeaf restoredLeaf = (VFSLeaf) restoredItem; - try(InputStream inStream = revision.getInputStream()) { - if (VFSManager.copyContent(inStream, restoredLeaf)) { - VFSLeaf versionFile = getCanonicalVersionXmlFile(restoredLeaf, true); - Versions versions = readVersions(restoredLeaf, versionFile); - if (versions instanceof VersionsFileImpl) { - versions.getRevisions().remove(revision); - ((VersionsFileImpl) versions).setRevisionNr(getNextRevisionNr(versions)); - if (revision instanceof RevisionFileImpl) { - VFSLeaf fileToDelete = ((RevisionFileImpl)revision).getFile(); - if(fileToDelete != null) { - fileToDelete.deleteSilently(); - } - } - } - if (restoreDeletedFile && revision instanceof RevisionFileImpl) { - VFSMetadata versionedMetadata = ((RevisionFileImpl)revision).getMetadata(); - VFSMetadata metadata = restoredItem.getMetaInfo(); - if(versionedMetadata != null && metadata != null) { - metadata.copyValues(versionedMetadata); - // make sure the restored file is not locked - metadata.setLocked(false); - metadata.setLockedBy(null); - metadata.setLockedDate(null); - // restore last values - metadata.setUuid(versionedMetadata.getUuid()); - vfsRepositoryService.updateMetadata(metadata); - } - } - VFSXStream.write(versionFile, versions); - return true; - } - } catch(Exception e) { - log.error("", e); - } - } - return false; - } - - @Override - public boolean deleteRevisions(Versionable currentVersion, List<VFSRevision> versionsToDelete) { - VFSLeaf currentFile = (VFSLeaf) currentVersion; - Versions versions = readVersions(currentFile, true); - List<VFSRevision> allVersions = versions.getRevisions(); - - Map<String,VFSLeaf> filenamesToDelete = new HashMap<>(allVersions.size()); - for (VFSRevision versionToDelete : versionsToDelete) { - RevisionFileImpl versionImpl = (RevisionFileImpl) versionToDelete; - for (Iterator<VFSRevision> allVersionIt = allVersions.iterator(); allVersionIt.hasNext();) { - RevisionFileImpl allVersionImpl = (RevisionFileImpl) allVersionIt.next(); - if (allVersionImpl.getFilename() != null && allVersionImpl.getFilename().equals(versionImpl.getFilename())) { - allVersionIt.remove(); - break; - } - } - - VFSLeaf fileToDelete = versionImpl.getFile(); - if (fileToDelete != null) { - filenamesToDelete.put(fileToDelete.getName(), fileToDelete); - } - } - - List<RevisionFileImpl> missingFiles = new ArrayList<>(); - for(VFSRevision survivingVersion:allVersions) { - RevisionFileImpl survivingVersionImpl = (RevisionFileImpl)survivingVersion; - VFSLeaf revFile = survivingVersionImpl.getFile(); - if(revFile == null) { - missingFiles.add(survivingVersionImpl);//file is missing - } else if(filenamesToDelete.containsKey(revFile.getName())) { - filenamesToDelete.remove(revFile.getName()); - } - } - if(!missingFiles.isEmpty()) { - allVersions.removeAll(missingFiles); - } - - for(VFSLeaf fileToDelete:filenamesToDelete.values()) { - fileToDelete.deleteSilently(); - } - - VFSLeaf versionFile = getCanonicalVersionXmlFile(currentFile, true); - VFSXStream.write(versionFile, versions); - if (currentVersion.getVersions() instanceof VersionsFileImpl) { - ((VersionsFileImpl) currentVersion.getVersions()).update(versions); - } - return true; - } - - @Override - public boolean deleteVersions(VFSContainer container, List<Versions> versions) { - for(Versions versionToDelete:versions) { - if(versionToDelete instanceof VersionsFileImpl) { - VersionsFileImpl versionsImpl = (VersionsFileImpl)versionToDelete; - VFSLeaf versionFile = versionsImpl.getVersionFile(); - if(versionFile != null) { - //robust against manual file system manipulation - versionFile.deleteSilently(); - } - for (VFSRevision revisionToDelete : versionsImpl.getRevisions()) { - RevisionFileImpl versionImpl = (RevisionFileImpl)revisionToDelete; - VFSLeaf fileToDelete = versionImpl.getFile(); - if (fileToDelete != null) { - fileToDelete.deleteSilently(); - } - - String originFilename = versionImpl.getName(); - // delete - if(container.canMeta().equals(VFSConstants.YES) && container instanceof JavaIOItem) { - //if original was completely deleted, delete metadata too - File dir = ((JavaIOItem)container).getBasefile(); - File file = new File(dir, originFilename); - if(!file.exists()) { - vfsRepositoryService.deleteMetadata(file); - } - } - } - } - } - return true; - } - - @Override - public boolean delete(VFSItem item, boolean force) { - if (item instanceof VFSContainer) { - if (force) { - VFSContainer container = (VFSContainer)item; - VFSContainer versionContainer = getCanonicalVersionFolder(container, false); - if (versionContainer == null) { return true; } - return VFSConstants.YES.equals(versionContainer.delete()); - } - return true; - } else if (item instanceof VFSLeaf && item instanceof Versionable) { - VFSLeaf leaf = (VFSLeaf)item; - if (force || isTemporaryFile(leaf)) { - cleanUp(leaf); - } else { - Identity identity = ThreadLocalUserActivityLogger.getLoggedIdentity(); - addToRevisions((Versionable)leaf, identity, null); - } - } - return false; - } - - /** - * Some temporary/lock files of specific editors need to be force deleted - * with all versions. Word can reuse older names. - * @param leaf - * @return - */ - private boolean isTemporaryFile(VFSLeaf leaf) { - String name = leaf.getName(); - //temporary files - if(name.endsWith(".tmp")) { - //Word 2010: ~WRD0002.tmp - if(name.startsWith("~WRD") || name.startsWith("~WRL")) { - return true; - } - //PowerPoint 2010: ppt5101.tmp - if(name.startsWith("ppt")) { - return true; - } - } - //lock files of Word 2010, Excel 2010, PowerPoint 2010: - if(name.startsWith("~$") && (name.endsWith(".docx") || name.endsWith(".xlsx") || name.endsWith(".pptx"))) { - return true; - } - - //OpenOffice locks: .~lock.Versions_21.odt# - if(name.startsWith(".~lock.") && (name.endsWith(".odt#") /* Writer */ || name.endsWith(".ods#") /* Calc */ - || name.endsWith(".odp#") /* Impress */ || name.endsWith("odf#") /* Math */ - || name.endsWith(".odg#") /* Draw */)) { - return true; - } - //OpenOffice database lock - return name.endsWith(".odb.lck"); - } - - /** - * Clean up all revisions files, xml file - * @param leaf - */ - private void cleanUp(VFSLeaf leaf) { - String relPath = getRelPath(leaf); - if (relPath == null) return; // cannot handle - - File fVersion = new File(getRootVersionsFile(), relPath + ".xml"); - File fParentVersion = fVersion.getParentFile(); - if (!fParentVersion.exists()) return; //already deleted - - VFSLeaf versionLeaf = null; - if (fVersion.exists()) { - LocalFolderImpl localVersionContainer = new LocalFolderImpl(fParentVersion); - versionLeaf = (VFSLeaf) localVersionContainer.resolve(fVersion.getName()); - } - - if (versionLeaf == null) return; //already deleted - Versions versions = readVersions(leaf, versionLeaf); - for (VFSRevision versionToDelete : versions.getRevisions()) { - RevisionFileImpl versionImpl = (RevisionFileImpl) versionToDelete; - VFSLeaf fileToDelete = versionImpl.getFile(); - if (fileToDelete != null) { - fileToDelete.delete(); - } - } - versionLeaf.delete(); - } - - @Override - public boolean rename(VFSItem item, String newname) { - if (item instanceof VFSLeaf) { - VFSLeaf currentFile = (VFSLeaf) item; - VFSLeaf versionFile = getCanonicalVersionXmlFile(currentFile, true); - // infinite loop if rename is own versions file - return VFSConstants.YES.equals(versionFile.rename(newname + ".xml")); - } else if (item instanceof VFSContainer) { - VFSContainer container = (VFSContainer) item; - VFSContainer versionContainer = getCanonicalVersionFolder(container, false); - if (versionContainer == null) { return true; } - return VFSConstants.YES.equals(versionContainer.rename(newname)); - } - return false; - } - - @Override - public boolean addToRevisions(Versionable currentVersion, Identity identity, String comment) { - int maxNumOfVersions = versioningConfigurator.getMaxNumOfVersionsAllowed(); - if(maxNumOfVersions == 0) { - return true;//deactivated, return all ok - } - - VFSLeaf currentFile = (VFSLeaf) currentVersion; - - VFSLeaf versionFile = getCanonicalVersionXmlFile(currentFile, true); - if(versionFile == null) { - return false;//cannot do something with the current file - } - - VFSContainer versionContainer = versionFile.getParentContainer(); - - String name = currentFile.getName(); - - // read from the - Versions v = readVersions(currentFile, versionFile); - if (!(v instanceof VersionsFileImpl)) { - log.error("Wrong implementation of Versions: " + v); - return false; - } - VersionsFileImpl versions = (VersionsFileImpl) v; - boolean sameFile = isSameFile(currentFile, versions); - String uuid = sameFile ? getLastRevisionFilename(versions) - : UUID.randomUUID().toString() + "_" + name; - - String versionNr = getNextRevisionNr(versions); - String currentAuthor = versions.getAuthor(); - Date lastModifiedDate = null; - - VFSMetadata metaInfo = null; - if (currentFile.canMeta() == VFSConstants.YES) { - metaInfo = currentFile.getMetaInfo(); - if(metaInfo != null) { - vfsRepositoryService.resetThumbnails(currentFile); - if(currentAuthor == null && metaInfo.getAuthor() != null) { - currentAuthor = metaInfo.getAuthor().getName(); - } - lastModifiedDate = metaInfo.getLastModified(); - } - } - - if(lastModifiedDate == null) { - Calendar cal = Calendar.getInstance(); - cal.setTime(new Date()); - lastModifiedDate = cal.getTime(); - } - - RevisionFileImpl newRevision = new RevisionFileImpl(); - newRevision.setUuid(UUID.randomUUID().toString()); - newRevision.setName(name); - newRevision.setFilename(uuid); - newRevision.setRevisionNr(versionNr); - newRevision.setComment(versions.getComment()); - newRevision.setAuthor(currentAuthor); - newRevision.setLastModified(lastModifiedDate.getTime()); - //TODO metadata newRevision.setMetadata(metaInfo); - - if (versions.getRevisions().isEmpty() && currentVersion instanceof VFSItem) { - VFSMetadata currentMeta = ((VFSItem)currentVersion).getMetaInfo(); - if(currentMeta != null && currentMeta.getAuthor() != null) { - versions.setCreator(currentMeta.getAuthor().getName()); - } - } - - if (sameFile || VFSManager.copyContent(currentFile, versionContainer.createChildLeaf(uuid), false)) { - if (identity != null) { - versions.setAuthor(identity.getName()); - } - - 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)); - VFSXStream.write(versionFile, versions); - if (currentVersion.getVersions() instanceof VersionsFileImpl) { - ((VersionsFileImpl) currentVersion.getVersions()).update(versions); - } - return true; - } else { - log.error("Cannot create a version of this file: " + currentVersion); - } - return false; - } - - private boolean isSameFile(VFSLeaf currentFile, VersionsFileImpl versions) { - boolean same = false; - if(versions.getRevisions() != null && !versions.getRevisions().isEmpty()) { - VFSRevision lastRevision = versions.getRevisions().get(versions.getRevisions().size() -1); - - long lastSize = lastRevision.getSize(); - long currentSize = currentFile.getSize(); - if(currentSize == lastSize && currentSize > 0 - && lastRevision instanceof RevisionFileImpl - && currentFile instanceof LocalFileImpl) { - RevisionFileImpl lastRev = ((RevisionFileImpl)lastRevision); - LocalFileImpl current = (LocalFileImpl)currentFile; - //can be the same file - try { - Checksum cm1 = FileUtils.checksum(((LocalFileImpl)lastRev.getFile()).getBasefile() , new Adler32()); - Checksum cm2 = FileUtils.checksum(current.getBasefile() , new Adler32()); - same = cm1.getValue() == cm2.getValue(); - } catch (IOException e) { - log.debug("Error calculating the checksum of files"); - } - } - } - return same; - } - - @Override - public String getNextRevisionNr(Versions versions) { - int maxNumber = 0; - for (VFSRevision version : versions.getRevisions()) { - String versionNr = version.getRevisionNr(); - if (versionNr != null && versionNr.length() > 0) { - try { - int number = Integer.parseInt(versionNr); - maxNumber = Math.max(maxNumber, number); - } catch (Exception ex) { - // if not a number, don't interest us - } - } - } - return Integer.toString(maxNumber + 1); - } - - private String getLastRevisionFilename(Versions versions) { - if(versions.getRevisions() == null || versions.getRevisions().isEmpty()) { - return null; - } - - VFSRevision revision = versions.getRevisions().get(versions.getRevisions().size() - 1); - if(revision instanceof RevisionFileImpl) { - return ((RevisionFileImpl)revision).getFilename(); - } - return null; - } - - /** - * Get the canonical path to the file's meta file. - * - * @param bcPath - * @return String - */ - private VFSLeaf getCanonicalVersionXmlFile(VFSItem item, boolean create) { - File f = getOriginFile(item); - if (!f.exists()) { return null; } - - String relPath = getRelPath(item); - if (relPath == null) { - // cannot handle - return null; - } - - File fVersion = new File(getRootVersionsFile(), relPath + ".xml"); - File fParentVersion = fVersion.getParentFile(); - if (!fParentVersion.exists() && create) { - fParentVersion.mkdirs(); - } - - if (fVersion.exists()) { - LocalFolderImpl localVersionContainer = new LocalFolderImpl(fParentVersion); - return (VFSLeaf) localVersionContainer.resolve(fVersion.getName()); - } else if (create) { - LocalFolderImpl localVersionContainer = new LocalFolderImpl(fParentVersion); - VersionsFileImpl versions = new VersionsFileImpl(); - versions.setVersioned(isVersioned(item)); - versions.setRevisionNr(getNextRevisionNr(versions)); - VFSLeaf fVersions = localVersionContainer.createChildLeaf(fVersion.getName()); - if(fVersions != null) { - VFSXStream.write(fVersions, versions); - } - return fVersions; - } - return null; - } - - protected VFSContainer getCanonicalVersionFolder(VFSContainer container, boolean create) { - String relPath = getRelPath(container); - if(relPath != null) { - File fVersion = new File(getRootVersionsFile(), relPath); - if (fVersion.exists()) { - return new LocalFolderImpl(fVersion); - } - if (create) { - fVersion.mkdirs(); - return new LocalFolderImpl(fVersion); - } - } - return null; - } - - private String getRelPath(VFSItem item) { - if (item instanceof NamedContainerImpl) { - item = ((NamedContainerImpl)item).getDelegate(); - } - if (item instanceof MergeSource) { - item = ((MergeSource)item).getRootWriteContainer(); - } - return item.getRelPath(); - } - - private boolean isVersionFile(VFSItem item) { - File f = getOriginFile(item); - if (f == null) return false; - - try { - String path = f.getCanonicalPath(); - String vPath = getRootVersionsFile().getCanonicalPath(); - return path.startsWith(vPath); - } catch (IOException e) { - log.error("Cannot check if this file is a version file: " + item, e); - return false; - } - } - - private boolean isVersioned(VFSItem item) { - if (item == null) return false; - VFSContainer parent = item.getParentContainer(); - return FolderConfig.versionsEnabled(parent); - } - - private File getOriginFile(VFSItem item) { - if (item instanceof LocalImpl) { - LocalImpl localImpl = (LocalImpl) item; - return localImpl.getBasefile(); - } - - String relPath = item.getRelPath(); - if (relPath != null) { - return VFSManager.olatRootFile(relPath); - } - return null; - } - - public File getCanonicalRootFile() { - if(rootFolder == null) { - rootFolder = new File(FolderConfig.getCanonicalRoot()); - } - return rootFolder; - } - - public String getCanonicalRoot() { - return getCanonicalRootFile().getAbsolutePath(); - } - - public File getRootVersionsFile() { - if (rootVersionsContainer == null) { - rootVersionFolder = new File(FolderConfig.getCanonicalVersionRoot()); - if(!rootVersionFolder.exists()) { - rootVersionFolder.mkdirs(); - } - rootVersionsContainer = new LocalFolderImpl(rootVersionFolder); - } - return rootVersionFolder; - } - - public VFSContainer getRootVersionsContainer() { - if (rootVersionsContainer == null) { - rootVersionFolder = new File(FolderConfig.getCanonicalVersionRoot()); - if(!rootVersionFolder.exists()) { - rootVersionFolder.mkdirs(); - } - rootVersionsContainer = new LocalFolderImpl(rootVersionFolder); - } - return rootVersionsContainer; - } - - @Override - public int countDirectories() { - VFSContainer versionsContainer = getRootVersionsContainer(); - if(versionsContainer.exists()) { - return countDirectories(versionsContainer); - } - return 0; - } - - private int countDirectories(VFSContainer container) { - int count = 1;//itself - List<VFSItem> children = container.getItems(new VFSSystemItemFilter()); - for(VFSItem child:children) { - if(child instanceof VFSContainer) { - count += countDirectories((VFSContainer)child); - } - } - return count; - } - - @Override - public void pruneHistory(long maxHistoryLength, ProgressDelegate progress) { - VFSContainer versionsContainer = getRootVersionsContainer(); - if(!versionsContainer.exists()) { - return; - } - //delete folder without versioning first - - int count = 0; - String[] excludedRootFolders = new String[]{"tmp","scorm","forum","portfolio"}; - for(String excludedRootFolder:excludedRootFolders) { - VFSItem excludedContainer = versionsContainer.resolve(excludedRootFolder); - if(excludedContainer instanceof LocalFolderImpl) { - File excludedFile = ((LocalFolderImpl)excludedContainer).getBasefile(); - FileUtils.deleteQuietly(excludedFile); - if(progress != null) progress.setInfo(excludedContainer.getName()); - } - if(progress != null) progress.setActual(++count); - } - - if(maxHistoryLength < 0) { - //nothing to do - } else if(maxHistoryLength == 0 && versionsContainer instanceof LocalFolderImpl) { - //delete all the stuff - FileUtils.deleteQuietly(((LocalFolderImpl)versionsContainer).getBasefile()); - } else { - pruneVersionHistory(versionsContainer, maxHistoryLength, progress, count); - } - - if(progress != null) progress.finished(); - } - - private void pruneVersionHistory(VFSContainer container, long maxHistoryLength, ProgressDelegate progress, int count) { - List<VFSItem> children = container.getItems(new VFSSystemItemFilter()); - for(VFSItem child:children) { - if(child instanceof VFSContainer) { - if(progress != null) progress.setActual(++count); - pruneVersionHistory((VFSContainer)child, maxHistoryLength, progress, count); - } - if(child instanceof VFSLeaf) { - VFSLeaf versionsLeaf = (VFSLeaf)child; - pruneVersionHistory(versionsLeaf, maxHistoryLength, progress); - } - } - } - - private void pruneVersionHistory(VFSLeaf versionsLeaf, long maxHistoryLength, ProgressDelegate progress) { - if(versionsLeaf.getName().endsWith(".xml") && isVersionsXmlFile(versionsLeaf)) { - File originalFile = reversedOriginFile(versionsLeaf); - if(originalFile.exists()) { - VFSLeaf original = new LocalFileImpl(originalFile); - if(progress != null) progress.setInfo(original.getName()); - Versions versions = readVersions(original, versionsLeaf); - List<VFSRevision> revisions = versions.getRevisions(); - if(revisions.size() > maxHistoryLength) { - List<VFSRevision> revisionsToDelete = revisions.subList(0, revisions.size() - (int)maxHistoryLength); - deleteRevisions((Versionable)original, revisionsToDelete); - } - } - } - } - - @Override - public boolean deleteOrphans(ProgressDelegate progress) { - List<OrphanVersion> orphans = orphans(); - if(progress != null) progress.setMax(orphans.size()); - int count = 0; - for(OrphanVersion orphan:orphans) { - delete(orphan); - if(progress != null) { - progress.setActual(++count); - progress.setInfo(orphan.getOriginalFilePath()); - } - } - if(progress != null) progress.finished(); - return true; - } - - @Override - public boolean delete(OrphanVersion orphan) { - VFSLeaf versionLeaf = orphan.getVersionsLeaf(); - - if (versionLeaf == null) return true; //already deleted - Versions versions = orphan.getVersions(); - for (VFSRevision versionToDelete : versions.getRevisions()) { - RevisionFileImpl versionImpl = (RevisionFileImpl) versionToDelete; - versionImpl.setContainer(orphan.getVersionsLeaf().getParentContainer()); - VFSLeaf fileToDelete = versionImpl.getFile(); - if (fileToDelete != null) { - fileToDelete.delete(); - } - } - versionLeaf.delete(); - return true; - } - - @Override - public List<OrphanVersion> orphans() { - List<OrphanVersion> orphans = new ArrayList<>(); - VFSContainer versionsContainer = getRootVersionsContainer(); - crawlForOrphans(versionsContainer, orphans); - return orphans; - } - - private void crawlForOrphans(VFSContainer container, List<OrphanVersion> orphans) { - if(!container.exists()) { - return; - } - - List<VFSItem> children = container.getItems(); - for(VFSItem child:children) { - if(child instanceof VFSContainer) { - crawlForOrphans((VFSContainer)child, orphans); - } - if(child instanceof VFSLeaf) { - VFSLeaf versionsLeaf = (VFSLeaf)child; - if(child.getName().endsWith(".xml")) { - Versions versions = isOrphan(versionsLeaf); - if(versions == null) { - continue; - } else { - List<VFSRevision> revisions = versions.getRevisions(); - if(revisions != null) { - for(VFSRevision revision:revisions) { - if(revision instanceof RevisionFileImpl) { - ((RevisionFileImpl)revision).setContainer(container); - } - } - } - } - File originalFile = reversedOriginFile(child); - if(!originalFile.exists()) { - VFSLeaf orphan = new LocalFileImpl(originalFile); - orphans.add(new OrphanVersion(orphan, versionsLeaf, versions)); - } - } - } - } - } - - private Versions isOrphan(VFSLeaf potentialOrphan) { - try { - if(potentialOrphan.exists()) { - return (VersionsFileImpl) VFSXStream.read(potentialOrphan); - } - return null; - } catch (Exception e) { - return null; - } - } - - private File reversedOriginFile(VFSItem versionXml) { - String path = File.separatorChar + versionXml.getName().substring(0, versionXml.getName().length() - 4); - for(VFSContainer parent=versionXml.getParentContainer(); parent != null && !parent.isSame(getRootVersionsContainer()); parent = parent.getParentContainer()) { - path = File.separatorChar + parent.getName() + path; - } - - return new File(getCanonicalRoot(), path); - } -} diff --git a/src/main/java/org/olat/core/util/vfs/version/VersionsManager.java b/src/main/java/org/olat/core/util/vfs/version/VersionsManager.java deleted file mode 100644 index 3cd8d2e8d36c15e9092d17625d1ef93951dc83e6..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/core/util/vfs/version/VersionsManager.java +++ /dev/null @@ -1,203 +0,0 @@ -/** - * <a href="http://www.openolat.org"> - * OpenOLAT - Online Learning and Training</a><br> - * <p> - * Licensed under the Apache License, Version 2.0 (the "License"); <br> - * you may not use this file except in compliance with the License.<br> - * You may obtain a copy of the License at the - * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> - * <p> - * Unless required by applicable law or agreed to in writing,<br> - * software distributed under the License is distributed on an "AS IS" BASIS, <br> - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> - * See the License for the specific language governing permissions and <br> - * limitations under the License. - * <p> - * Initial code contributed and copyrighted by<br> - * frentix GmbH, http://www.frentix.com - * <p> - */ -package org.olat.core.util.vfs.version; - -import java.io.InputStream; -import java.util.List; - -import org.olat.core.configuration.ConfigOnOff; -import org.olat.core.id.Identity; -import org.olat.core.util.async.ProgressDelegate; -import org.olat.core.util.vfs.VFSContainer; -import org.olat.core.util.vfs.VFSItem; -import org.olat.core.util.vfs.VFSLeaf; - -/** - * - * Description:<br> - * - * - * <P> - * Initial Date: 21 sept. 2009 <br> - * - * @author srosse - */ -public interface VersionsManager extends ConfigOnOff { - - /** - * Get or create the versions datas of this file - * - * @param a file - * @return - */ - public Versions createVersionsFor(VFSLeaf leaf); - - /** - * Get or create the versions datas of this file - * - * @param a file - * @param force the creation of the file - * @return - */ - public Versions createVersionsFor(VFSLeaf leaf, boolean force); - - /** - * Return the list of deleted files in this container. - * - * @param container - * @return - */ - public List<Versions> getDeletedFiles(VFSContainer container); - - /** - * Only used internally - * - * @param versions - * @return - */ - public String getNextRevisionNr(Versions versions); - - /** - * Add a new version of the file. The current version will be saved and - * secured, The new version replaced the old one. - * - * @param currentVersion - * @param author - * @param comment - * @param newVersion - * @return - */ - public boolean addVersion(Versionable currentVersion, Identity author, String comment, InputStream newVersion); - - /** - * Add a new revision to the files. The method check the number of revisions against the absolute - * maximum limit for the instance. - * @param currentVersion - * @param author - * @param comment - * @return - */ - public boolean addToRevisions(Versionable currentVersion, Identity author, String comment); - - /** - * Move a versioned file to the target container - * - * @param currentVersion - * @param target container - * @return - */ - public boolean move(Versionable currentVersion, VFSContainer container); - - /** - * Copy a versioned file to the target container - * - * @param currentVersion - * @param target container - * @return - */ - public boolean copy(Versionable currentVersion, VFSContainer container); - - /** - * Move a versioned file to an other (WebDAV only!!!) - * - * @param currentVersion - * @param oldVersion - * @return - */ - public boolean move(VFSLeaf currentFile, VFSLeaf targetFile, Identity author); - - /** - * Restore a versioned file to the selected revision. The current version is - * secured before being replaced by the revision's file - * - * @param currentVersion - * @param version - * @return - */ - public boolean restore(Versionable currentVersion, VFSRevision version, String comment); - - /** - * Restore a revision in the target container, usefull to restore deleted - * files - * - * @param target container - * @param selected revision - * @return - */ - public boolean restore(VFSContainer container, VFSRevision revision); - - /** - * Delete a list of revisions from a file - * - * @param currentVersion - * @param revisionsToDelete - * @return - */ - public boolean deleteRevisions(Versionable currentVersion, List<VFSRevision> revisionsToDelete); - - /** - * Delete and remove from versioning a list of deleted versions (files) - * @param versions - * @return - */ - public boolean deleteVersions(VFSContainer container, List<Versions> versions); - - /** - * Delete a full container - * - * @param container - * @param force, if true delete it definitely (the deleted files don't appear - * in the list of deleted files) - * @return - */ - public boolean delete(VFSItem item, boolean force); - - /** - * Rename a file and propagate the change to the version. - * - * @param item - * @param newname - * @return - */ - public boolean rename(VFSItem item, String newname); - - /** - * @return The list of orphans - */ - public List<OrphanVersion> orphans(); - - /** - * @param orphan - * @return - */ - public boolean delete(OrphanVersion orphan); - - /** - * Delete the orphans - * @return - */ - public boolean deleteOrphans(ProgressDelegate progress); - - - public void pruneHistory(long historyLength, ProgressDelegate progress); - - - public int countDirectories(); -} diff --git a/src/main/java/org/olat/course/PersistingCourseImpl.java b/src/main/java/org/olat/course/PersistingCourseImpl.java index bc7c0b34d5e7a40d7956eb2123771202aba6acf3..f314db25c66fbd636fa57af8ffca60c7b9a788f0 100644 --- a/src/main/java/org/olat/course/PersistingCourseImpl.java +++ b/src/main/java/org/olat/course/PersistingCourseImpl.java @@ -26,11 +26,13 @@ package org.olat.course; import java.io.File; +import java.io.InputStream; import java.io.Serializable; import org.olat.admin.quota.QuotaConstants; import org.olat.core.CoreSpringFactory; import org.olat.core.commons.persistence.DBFactory; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.id.IdentityEnvironment; import org.olat.core.id.OLATResourceable; import org.olat.core.logging.AssertException; @@ -49,8 +51,6 @@ import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSManager; import org.olat.core.util.vfs.callbacks.FullAccessWithLazyQuotaCallback; import org.olat.core.util.vfs.callbacks.FullAccessWithQuotaCallback; -import org.olat.core.util.vfs.version.Versionable; -import org.olat.core.util.vfs.version.VersionsManager; import org.olat.core.util.xml.XStreamHelper; import org.olat.course.assessment.AssessmentHelper; import org.olat.course.config.CourseConfig; @@ -446,18 +446,18 @@ public class PersistingCourseImpl implements ICourse, OLATResourceable, Serializ * @param obj */ private void writeObject(String fileName, Object obj) { - VFSItem vfsItem = getCourseBaseContainer().resolve(fileName); + VFSLeaf vfsItem =(VFSLeaf)getCourseBaseContainer().resolve(fileName); if (vfsItem == null) { vfsItem = getCourseBaseContainer().createChildLeaf(fileName); - } else if(vfsItem.exists() && vfsItem instanceof Versionable) { - try { - CoreSpringFactory.getImpl(VersionsManager.class).addToRevisions((Versionable)vfsItem, null, ""); + } else if(vfsItem.exists()) { + try(InputStream in=vfsItem.getInputStream()) { + CoreSpringFactory.getImpl(VFSRepositoryService.class).addVersion(vfsItem, null, "", in); } catch (Exception e) { log.error("Cannot versioned " + fileName, e); } } XStream xstream = CourseXStreamAliases.getWriteCourseXStream(); - XStreamHelper.writeObject(xstream, (VFSLeaf)vfsItem, obj); + XStreamHelper.writeObject(xstream, vfsItem, obj); } /** diff --git a/src/main/java/org/olat/course/config/manager/CourseConfigManagerImpl.java b/src/main/java/org/olat/course/config/manager/CourseConfigManagerImpl.java index 40e7d43e8cc6282daff3e68a10a448b01df752a2..15a9185ab2a8d943c4ceed4459d22a118c8988a7 100644 --- a/src/main/java/org/olat/course/config/manager/CourseConfigManagerImpl.java +++ b/src/main/java/org/olat/course/config/manager/CourseConfigManagerImpl.java @@ -25,17 +25,17 @@ package org.olat.course.config.manager; +import java.io.InputStream; import java.util.HashMap; import java.util.Hashtable; import org.olat.core.CoreSpringFactory; +import org.olat.core.commons.services.vfs.VFSRepositoryService; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; 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.VersionsManager; import org.olat.core.util.xml.XStreamHelper; import org.olat.course.ICourse; import org.olat.course.config.CourseConfig; @@ -106,9 +106,9 @@ public class CourseConfigManagerImpl implements CourseConfigManager { if (configFile == null) { // create new config file configFile = course.getCourseBaseContainer().createChildLeaf(COURSECONFIG_XML); - } else if(configFile.exists() && configFile instanceof Versionable) { - try { - CoreSpringFactory.getImpl(VersionsManager.class).addToRevisions((Versionable)configFile, null, ""); + } else if(configFile.exists() && configFile.canVersion() == VFSConstants.YES) { + try(InputStream in = configFile.getInputStream()) { + CoreSpringFactory.getImpl(VFSRepositoryService.class).addVersion(configFile, null, "", in); } catch (Exception e) { log.error("Cannot versioned CourseConfig.xml", e); } diff --git a/src/main/java/org/olat/course/nodes/bc/BCWebService.java b/src/main/java/org/olat/course/nodes/bc/BCWebService.java index 83aecd4b8f2f95c7d9d63c0aaa2a0629cac4f82d..f93258dfa1a947e9984b2b44f2bcee579f531ce1 100644 --- a/src/main/java/org/olat/course/nodes/bc/BCWebService.java +++ b/src/main/java/org/olat/course/nodes/bc/BCWebService.java @@ -48,6 +48,7 @@ import javax.ws.rs.core.Response.Status; import org.olat.core.CoreSpringFactory; import org.olat.core.commons.services.notifications.NotificationsManager; import org.olat.core.commons.services.notifications.Subscriber; +import org.olat.core.commons.services.vfs.restapi.VFSWebservice; import org.olat.core.gui.UserRequest; import org.olat.core.id.IdentityEnvironment; import org.olat.core.util.StringHelper; @@ -55,7 +56,6 @@ import org.olat.core.util.nodes.INode; import org.olat.core.util.tree.Visitor; import org.olat.core.util.vfs.VFSContainer; import org.olat.core.util.vfs.callbacks.VFSSecurityCallback; -import org.olat.core.util.vfs.restapi.VFSWebservice; import org.olat.course.ICourse; import org.olat.course.condition.Condition; import org.olat.course.nodes.BCCourseNode; diff --git a/src/main/java/org/olat/modules/fo/restapi/ForumWebService.java b/src/main/java/org/olat/modules/fo/restapi/ForumWebService.java index 26c08eebac15e2506959b8e7a9391d5b8ddc4ec1..2ab810f59ca548f7dddfb9006d86c46af9e08d6f 100644 --- a/src/main/java/org/olat/modules/fo/restapi/ForumWebService.java +++ b/src/main/java/org/olat/modules/fo/restapi/ForumWebService.java @@ -60,6 +60,7 @@ import org.apache.commons.io.IOUtils; import org.olat.basesecurity.BaseSecurity; import org.olat.basesecurity.OrganisationRoles; import org.olat.basesecurity.model.IdentityRefImpl; +import org.olat.core.commons.services.vfs.restapi.VFSStreamingOutput; import org.olat.core.gui.media.ServletUtil; import org.olat.core.id.Identity; import org.olat.core.id.Roles; @@ -74,7 +75,6 @@ import org.olat.core.util.vfs.VFSItem; import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSManager; import org.olat.core.util.vfs.filters.VFSSystemItemFilter; -import org.olat.core.util.vfs.restapi.VFSStreamingOutput; import org.olat.modules.fo.Forum; import org.olat.modules.fo.Message; import org.olat.modules.fo.manager.ForumManager; diff --git a/src/main/java/org/olat/modules/wiki/Wiki.java b/src/main/java/org/olat/modules/wiki/Wiki.java index b3312589401095078e3278e6dd4ca183ff86b87a..1fcbd81e4ad8e2616f9893efa528630732faaeb9 100644 --- a/src/main/java/org/olat/modules/wiki/Wiki.java +++ b/src/main/java/org/olat/modules/wiki/Wiki.java @@ -313,7 +313,7 @@ public class Wiki implements WikiContainer, Serializable { List<VFSItem> mediaFilesOnly = new ArrayList<>(); for (Iterator<VFSItem> iter = allFiles.iterator(); iter.hasNext();) { VFSItem element = iter.next(); - if(!element.getName().endsWith(WikiMainController.METADATA_SUFFIX)) {//TODO metadata + if(!element.getName().endsWith(WikiMainController.METADATA_SUFFIX)) {//TODO mediaFilesOnly.add(element); } } diff --git a/src/main/java/org/olat/portfolio/ui/artefacts/collect/EPCreateFileArtefactStepForm00.java b/src/main/java/org/olat/portfolio/ui/artefacts/collect/EPCreateFileArtefactStepForm00.java index 17457c95caabdd735276d64f1fc90afb2a2a11e3..425247f485b8d837c79314cef319361e5acd6009 100644 --- a/src/main/java/org/olat/portfolio/ui/artefacts/collect/EPCreateFileArtefactStepForm00.java +++ b/src/main/java/org/olat/portfolio/ui/artefacts/collect/EPCreateFileArtefactStepForm00.java @@ -33,11 +33,8 @@ import org.olat.core.gui.control.generic.wizard.StepsEvent; import org.olat.core.gui.control.generic.wizard.StepsRunContext; import org.olat.core.util.StringHelper; import org.olat.core.util.vfs.VFSContainer; -import org.olat.core.util.vfs.VFSLeaf; -import org.olat.core.util.vfs.VFSManager; import org.olat.portfolio.manager.EPFrontendManager; import org.olat.portfolio.model.artefacts.AbstractArtefact; -import org.olat.portfolio.model.artefacts.FileArtefact; /** * Description:<br> @@ -127,9 +124,9 @@ public class EPCreateFileArtefactStepForm00 extends StepFormBasicController { } private void saveUpload(){ - VFSLeaf contFile = vfsTemp.createChildLeaf(fileupload.getUploadFileName()); - VFSManager.copyContent(fileupload.getUploadInputStream(), contFile); - ((FileArtefact) artefact).setFilename(fileupload.getUploadFileName()); + //VFSLeaf contFile = vfsTemp.createChildLeaf(fileupload.getUploadFileName()); + //VFSManager.copyContent(fileupload.getUploadInputStream(), contFile); + fileupload.moveUploadFileTo(vfsTemp); } /** diff --git a/src/main/java/org/olat/restapi/group/LearningGroupWebService.java b/src/main/java/org/olat/restapi/group/LearningGroupWebService.java index 693efc2974b393b4b682f353436c3d23c1f68417..ebd51b8c33c6cfda6daabb6cf06235478c830bae 100644 --- a/src/main/java/org/olat/restapi/group/LearningGroupWebService.java +++ b/src/main/java/org/olat/restapi/group/LearningGroupWebService.java @@ -52,6 +52,8 @@ import org.olat.collaboration.CollaborationTools; import org.olat.collaboration.CollaborationToolsFactory; import org.olat.core.CoreSpringFactory; import org.olat.core.commons.services.notifications.SubscriptionContext; +import org.olat.core.commons.services.vfs.restapi.VFSWebServiceSecurityCallback; +import org.olat.core.commons.services.vfs.restapi.VFSWebservice; import org.olat.core.gui.UserRequest; import org.olat.core.id.Identity; import org.olat.core.logging.OLog; @@ -62,8 +64,6 @@ import org.olat.core.util.vfs.Quota; import org.olat.core.util.vfs.QuotaManager; import org.olat.core.util.vfs.VFSManager; import org.olat.core.util.vfs.callbacks.VFSSecurityCallback; -import org.olat.core.util.vfs.restapi.VFSWebServiceSecurityCallback; -import org.olat.core.util.vfs.restapi.VFSWebservice; import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroupAddResponse; import org.olat.group.BusinessGroupService; diff --git a/src/main/java/org/olat/restapi/repository/SharedFolderWebService.java b/src/main/java/org/olat/restapi/repository/SharedFolderWebService.java index 46121afd806ba90dda906a827e94bd13f88019ed..715010598c00fcaee68f33b031ada390c48c49ec 100644 --- a/src/main/java/org/olat/restapi/repository/SharedFolderWebService.java +++ b/src/main/java/org/olat/restapi/repository/SharedFolderWebService.java @@ -40,13 +40,13 @@ import javax.ws.rs.core.Response.Status; import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriInfo; +import org.olat.core.commons.services.vfs.restapi.VFSWebservice; import org.olat.core.util.WebappHelper; 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.ReadOnlyCallback; import org.olat.core.util.vfs.filters.VFSSystemItemFilter; -import org.olat.core.util.vfs.restapi.VFSWebservice; import org.olat.modules.sharedfolder.SharedFolderManager; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryManager; diff --git a/src/main/java/org/olat/restapi/repository/course/CourseGroupWebService.java b/src/main/java/org/olat/restapi/repository/course/CourseGroupWebService.java index 9927b2ea39d710f8624045ade28df71ddc9e7044..1fc933d17f413be087396a85338618e4adf10c4f 100644 --- a/src/main/java/org/olat/restapi/repository/course/CourseGroupWebService.java +++ b/src/main/java/org/olat/restapi/repository/course/CourseGroupWebService.java @@ -43,14 +43,14 @@ import org.olat.collaboration.CollaborationTools; import org.olat.collaboration.CollaborationToolsFactory; import org.olat.core.CoreSpringFactory; import org.olat.core.commons.services.notifications.SubscriptionContext; +import org.olat.core.commons.services.vfs.restapi.VFSWebServiceSecurityCallback; +import org.olat.core.commons.services.vfs.restapi.VFSWebservice; import org.olat.core.gui.UserRequest; import org.olat.core.id.Identity; import org.olat.core.util.vfs.Quota; import org.olat.core.util.vfs.QuotaManager; import org.olat.core.util.vfs.VFSContainer; import org.olat.core.util.vfs.VFSManager; -import org.olat.core.util.vfs.restapi.VFSWebServiceSecurityCallback; -import org.olat.core.util.vfs.restapi.VFSWebservice; import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroupService; import org.olat.group.model.SearchBusinessGroupParams; diff --git a/src/main/java/org/olat/restapi/repository/course/CourseResourceFolderWebService.java b/src/main/java/org/olat/restapi/repository/course/CourseResourceFolderWebService.java index 0710b29b240328cfb71eb8f65613d42ef6171bae..601c3482ebdfa6237b495c0e6de2a9b34d57d27f 100644 --- a/src/main/java/org/olat/restapi/repository/course/CourseResourceFolderWebService.java +++ b/src/main/java/org/olat/restapi/repository/course/CourseResourceFolderWebService.java @@ -64,7 +64,6 @@ import org.olat.core.util.vfs.VFSLockApplicationType; import org.olat.core.util.vfs.VFSLockManager; import org.olat.core.util.vfs.callbacks.ReadOnlyCallback; import org.olat.core.util.vfs.filters.VFSSystemItemFilter; -import org.olat.core.util.vfs.version.Versionable; import org.olat.course.ICourse; import org.olat.course.config.CourseConfig; import org.olat.modules.sharedfolder.SharedFolderManager; @@ -349,32 +348,29 @@ public class CourseResourceFolderWebService { return Response.serverError().status(Status.UNAUTHORIZED).build(); } - if (existingVFSItem instanceof Versionable && ((Versionable)existingVFSItem).getVersions().isVersioned()) { - Versionable existingVersionableItem = (Versionable)existingVFSItem; - boolean ok = existingVersionableItem.getVersions().addVersion(ureq.getIdentity(), "REST upload", file); - if(ok) { - log.audit(""); - } - newFile = (VFSLeaf)existingVersionableItem; + if (existingVFSItem instanceof VFSLeaf && existingVFSItem.canVersion() == VFSConstants.YES) { + VFSLeaf existingLeaf = (VFSLeaf)existingVFSItem; + vfsRepositoryService.addVersion(existingLeaf, ureq.getIdentity(), "REST upload", file); + newFile = existingLeaf; } else { existingVFSItem.delete(); newFile = container.createChildLeaf(filename); OutputStream out = ((VFSLeaf)newFile).getOutputStream(false); - FileUtils.copy(file, out); + FileUtils.copy(file, out);//TODO metadata use VFSManager ? FileUtils.closeSafely(out); FileUtils.closeSafely(file); } } else if (file != null) { newFile = container.createChildLeaf(filename); OutputStream out = ((VFSLeaf)newFile).getOutputStream(false); - FileUtils.copy(file, out); + FileUtils.copy(file, out);//TODO metadata use VFSManager ? FileUtils.closeSafely(out); FileUtils.closeSafely(file); } else { newFile = container.createChildContainer(filename); } - if(newFile.canMeta() == VFSConstants.YES ) { + if(newFile.canMeta() == VFSConstants.YES) { VFSMetadata infos = newFile.getMetaInfo(); infos.setAuthor(ureq.getIdentity()); vfsRepositoryService.updateMetadata(infos); diff --git a/src/main/java/org/olat/user/restapi/UserFoldersWebService.java b/src/main/java/org/olat/user/restapi/UserFoldersWebService.java index 06b717f6ffcb2e067d70b1489e48dc651e95368d..b30a860a85badd0be7c53112528387a0522068f4 100644 --- a/src/main/java/org/olat/user/restapi/UserFoldersWebService.java +++ b/src/main/java/org/olat/user/restapi/UserFoldersWebService.java @@ -49,6 +49,7 @@ import org.olat.core.commons.modules.bc.BriefcaseWebDAVProvider; import org.olat.core.commons.modules.bc.FolderConfig; import org.olat.core.commons.services.notifications.NotificationsManager; import org.olat.core.commons.services.notifications.Subscriber; +import org.olat.core.commons.services.vfs.restapi.VFSWebservice; import org.olat.core.id.Identity; import org.olat.core.id.IdentityEnvironment; import org.olat.core.id.Roles; @@ -58,7 +59,6 @@ import org.olat.core.util.vfs.VFSContainer; import org.olat.core.util.vfs.VFSManager; import org.olat.core.util.vfs.callbacks.ReadOnlyCallback; import org.olat.core.util.vfs.callbacks.VFSSecurityCallback; -import org.olat.core.util.vfs.restapi.VFSWebservice; import org.olat.course.CourseFactory; import org.olat.course.ICourse; import org.olat.course.nodes.BCCourseNode; diff --git a/src/main/resources/META-INF/persistence.xml b/src/main/resources/META-INF/persistence.xml index 063618908ae8f0a8d981e2d8c81a796947ba92df..f19d1a7eba2b3eaf4d9f9ba49c195e4242393665 100644 --- a/src/main/resources/META-INF/persistence.xml +++ b/src/main/resources/META-INF/persistence.xml @@ -96,6 +96,7 @@ <class>org.olat.core.commons.services.vfs.model.VFSMetadataFileSaved</class> <class>org.olat.core.commons.services.vfs.model.VFSMetadataDownloadCount</class> <class>org.olat.core.commons.services.vfs.model.VFSThumbnailMetadataImpl</class> + <class>org.olat.core.commons.services.vfs.model.VFSRevisionImpl</class> <class>org.olat.course.assessment.model.AssessmentModeImpl</class> <class>org.olat.course.assessment.model.AssessmentModeToAreaImpl</class> <class>org.olat.course.assessment.model.AssessmentModeToGroupImpl</class> diff --git a/src/main/resources/database/mysql/alter_13_2_x_to_13_3_0.sql b/src/main/resources/database/mysql/alter_13_2_x_to_13_3_0.sql index 9e53a48280516c2c00ccf473bef12f57e94a6a13..59ac4246ad14d7fe64206c900ac25d3dfb56555a 100644 --- a/src/main/resources/database/mysql/alter_13_2_x_to_13_3_0.sql +++ b/src/main/resources/database/mysql/alter_13_2_x_to_13_3_0.sql @@ -4,6 +4,7 @@ create table o_vfs_metadata ( creationdate datetime not null, lastmodified datetime not null, f_uuid varchar(64) not null, + f_deleted boolean default 0 not null, f_filename varchar(256) not null, f_relative_path varchar(2048) not null, f_directory bool default false, @@ -29,6 +30,8 @@ create table o_vfs_metadata ( f_licensor text(4000), f_locked_date timestamp, f_locked bool default false, + f_revision_nr bigint default 0 not null, + f_revision_comment text(32000), f_m_path_keys varchar(1024), fk_locked_identity bigint, fk_license_type bigint, @@ -68,5 +71,40 @@ alter table o_vfs_thumbnail ENGINE = InnoDB; alter table o_vfs_thumbnail add constraint fthumb_to_meta_idx foreign key (fk_metadata) references o_vfs_metadata (id); +create table o_vfs_revision ( + id bigint not null auto_increment, + creationdate datetime not null, + lastmodified datetime not null, + f_revision_size bigint default 0 not null, + f_revision_nr bigint default 0 not null, + f_revision_filename varchar(256) not null, + f_revision_comment text(32000), + f_revision_lastmodified datetime not null, + f_comment text(32000), + f_title varchar(2000), + f_publisher varchar(2000), + f_creator varchar(2000), + f_source varchar(2000), + f_city varchar(256), + f_pages varchar(16), + f_language varchar(16), + f_url text(1024), + f_pub_month varchar(16), + f_pub_year varchar(16), + f_license_type_name varchar(256), + f_license_text mediumtext, + f_licensor text(4000), + fk_license_type bigint, + fk_author bigint, + fk_metadata bigint not null, + primary key (id) +); + +alter table o_vfs_revision ENGINE = InnoDB; + +alter table o_vfs_revision add constraint fvers_to_author_idx foreign key (fk_author) references o_bs_identity (id); +alter table o_vfs_revision add constraint fvers_to_meta_idx foreign key (fk_metadata) references o_vfs_metadata (id); +alter table o_vfs_metadata add constraint fvers_to_lic_type_idx foreign key (fk_license_type) references o_lic_license_type (id); + diff --git a/src/main/resources/database/mysql/setupDatabase.sql b/src/main/resources/database/mysql/setupDatabase.sql index b70d5d51b38df7b38e20b28ff7fa9490a4253a2c..74bc0f9d68976561b57221555b4f81b14c548d68 100644 --- a/src/main/resources/database/mysql/setupDatabase.sql +++ b/src/main/resources/database/mysql/setupDatabase.sql @@ -1686,6 +1686,7 @@ create table o_vfs_metadata ( creationdate datetime not null, lastmodified datetime not null, f_uuid varchar(64) not null, + f_deleted boolean default 0 not null, f_filename varchar(256) not null, f_relative_path varchar(2048) not null, f_directory bool default false, @@ -1713,6 +1714,8 @@ create table o_vfs_metadata ( f_locked bool default false, f_m_path_keys varchar(1024), fk_locked_identity bigint, + f_revision_nr bigint default 0 not null, + f_revision_comment text(32000), fk_license_type bigint, fk_author bigint, fk_parent bigint, @@ -1734,6 +1737,35 @@ create table o_vfs_thumbnail ( primary key (id) ); +create table o_vfs_revision ( + id bigint not null auto_increment, + creationdate datetime not null, + lastmodified datetime not null, + f_revision_size bigint default 0 not null, + f_revision_nr bigint default 0 not null, + f_revision_filename varchar(256) not null, + f_revision_comment text(32000), + f_revision_lastmodified datetime not null, + f_comment text(32000), + f_title varchar(2000), + f_publisher varchar(2000), + f_creator varchar(2000), + f_source varchar(2000), + f_city varchar(256), + f_pages varchar(16), + f_language varchar(16), + f_url text(1024), + f_pub_month varchar(16), + f_pub_year varchar(16), + f_license_type_name varchar(256), + f_license_text mediumtext, + f_licensor text(4000), + fk_license_type bigint, + fk_author bigint, + fk_metadata bigint not null, + primary key (id) +); + -- portfolio create table o_pf_binder ( id bigint not null auto_increment, @@ -3097,6 +3129,7 @@ alter table o_qual_generator_to_org ENGINE = InnoDB; alter table o_qual_analysis_presentation ENGINE = InnoDB; alter table o_vfs_metadata ENGINE = InnoDB; alter table o_vfs_thumbnail ENGINE = InnoDB; +alter table o_vfs_revision ENGINE = InnoDB; alter table o_sms_message_log ENGINE = InnoDB; alter table o_feed ENGINE = InnoDB; alter table o_feed_item ENGINE = InnoDB; @@ -3597,6 +3630,10 @@ create index f_m_filename_idx on o_vfs_metadata (f_filename(255)); alter table o_vfs_thumbnail add constraint fthumb_to_meta_idx foreign key (fk_metadata) references o_vfs_metadata (id); +alter table o_vfs_revision add constraint fvers_to_author_idx foreign key (fk_author) references o_bs_identity (id); +alter table o_vfs_revision add constraint fvers_to_meta_idx foreign key (fk_metadata) references o_vfs_metadata (id); +alter table o_vfs_metadata add constraint fvers_to_lic_type_idx foreign key (fk_license_type) references o_lic_license_type (id); + -- quality management alter table o_qual_data_collection add constraint qual_dc_to_gen_idx foreign key (fk_generator) references o_qual_generator (id); create index idx_dc_status_idx on o_qual_data_collection (q_status); diff --git a/src/main/resources/database/oracle/alter_13_2_x_to_13_3_0.sql b/src/main/resources/database/oracle/alter_13_2_x_to_13_3_0.sql index 999ca3814b5ce1f71998d01b1265d5b38dcd3699..6faaa5f880be3b0e2430851fd5a5d258b45aff64 100644 --- a/src/main/resources/database/oracle/alter_13_2_x_to_13_3_0.sql +++ b/src/main/resources/database/oracle/alter_13_2_x_to_13_3_0.sql @@ -3,6 +3,7 @@ create table o_vfs_metadata ( creationdate timestamp not null, lastmodified timestamp not null, f_uuid varchar(64) not null, + f_deleted number default 0 not null, f_filename varchar(256) not null, f_relative_path varchar(2048) not null, f_directory number default 0, @@ -28,6 +29,8 @@ create table o_vfs_metadata ( f_licensor varchar(4000), f_locked_date timestamp, f_locked number default 0, + f_revision_nr number(20) default 0 not null, + f_revision_comment varchar(32000), f_m_path_keys varchar(1024), fk_locked_identity number(20), fk_license_type number(20), @@ -67,3 +70,41 @@ create table o_vfs_thumbnail ( alter table o_vfs_thumbnail add constraint fthumb_to_meta_idx foreign key (fk_metadata) references o_vfs_metadata (id); create index idx_fthumb_to_meta_idx on o_vfs_thumbnail (fk_metadata); + +create table o_vfs_revision ( + id number(20) generated always as identity, + creationdate timestamp not null, + lastmodified timestamp not null, + f_revision_size number(20) default 0 not null, + f_revision_nr number(20) default 0 not null, + f_revision_filename varchar(256) not null, + f_revision_comment varchar(32000), + f_revision_lastmodified timestamp not null, + f_comment varchar(32000), + f_title varchar(2000), + f_publisher varchar(2000), + f_creator varchar(2000), + f_source varchar(2000), + f_city varchar(256), + f_pages varchar(2000), + f_language varchar(16), + f_url varchar(1024), + f_pub_month varchar(16), + f_pub_year varchar(16), + f_license_type_name varchar(256), + f_license_text CLOB, + f_licensor varchar(4000), + fk_license_type number(20), + fk_author number(20), + fk_metadata number(20) not null, + primary key (id) +); + +alter table o_vfs_revision add constraint fvers_to_author_idx foreign key (fk_author) references o_bs_identity (id); +create index idx_fvers_to_author_idx on o_vfs_revision (fk_author); +alter table o_vfs_revision add constraint fvers_to_meta_idx foreign key (fk_metadata) references o_vfs_metadata (id); +create index idx_fvers_to_meta_idx on o_vfs_revision (fk_metadata); +alter table o_vfs_revision add constraint fvers_to_lic_type_idx foreign key (fk_license_type) references o_lic_license_type (id); +create index idx_fvers_to_lic_type_idx on o_vfs_revision (fk_license_type); + + diff --git a/src/main/resources/database/oracle/setupDatabase.sql b/src/main/resources/database/oracle/setupDatabase.sql index 4824214ded791b0410144bd45d6a294a5a694a6f..356a54d716e6acac5699d8e7508e2a559ef2a332 100644 --- a/src/main/resources/database/oracle/setupDatabase.sql +++ b/src/main/resources/database/oracle/setupDatabase.sql @@ -1664,6 +1664,35 @@ create table o_vfs_thumbnail ( primary key (id) ); +create table o_vfs_revision ( + id number(20) generated always as identity, + creationdate timestamp not null, + lastmodified timestamp not null, + f_revision_size number(20) default 0 not null, + f_revision_nr number(20) default 0 not null, + f_revision_filename varchar(256) not null, + f_revision_comment varchar(32000), + f_revision_lastmodified timestamp not null, + f_comment varchar(32000), + f_title varchar(2000), + f_publisher varchar(2000), + f_creator varchar(2000), + f_source varchar(2000), + f_city varchar(256), + f_pages varchar(2000), + f_language varchar(16), + f_url varchar(1024), + f_pub_month varchar(16), + f_pub_year varchar(16), + f_license_type_name varchar(256), + f_license_text CLOB, + f_licensor varchar(4000), + fk_license_type number(20), + fk_author number(20), + fk_metadata number(20) not null, + primary key (id) +); + -- portfolio create table o_pf_binder ( id number(20) GENERATED ALWAYS AS IDENTITY, @@ -3628,6 +3657,13 @@ create index f_m_filename_idx on o_vfs_metadata (f_filename); alter table o_vfs_thumbnail add constraint fthumb_to_meta_idx foreign key (fk_metadata) references o_vfs_metadata (id); create index idx_fthumb_to_meta_idx on o_vfs_thumbnail (fk_metadata); +alter table o_vfs_revision add constraint fvers_to_author_idx foreign key (fk_author) references o_bs_identity (id); +create index idx_fvers_to_author_idx on o_vfs_revision (fk_author); +alter table o_vfs_revision add constraint fvers_to_meta_idx foreign key (fk_metadata) references o_vfs_metadata (id); +create index idx_fvers_to_meta_idx on o_vfs_revision (fk_metadata); +alter table o_vfs_revision add constraint fvers_to_lic_type_idx foreign key (fk_license_type) references o_lic_license_type (id); +create index idx_fvers_to_lic_type_idx on o_vfs_revision (fk_license_type); + -- portfolio alter table o_pf_binder add constraint pf_binder_resource_idx foreign key (fk_olatresource_id) references o_olatresource (resource_id); create index idx_pf_binder_resource_idx on o_pf_binder (fk_olatresource_id); diff --git a/src/main/resources/database/postgresql/alter_13_2_x_to_13_3_0.sql b/src/main/resources/database/postgresql/alter_13_2_x_to_13_3_0.sql index 08ccac477dd9feabf2455492558181e5d5f374a4..646f00ab4e5545dc47d82c3c13c6ae6b8ab3f3ff 100644 --- a/src/main/resources/database/postgresql/alter_13_2_x_to_13_3_0.sql +++ b/src/main/resources/database/postgresql/alter_13_2_x_to_13_3_0.sql @@ -4,6 +4,7 @@ create table o_vfs_metadata ( creationdate timestamp not null, lastmodified timestamp not null, f_uuid varchar(64) not null, + f_deleted bool default false not null, f_filename varchar(256) not null, f_relative_path varchar(2048) not null, f_directory bool default false, @@ -29,6 +30,8 @@ create table o_vfs_metadata ( f_licensor varchar(4000), f_locked_date timestamp, f_locked bool default false, + f_revision_nr bigint default 0 not null, + f_revision_comment varchar(32000), f_m_path_keys varchar(1024), fk_locked_identity bigint, fk_license_type bigint, @@ -68,3 +71,43 @@ create table o_vfs_thumbnail ( alter table o_vfs_thumbnail add constraint fthumb_to_meta_idx foreign key (fk_metadata) references o_vfs_metadata (id); create index idx_fthumb_to_meta_idx on o_vfs_thumbnail (fk_metadata); + +create table o_vfs_revision ( + id bigserial, + creationdate timestamp not null, + lastmodified timestamp not null, + f_revision_size bigint default 0 not null, + f_revision_nr bigint default 0 not null, + f_revision_filename varchar(256) not null, + f_revision_comment varchar(32000), + f_revision_lastmodified timestamp not null, + f_comment varchar(32000), + f_title varchar(2000), + f_publisher varchar(2000), + f_creator varchar(2000), + f_source varchar(2000), + f_city varchar(256), + f_pages varchar(2000), + f_language varchar(16), + f_url varchar(1024), + f_pub_month varchar(16), + f_pub_year varchar(16), + f_license_type_name varchar(256), + f_license_text text, + f_licensor varchar(4000), + fk_license_type bigint, + fk_author bigint, + fk_metadata bigint not null, + primary key (id) +); + +alter table o_vfs_revision add constraint fvers_to_author_idx foreign key (fk_author) references o_bs_identity (id); +create index idx_fvers_to_author_idx on o_vfs_revision (fk_author); +alter table o_vfs_revision add constraint fvers_to_meta_idx foreign key (fk_metadata) references o_vfs_metadata (id); +create index idx_fvers_to_meta_idx on o_vfs_revision (fk_metadata); +alter table o_vfs_revision add constraint fvers_to_lic_type_idx foreign key (fk_license_type) references o_lic_license_type (id); +create index idx_fvers_to_lic_type_idx on o_vfs_revision (fk_license_type); + + + + diff --git a/src/main/resources/database/postgresql/setupDatabase.sql b/src/main/resources/database/postgresql/setupDatabase.sql index f04b654639ab0c8a047c0fc88f2b659c9bb2e28e..fd61561d79a331751d3eee49b62677449fdc4701 100644 --- a/src/main/resources/database/postgresql/setupDatabase.sql +++ b/src/main/resources/database/postgresql/setupDatabase.sql @@ -1579,6 +1579,7 @@ create table o_vfs_metadata ( creationdate timestamp not null, lastmodified timestamp not null, f_uuid varchar(64) not null, + f_deleted bool default false not null, f_filename varchar(256) not null, f_relative_path varchar(2048) not null, f_directory bool default false, @@ -1604,6 +1605,8 @@ create table o_vfs_metadata ( f_licensor varchar(4000), f_locked_date timestamp, f_locked bool default false, + f_revision_nr bigint default 0 not null, + f_revision_comment varchar(32000), f_m_path_keys varchar(1024), fk_locked_identity bigint, fk_license_type bigint, @@ -1627,6 +1630,35 @@ create table o_vfs_thumbnail ( primary key (id) ); +create table o_vfs_revision ( + id bigserial, + creationdate timestamp not null, + lastmodified timestamp not null, + f_revision_size bigint default 0 not null, + f_revision_nr bigint default 0 not null, + f_revision_filename varchar(256) not null, + f_revision_comment varchar(32000), + f_revision_lastmodified timestamp not null, + f_comment varchar(32000), + f_title varchar(2000), + f_publisher varchar(2000), + f_creator varchar(2000), + f_source varchar(2000), + f_city varchar(256), + f_pages varchar(2000), + f_language varchar(16), + f_url varchar(1024), + f_pub_month varchar(16), + f_pub_year varchar(16), + f_license_type_name varchar(256), + f_license_text text, + f_licensor varchar(4000), + fk_license_type bigint, + fk_author bigint, + fk_metadata bigint not null, + primary key (id) +); + -- portfolio create table o_pf_binder ( id bigserial, @@ -3589,6 +3621,13 @@ create index f_m_filename_idx on o_vfs_metadata (f_filename); alter table o_vfs_thumbnail add constraint fthumb_to_meta_idx foreign key (fk_metadata) references o_vfs_metadata (id); create index idx_fthumb_to_meta_idx on o_vfs_thumbnail (fk_metadata); +alter table o_vfs_revision add constraint fvers_to_author_idx foreign key (fk_author) references o_bs_identity (id); +create index idx_fvers_to_author_idx on o_vfs_revision (fk_author); +alter table o_vfs_revision add constraint fvers_to_meta_idx foreign key (fk_metadata) references o_vfs_metadata (id); +create index idx_fvers_to_meta_idx on o_vfs_revision (fk_metadata); +alter table o_vfs_revision add constraint fvers_to_lic_type_idx foreign key (fk_license_type) references o_lic_license_type (id); +create index idx_fvers_to_lic_type_idx on o_vfs_revision (fk_license_type); + -- evaluation form alter table o_eva_form_survey add constraint eva_surv_to_surv_idx foreign key (fk_series_previous) references o_eva_form_survey (id); create unique index idx_eva_surv_ores_idx on o_eva_form_survey (e_resid, e_resname, e_sub_ident); diff --git a/src/test/java/org/olat/core/commons/services/vfs/manager/VFSMetadataDAOTest.java b/src/test/java/org/olat/core/commons/services/vfs/manager/VFSMetadataDAOTest.java index cff00b3cf6cad7012bb79afa84e37f145965ed03..c6fa47af0799a019f3dcc22b5e64ffb392a1aa2c 100644 --- a/src/test/java/org/olat/core/commons/services/vfs/manager/VFSMetadataDAOTest.java +++ b/src/test/java/org/olat/core/commons/services/vfs/manager/VFSMetadataDAOTest.java @@ -141,7 +141,7 @@ public class VFSMetadataDAOTest extends OlatTestCase { dbInstance.commitAndCloseSession(); Assert.assertNotNull(metadata); - vfsMetadataDao.updateMetadata(12345l, relativePath, filename); + vfsMetadataDao.updateMetadata(12345l, new Date(),relativePath, filename); dbInstance.commitAndCloseSession(); VFSMetadata loadedMetadata = vfsMetadataDao.loadMetadata(metadata.getKey()); diff --git a/src/test/java/org/olat/core/commons/services/vfs/manager/VFSRevisionDAOTest.java b/src/test/java/org/olat/core/commons/services/vfs/manager/VFSRevisionDAOTest.java new file mode 100644 index 0000000000000000000000000000000000000000..e99f109090a5657182d1d9f7f856c47bbfb247f1 --- /dev/null +++ b/src/test/java/org/olat/core/commons/services/vfs/manager/VFSRevisionDAOTest.java @@ -0,0 +1,76 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.vfs.manager; + +import java.util.Date; +import java.util.List; +import java.util.UUID; + +import org.junit.Assert; +import org.junit.Test; +import org.olat.core.commons.persistence.DB; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRevision; +import org.olat.core.id.Identity; +import org.olat.test.JunitTestHelper; +import org.olat.test.OlatTestCase; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * + * Initial date: 18 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class VFSRevisionDAOTest extends OlatTestCase { + + @Autowired + private DB dbInstance; + @Autowired + private VFSRevisionDAO revisionDao; + @Autowired + private VFSMetadataDAO vfsMetadataDao; + + @Test + public void createRevision() { + Identity author = JunitTestHelper.createAndPersistIdentityAsRndUser("rev-1"); + VFSMetadata metadata = vfsMetadataDao.createMetadata(UUID.randomUUID().toString(), "test/revs", "text.txt", + new Date(), 10l, false, "file:///text.tx", "file", null); + VFSRevision revision = revisionDao.createRevision(author, "._oo_vr_1_text.txt", 1, 25l, new Date(), "A comment", metadata); + dbInstance.commitAndCloseSession(); + + Assert.assertNotNull(revision); + } + + @Test + public void getRevisions() { + Identity author = JunitTestHelper.createAndPersistIdentityAsRndUser("rev-1"); + VFSMetadata metadata = vfsMetadataDao.createMetadata(UUID.randomUUID().toString(), "test/revs", "text.txt", + new Date(), 10l, false, "file:///text.tx", "file", null); + VFSRevision revision = revisionDao.createRevision(author, "._oo_vr_1_text.txt", 1, 25l, new Date(), "A comment", metadata); + dbInstance.commitAndCloseSession(); + + List<VFSRevision> revisions = revisionDao.getRevisions(metadata); + Assert.assertNotNull(revisions); + Assert.assertEquals(1, revisions.size()); + Assert.assertEquals(revision, revisions.get(0)); + } + +} diff --git a/src/test/java/org/olat/core/commons/services/vfs/manager/VFSVersioningTest.java b/src/test/java/org/olat/core/commons/services/vfs/manager/VFSVersioningTest.java new file mode 100644 index 0000000000000000000000000000000000000000..22d2a108994927861f7f657d4a8108e994e89e09 --- /dev/null +++ b/src/test/java/org/olat/core/commons/services/vfs/manager/VFSVersioningTest.java @@ -0,0 +1,637 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.vfs.manager; + +import static org.junit.Assert.assertEquals; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.Callable; + +import org.apache.commons.io.IOUtils; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.olat.core.commons.persistence.DB; +import org.olat.core.commons.services.vfs.VFSMetadata; +import org.olat.core.commons.services.vfs.VFSRepositoryService; +import org.olat.core.commons.services.vfs.VFSRevision; +import org.olat.core.commons.services.vfs.VFSVersionModule; +import org.olat.core.commons.services.vfs.model.VFSRevisionImpl; +import org.olat.core.id.Identity; +import org.olat.core.util.vfs.VFSConstants; +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.VFSManager; +import org.olat.core.util.vfs.filters.VFSItemFilter; +import org.olat.test.JunitTestHelper; +import org.olat.test.OlatTestCase; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * + * Initial date: 20 mars 2019<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class VFSVersioningTest extends OlatTestCase { + + @Autowired + private DB dbInstance; + @Autowired + private VFSVersionModule versionsModule; + @Autowired + private VFSRepositoryService vfsRepositoryService; + + @Before + public void setUp() throws Exception { + waitForCondition(new SetMaxNumberOfVersions(versionsModule, 10l), 2000); + } + + @After + public void resetMaxVersions() { + int maxNumberOfVersions = versionsModule.getMaxNumberOfVersions(); + if(maxNumberOfVersions != 10) { + versionsModule.setMaxNumberOfVersions(10); + waitForCondition(new SetMaxNumberOfVersions(versionsModule, 10l), 2000); + } + } + + @Test + public void addVersions() throws IOException { + Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("vers-1"); + + //create a file + VFSContainer rootTest = VFSManager.olatRootContainer("/test", null); + String filename = UUID.randomUUID().toString() + ".txt"; + VFSLeaf file = rootTest.createChildLeaf(filename); + int byteCopied = copyTestTxt(file); + Assert.assertFalse(byteCopied == 0); + VFSMetadata data = vfsRepositoryService.getMetadataFor(file); + data.setAuthor(id); + vfsRepositoryService.updateMetadata(data); + dbInstance.commitAndCloseSession(); + + //save a first version + InputStream in1 = new ByteArrayInputStream("Hello version 1".getBytes()); + vfsRepositoryService.addVersion(file, id, "Version 1", in1); + in1.close(); + + //save a second version + InputStream in2 = new ByteArrayInputStream("Hello version 2".getBytes()); + vfsRepositoryService.addVersion(file, id, "Version 2", in2); + in2.close(); + + //save a third version + InputStream in3 = new ByteArrayInputStream("Hello version 3".getBytes()); + vfsRepositoryService.addVersion(file, id, "Version 3", in3); + in3.close(); + + //make the checks + VFSItem retrievedFile = rootTest.resolve(filename); + VFSMetadata metadata = vfsRepositoryService.getMetadataFor(retrievedFile); + List<VFSRevision> revisions = vfsRepositoryService.getRevisions(metadata); + Assert.assertNotNull(revisions); + Assert.assertEquals(3, revisions.size()); + + VFSRevision revision0 = revisions.get(0); + //we don't set an author for the original file + Assert.assertEquals(id, revision0.getAuthor());//TODO remove the first author + VFSRevision revision1 = revisions.get(1); + Assert.assertEquals(id, revision1.getAuthor()); + VFSRevision revision2 = revisions.get(2); + Assert.assertEquals(id, revision2.getAuthor()); + + //check the comments + Assert.assertNull(revision0.getRevisionComment()); + Assert.assertEquals("Version 1", revision1.getRevisionComment()); + Assert.assertEquals("Version 2", revision2.getRevisionComment()); + Assert.assertEquals("Version 3", metadata.getRevisionComment()); + } + + @Test + public void addVersions_overflow_lowLevel() throws IOException { + versionsModule.setMaxNumberOfVersions(3); + waitForCondition(new SetMaxNumberOfVersions(versionsModule, 3l), 2000); + + Identity id2 = JunitTestHelper.createAndPersistIdentityAsRndUser("vers-2"); + + //create a file + VFSContainer rootTest = VFSManager.olatRootContainer("/test_" + UUID.randomUUID(), null); + String filename = UUID.randomUUID().toString() + ".txt"; + VFSLeaf file = rootTest.createChildLeaf(filename); + int byteCopied = copyTestTxt(file); + Assert.assertFalse(byteCopied == 0); + + //save a first version + for(int i=0; i<5; i++) { + InputStream inv = new ByteArrayInputStream(("Hello version " + i).getBytes()); + vfsRepositoryService.addVersion(file, id2, "Version " + (1 +i), inv); + inv.close(); + } + + VFSItem retrievedFile = rootTest.resolve(filename); + VFSMetadata metadata = vfsRepositoryService.getMetadataFor(retrievedFile); + List<VFSRevision> revisions = vfsRepositoryService.getRevisions(metadata); + Assert.assertNotNull(revisions); + Assert.assertEquals(3, revisions.size()); + Assert.assertEquals(3, revisions.get(0).getRevisionNr()); + Assert.assertEquals(4, revisions.get(1).getRevisionNr()); + Assert.assertEquals(5, revisions.get(2).getRevisionNr()); + + Assert.assertEquals("Version 5", metadata.getRevisionComment()); + Assert.assertEquals(id2, revisions.get(2).getAuthor()); + } + + @Test + public void addVersions_overflow_lowLevel_deactivated() throws IOException { + versionsModule.setMaxNumberOfVersions(0); + waitForCondition(new SetMaxNumberOfVersions(versionsModule, 0l), 2000); + + Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("vers-"); + + //create a file + VFSContainer rootTest = VFSManager.olatRootContainer("/test_" + UUID.randomUUID(), null); + String filename = UUID.randomUUID().toString() + ".txt"; + VFSLeaf file = rootTest.createChildLeaf(filename); + int byteCopied = copyTestTxt(file); + Assert.assertFalse(byteCopied == 0); + + //save a first version + for(int i=0; i<5; i++) { + InputStream inv = new ByteArrayInputStream(("Hello version " + i).getBytes()); + vfsRepositoryService.addVersion(file, id, "Version " + (1 +i), inv); + inv.close(); + } + + VFSItem retrievedFile = rootTest.resolve(filename); + VFSMetadata metadata = vfsRepositoryService.getMetadataFor(retrievedFile); + List<VFSRevision> revisions = vfsRepositoryService.getRevisions(metadata); + Assert.assertNotNull(revisions); + Assert.assertTrue(revisions.isEmpty()); + } + + @Test + public void versionChecksum() throws IOException { + VFSContainer rootTest = VFSManager.olatRootContainer("/ver-" + UUID.randomUUID(), null); + String filename = UUID.randomUUID().toString() + ".txt"; + VFSLeaf file = rootTest.createChildLeaf(filename); + int byteCopied = copyTestTxt(file); + Assert.assertFalse(byteCopied == 0); + + Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("vers-4"); + + //save a first version + InputStream in1 = VFSVersioningTest.class.getResourceAsStream("test.txt"); + vfsRepositoryService.addVersion(file, id, "Version 1", in1); + in1.close(); + + //save a second version + InputStream in2 = VFSVersioningTest.class.getResourceAsStream("test.txt"); + vfsRepositoryService.addVersion(file, id, "Version 2", in2); + in2.close(); + + //save a third version + InputStream in3 = VFSVersioningTest.class.getResourceAsStream("test.txt"); + vfsRepositoryService.addVersion(file, id, "Version 3", in2); + in3.close(); + + //check if there is only one backup file + VFSContainer versionContainer = file.getParentContainer(); + List<VFSItem> items = versionContainer.getItems(new VersionsFilter(filename)); + Assert.assertEquals(1, items.size());// TODO metadata was 2 but 1 seems correcter + + //check number of versions + VFSItem reloadFile = rootTest.resolve(filename); + VFSMetadata metadata = vfsRepositoryService.getMetadataFor(reloadFile); + List<VFSRevision> revisions = vfsRepositoryService.getRevisions(metadata); + Assert.assertNotNull(revisions); + Assert.assertEquals(3, revisions.size()); + } + + @Test + public void container_copyFrom() throws IOException { + Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("vers-11"); + + //create a file + VFSContainer rootTest = VFSManager.olatRootContainer("/test_" + UUID.randomUUID(), null); + VFSContainer targetRootTest = rootTest.createChildContainer("Copy"); + String filename = UUID.randomUUID().toString() + ".txt"; + VFSLeaf file = rootTest.createChildLeaf(filename); + int byteCopied = copyTestTxt(file); + Assert.assertFalse(byteCopied == 0); + + //save a first version + for(int i=0; i<2; i++) { + InputStream inv = new ByteArrayInputStream(("Hello version " + i).getBytes()); + vfsRepositoryService.addVersion(file, id, "Version " + (1 +i), inv); + inv.close(); + } + + targetRootTest.copyFrom(file); + dbInstance.commitAndCloseSession(); + + VFSItem targetFile = targetRootTest.resolve(filename); + VFSMetadata targetMetadata = vfsRepositoryService.getMetadataFor(targetFile); + List<VFSRevision> revisions = vfsRepositoryService.getRevisions(targetMetadata); + Assert.assertNotNull(revisions); + Assert.assertEquals(2, revisions.size()); + for(VFSRevision revision:revisions) { + VFSItem revFile = targetRootTest.resolve(((VFSRevisionImpl)revision).getFilename()); + Assert.assertNotNull(revFile); + Assert.assertTrue(revFile.exists()); + Assert.assertTrue(revFile instanceof VFSLeaf); + Assert.assertTrue(((VFSLeaf)revFile).getSize() > 4); + } + } + + /** + * The test create an original file and 3 revisions with exactly + * the same content. We delete the original and the first version. + * We check that version 2 and 3 survives and that the file exists. + * + * @throws IOException + */ + @Test + public void deleteVersions_withSameFile() throws IOException { + VFSContainer rootTest = VFSManager.olatRootContainer("/ver-" + UUID.randomUUID(), null); + String filename = UUID.randomUUID().toString() + ".txt"; + VFSLeaf file = rootTest.createChildLeaf(filename); + int byteCopied = copyTestTxt(file); + Assert.assertFalse(byteCopied == 0); + + Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("vers-5"); + + //save a first version + InputStream in1 = VFSVersioningTest.class.getResourceAsStream("test.txt"); + vfsRepositoryService.addVersion(file, id, "Version 1", in1); + in1.close(); + + //save a second version + InputStream in2 = VFSVersioningTest.class.getResourceAsStream("test.txt"); + vfsRepositoryService.addVersion(file, id, "Version 2", in2); + in2.close(); + + //save a third version + InputStream in3 = VFSVersioningTest.class.getResourceAsStream("test.txt"); + vfsRepositoryService.addVersion(file, id, "Version 3", in2); + in3.close(); + + //delete revisions + VFSItem reloadFile = rootTest.resolve(filename); + VFSMetadata metadata = vfsRepositoryService.getMetadataFor(reloadFile); + List<VFSRevision> revisions = vfsRepositoryService.getRevisions(metadata); + vfsRepositoryService.deleteRevisions(id, revisions.subList(0, 2)); + dbInstance.commitAndCloseSession(); + + //check number of versions + List<VFSRevision> trimmedRevisions = vfsRepositoryService.getRevisions(metadata); + + Assert.assertNotNull(trimmedRevisions); + Assert.assertEquals(1, trimmedRevisions.size()); + //check surviving versions + Assert.assertEquals("Version 2", trimmedRevisions.get(0).getRevisionComment()); + Assert.assertEquals("Version 3", metadata.getRevisionComment()); + //check that the last backup file exists + VFSRevisionImpl revision2 = (VFSRevisionImpl)trimmedRevisions.get(0); + VFSItem revision2File = reloadFile.getParentContainer().resolve(revision2.getFilename()); + Assert.assertNotNull(revision2File); + Assert.assertTrue(revision2File.exists()); + Assert.assertTrue(revision2File instanceof VFSLeaf); + + //check if there is only one backup file + VFSContainer versionContainer = reloadFile.getParentContainer(); + List<VFSItem> items = versionContainer.getItems(new VersionsFilter(filename)); + Assert.assertEquals(1, items.size()); + } + + /** + * The test create an original file and 5 versions. It manually + * delete the physical back up file. We delete the versions + * of the orginal, 1 and 2. At the end, there is only version 4 + * and 5. + * + * + * @throws IOException + */ + @Test + public void deleteVersions_withMissingRevisionFile() throws IOException { + VFSContainer rootTest = VFSManager.olatRootContainer("/ver-" + UUID.randomUUID(), null); + String filename = UUID.randomUUID().toString() + ".txt"; + VFSLeaf file = rootTest.createChildLeaf(filename); + int byteCopied = copyTestTxt(file); + Assert.assertFalse(byteCopied == 0); + + Identity id2 = JunitTestHelper.createAndPersistIdentityAsRndUser("vers-6"); + + //save a first version + InputStream in1 = new ByteArrayInputStream("Hello version 1".getBytes()); + vfsRepositoryService.addVersion(file, id2, "Version 1", in1); + in1.close(); + + //save a second version + InputStream in2 = new ByteArrayInputStream("Hello version 2".getBytes()); + vfsRepositoryService.addVersion(file, id2, "Version 2", in2); + in2.close(); + + //save a third version + InputStream in3 = new ByteArrayInputStream("Hello version 3".getBytes()); + vfsRepositoryService.addVersion(file, id2, "Version 3", in3); + in3.close(); + + //save a fourth version + InputStream in4 = new ByteArrayInputStream("Hello version 4".getBytes()); + vfsRepositoryService.addVersion(file, id2, "Version 4", in4); + in4.close(); + + //save a fourth version + InputStream in5 = new ByteArrayInputStream("Hello version 5".getBytes()); + vfsRepositoryService.addVersion(file, id2, "Version 5", in5); + in5.close(); + + dbInstance.commitAndCloseSession(); + + //delete a specific + VFSMetadata metadata = vfsRepositoryService.getMetadataFor(file); + List<VFSRevision> revisions = vfsRepositoryService.getRevisions(metadata); + VFSRevision rev4 = revisions.get(3); + VFSRevisionImpl toDeleteVersionImpl = (VFSRevisionImpl)rev4; + VFSItem itemToDelete = file.getParentContainer().resolve(toDeleteVersionImpl.getFilename()); + itemToDelete.deleteSilently(); + + //delete revisions + List<VFSRevision> toDelete = new ArrayList<>(revisions.subList(0, 3)); + vfsRepositoryService.deleteRevisions(id2, toDelete); + + dbInstance.commitAndCloseSession(); + + //check number of versions + VFSItem reloadFile = rootTest.resolve(filename); + VFSMetadata reloadedMetadata = vfsRepositoryService.getMetadataFor(reloadFile); + List<VFSRevision> reloadedRevisions = vfsRepositoryService.getRevisions(reloadedMetadata); + + Assert.assertNotNull(reloadedRevisions); + Assert.assertEquals(1, reloadedRevisions.size()); + VFSRevision revision = reloadedRevisions.get(0); + Assert.assertEquals("Version 4", revision.getRevisionComment()); + Assert.assertEquals("Version 5", reloadedMetadata.getRevisionComment()); + + //check if there is only one backup file + VFSContainer versionContainer = file.getParentContainer(); + List<VFSItem> items = versionContainer.getItems(new VersionsFilter(filename)); + Assert.assertEquals(1, items.size()); + } + + @Test + public void verionsWithAuthorsAndCreators() throws IOException { + //create a file + VFSContainer rootTest = VFSManager.olatRootContainer("/ver" + UUID.randomUUID(), null); + String filename = UUID.randomUUID().toString() + ".txt"; + VFSLeaf file = rootTest.createChildLeaf(filename); + int byteCopied = copyTestTxt(file); + Assert.assertFalse(byteCopied == 0); + Assert.assertEquals(VFSConstants.YES, file.canMeta()); + + Identity id1 = JunitTestHelper.createAndPersistIdentityAsRndUser("vers-7"); + Identity id2 = JunitTestHelper.createAndPersistIdentityAsRndUser("vers-8"); + + //set the author + VFSMetadata metadata = vfsRepositoryService.getMetadataFor(file); + metadata.setAuthor(id1); + metadata.setCreator(id1.getName()); + metadata = vfsRepositoryService.updateMetadata(metadata); + dbInstance.commitAndCloseSession(); + + //save a first version -> id2 + InputStream in1 = new ByteArrayInputStream("Hello version 1".getBytes()); + vfsRepositoryService.addVersion(file, id2, "Version 1", in1); + in1.close(); + + //save a second version -> id1 + InputStream in2 = new ByteArrayInputStream("Hello version 2".getBytes()); + vfsRepositoryService.addVersion(file, id1, "Version 2", in2); + in2.close(); + + //save a third version -> id2 + InputStream in3 = new ByteArrayInputStream("Hello version 3".getBytes()); + vfsRepositoryService.addVersion(file, id2, "Version 3", in3); + in3.close(); + + //make the checks + VFSItem retrievedFile = rootTest.resolve(filename); + metadata = vfsRepositoryService.getMetadataFor(file); + List<VFSRevision> revisions = vfsRepositoryService.getRevisions(metadata); + Assert.assertNotNull(revisions); + Assert.assertEquals(3, revisions.size()); + Assert.assertEquals(VFSConstants.YES, retrievedFile.canMeta()); + + VFSRevision revision0 = revisions.get(0); + //we don't set an author for the original file + Assert.assertEquals(id1, revision0.getAuthor()); + VFSRevision revision1 = revisions.get(1); + Assert.assertEquals(id2, revision1.getAuthor()); + VFSRevision revision2 = revisions.get(2); + Assert.assertEquals(id1, revision2.getAuthor()); + //current + Assert.assertEquals(id2, metadata.getAuthor()); + } + + @Test + public void deleteLeaf() throws IOException { + //create a file + VFSContainer rootTest = VFSManager.olatRootContainer("/ver" + UUID.randomUUID(), null); + String filename = UUID.randomUUID().toString() + ".txt"; + VFSLeaf file = rootTest.createChildLeaf(filename); + int byteCopied = copyTestTxt(file); + Assert.assertFalse(byteCopied == 0); + Assert.assertEquals(VFSConstants.YES, file.canMeta()); + + Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("vers-12"); + + //save a first version -> id + InputStream in1 = new ByteArrayInputStream("Hello version 1".getBytes()); + vfsRepositoryService.addVersion(file, id, "Version 1", in1); + in1.close(); + + dbInstance.commitAndCloseSession(); + VFSMetadata metadata = vfsRepositoryService.getMetadataFor(file); + + + // make sure the version is there + List<VFSItem> revFiles = file.getParentContainer().getItems(new VersionsFilter(filename)); + Assert.assertEquals(1, revFiles.size()); + + // delete all metadata and versions + file.deleteSilently(); + dbInstance.commitAndCloseSession(); + + List<VFSRevision> revisions = vfsRepositoryService.getRevisions(metadata); + Assert.assertTrue(revisions.isEmpty()); + List<VFSItem> deletedRevFiles = file.getParentContainer().getItems(new VersionsFilter(filename)); + Assert.assertTrue(deletedRevFiles.isEmpty()); + } + + @Test + public void rename_leaf() throws IOException { + //create a file + VFSContainer rootTest = VFSManager.olatRootContainer("/ver" + UUID.randomUUID(), null); + String filename = UUID.randomUUID().toString() + ".txt"; + VFSLeaf file = rootTest.createChildLeaf(filename); + int byteCopied = copyTestTxt(file); + Assert.assertFalse(byteCopied == 0); + Assert.assertEquals(VFSConstants.YES, file.canMeta()); + + Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("vers-12"); + + //save a first version -> id + InputStream in1 = new ByteArrayInputStream("Hello, move me".getBytes()); + vfsRepositoryService.addVersion(file, id, "Version 1", in1); + in1.close(); + dbInstance.commitAndCloseSession(); + + VFSMetadata metadata = vfsRepositoryService.getMetadataFor(file); + + // make sure the version is there + List<VFSItem> revFiles = file.getParentContainer().getItems(new VersionsFilter(filename)); + Assert.assertEquals(1, revFiles.size()); + + // delete all metadata and versions + String newName = "IMoved.txt"; + file.rename(newName); + dbInstance.commitAndCloseSession(); + + List<VFSRevision> revisions = vfsRepositoryService.getRevisions(metadata); + Assert.assertEquals(1, revisions.size()); + List<VFSItem> movedRevFiles = file.getParentContainer().getItems(new VersionsFilter(newName)); + Assert.assertEquals(1, movedRevFiles.size()); + Assert.assertEquals(((VFSRevisionImpl)revisions.get(0)).getFilename(), movedRevFiles.get(0).getName()); + } + + @Test + public void testMove() throws IOException { + //create a file + VFSContainer rootTest = VFSManager.olatRootContainer("/ver" + UUID.randomUUID(), null); + String filename = UUID.randomUUID().toString() + ".txt"; + VFSLeaf file = rootTest.createChildLeaf(filename); + int byteCopied = copyTestTxt(file); + Assert.assertFalse(byteCopied == 0); + Assert.assertEquals(VFSConstants.YES, file.canMeta()); + + Identity id1 = JunitTestHelper.createAndPersistIdentityAsRndUser("vers-9"); + Identity id2 = JunitTestHelper.createAndPersistIdentityAsRndUser("vers-10"); + + + //set the author + VFSMetadata metadata = vfsRepositoryService.getMetadataFor(file); + metadata.setAuthor(id1); + metadata.setCreator(id1.getName()); + metadata = vfsRepositoryService.updateMetadata(metadata); + + //save a first version -> id2 + InputStream in1 = new ByteArrayInputStream("Hello version 1".getBytes()); + vfsRepositoryService.addVersion(file, id2, "Version 1", in1); + in1.close(); + + //save a second version -> id1 + InputStream in2 = new ByteArrayInputStream("Hello version 2".getBytes()); + vfsRepositoryService.addVersion(file, id1, "Version 2", in2); + in2.close(); + + //move the file + VFSLeaf retrievedLeaf = (VFSLeaf)rootTest.resolve(filename); + String copyFilename = UUID.randomUUID().toString() + ".txt"; + VFSLeaf copyFile = rootTest.createChildLeaf(copyFilename); + OutputStream copyOutput = copyFile.getOutputStream(false); + InputStream copyInput = retrievedLeaf.getInputStream(); + IOUtils.copy(copyInput, copyOutput); + copyOutput.close(); + copyInput.close(); + //move the revisions + vfsRepositoryService.move(retrievedLeaf, copyFile, id2); + + //check if the revisions are moved + VFSLeaf retirevedCopyFile = (VFSLeaf)rootTest.resolve(copyFilename); + VFSMetadata metadataCopy = vfsRepositoryService.getMetadataFor(retirevedCopyFile); + List<VFSRevision> revisions = vfsRepositoryService.getRevisions(metadataCopy); + Assert.assertNotNull(revisions); + Assert.assertEquals(2, revisions.size()); + + VFSRevision revision0 = revisions.get(0); + //we don't set an author for the original file + assertEquals(id1, revision0.getAuthor()); + VFSRevision revision1 = revisions.get(1); + assertEquals(id2, revision1.getAuthor()); + //current + assertEquals(id1.getName(), metadataCopy.getCreator()); + assertEquals(id2, metadataCopy.getAuthor()); + } + + private int copyTestTxt(VFSLeaf file) { + try(OutputStream out = file.getOutputStream(false); + InputStream in = VFSVersioningTest.class.getResourceAsStream("test.txt")) { + return IOUtils.copy(in, out); + } catch(IOException e) { + return -1; + } + } + + + private static class SetMaxNumberOfVersions implements Callable<Boolean> { + + private final Long maxNumOfVersions; + private final VFSVersionModule versionConfig; + + public SetMaxNumberOfVersions(VFSVersionModule versionConfig, Long maxNumOfVersions) { + this.versionConfig = versionConfig; + this.maxNumOfVersions = maxNumOfVersions; + } + + @Override + public Boolean call() throws Exception { + int currentValue = versionConfig.getMaxNumberOfVersions(); + return currentValue == maxNumOfVersions.longValue(); + } + } + + private static class VersionsFilter implements VFSItemFilter { + + private final String filename; + + public VersionsFilter(String filename) { + this.filename = filename; + } + + @Override + public boolean accept(VFSItem item) { + if(item instanceof VFSLeaf && item.isHidden() && item.getName().endsWith(filename)) { + return true; + } + return false; + } + + } +} 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 deleted file mode 100644 index 7023235fa1a7627f2691a3bd69f152ebfdb65419..0000000000000000000000000000000000000000 --- a/src/test/java/org/olat/core/util/vfs/version/VersionManagerTest.java +++ /dev/null @@ -1,609 +0,0 @@ -/** - * <a href="http://www.openolat.org"> - * OpenOLAT - Online Learning and Training</a><br> - * <p> - * Licensed under the Apache License, Version 2.0 (the "License"); <br> - * you may not use this file except in compliance with the License.<br> - * You may obtain a copy of the License at the - * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> - * <p> - * Unless required by applicable law or agreed to in writing,<br> - * software distributed under the License is distributed on an "AS IS" BASIS, <br> - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> - * See the License for the specific language governing permissions and <br> - * limitations under the License. - * <p> - * Initial code contributed and copyrighted by<br> - * frentix GmbH, http://www.frentix.com - * <p> - */ -package org.olat.core.util.vfs.version; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; -import java.util.concurrent.Callable; - -import org.apache.commons.io.IOUtils; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.olat.core.CoreSpringFactory; -import org.olat.core.commons.services.vfs.VFSMetadata; -import org.olat.core.commons.services.vfs.VFSRepositoryService; -import org.olat.core.id.Identity; -import org.olat.core.util.vfs.VFSConstants; -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.VFSManager; -import org.olat.core.util.vfs.filters.VFSSystemItemFilter; -import org.olat.test.JunitTestHelper; -import org.olat.test.OlatTestCase; -import org.springframework.beans.factory.annotation.Autowired; - -/** - * - * Description:<br> - * - * <P> - * Initial Date: 23 déc. 2011 <br> - * - * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com - */ -public class VersionManagerTest extends OlatTestCase { - - private static boolean setuped = false; - - private static Identity id1, id2; - - @Autowired - private VersionsFileManager versionsManager; - @Autowired - private SimpleVersionConfig versioningConfigurator; - @Autowired - private VFSRepositoryService vfsRepositoryService; - - @Before - public void setUp() throws Exception { - if(setuped) return; - - //create identities - id1 = JunitTestHelper.createAndPersistIdentityAsUser("vm-one" + getRandomName()); - id2 = JunitTestHelper.createAndPersistIdentityAsUser("vm-two" + getRandomName()); - - SimpleVersionConfig versionConfig = (SimpleVersionConfig)CoreSpringFactory.getBean("versioningConfigurator"); - versionConfig.setMaxNumberOfVersionsProperty(10); - waitForCondition(new SetMaxNumberOfVersions(versionConfig, 10l), 2000); - setuped = true; - } - - @After - public void resetMaxVersions() { - int maxNumberOfVersions = versioningConfigurator.getMaxNumberOfVersionsProperty(); - if(maxNumberOfVersions != 10) { - versioningConfigurator.setMaxNumberOfVersionsProperty(10); - waitForCondition(new SetMaxNumberOfVersions(versioningConfigurator, 10l), 2000); - } - } - - private static class SetMaxNumberOfVersions implements Callable<Boolean> { - - private final Long maxNumOfVersions; - private final SimpleVersionConfig versioningConfig; - - public SetMaxNumberOfVersions(SimpleVersionConfig versioningConfig, Long maxNumOfVersions) { - this.versioningConfig = versioningConfig; - this.maxNumOfVersions = maxNumOfVersions; - } - - @Override - public Boolean call() throws Exception { - int currentValue = versioningConfig.getMaxNumberOfVersionsProperty(); - return currentValue == maxNumOfVersions.longValue(); - } - } - - @Test - public void testVersionManager() throws IOException { - //create a file - VFSContainer rootTest = VFSManager.olatRootContainer("/test", null); - String filename = getRandomName(); - VFSLeaf file = rootTest.createChildLeaf(filename); - int byteCopied = copyTestTxt(file); - assertFalse(byteCopied == 0); - assertTrue(file instanceof Versionable); - - //save a first version - Versionable versionedFile1 = (Versionable)file; - InputStream in1 = new ByteArrayInputStream("Hello version 1".getBytes()); - versionedFile1.getVersions().addVersion(id2, "Version 1", in1); - in1.close(); - - //save a second version - Versionable versionedFile2 = (Versionable)file; - InputStream in2 = new ByteArrayInputStream("Hello version 2".getBytes()); - versionedFile2.getVersions().addVersion(id2, "Version 2", in2); - in2.close(); - - //save a third version - Versionable versionedFile3 = (Versionable)file; - InputStream in3 = new ByteArrayInputStream("Hello version 3".getBytes()); - versionedFile3.getVersions().addVersion(id2, "Version 3", in3); - in3.close(); - - //make the checks - VFSItem retrievedFile = rootTest.resolve(filename); - assertTrue(retrievedFile instanceof Versionable); - Versions versions = versionsManager.createVersionsFor((VFSLeaf)retrievedFile); - List<VFSRevision> revisions = versions.getRevisions(); - assertNotNull(revisions); - assertEquals(3, revisions.size()); - - VFSRevision revision0 = revisions.get(0); - //we don't set an author for the original file - assertNull(null, revision0.getAuthor()); - VFSRevision revision1 = revisions.get(1); - assertEquals(id2.getName(), revision1.getAuthor()); - VFSRevision revision2 = revisions.get(2); - assertEquals(id2.getName(), revision2.getAuthor()); - - //check the comments - assertNull(revision0.getComment()); - assertEquals("Version 1", revision1.getComment()); - assertEquals("Version 2", revision2.getComment()); - assertEquals("Version 3", versions.getComment()); - } - - @Test - public void testOverflow_lowLevel() throws IOException { - versioningConfigurator.setMaxNumberOfVersionsProperty(3); - waitForCondition(new SetMaxNumberOfVersions(versioningConfigurator, 3l), 2000); - - //create a file - VFSContainer rootTest = VFSManager.olatRootContainer("/test_" + UUID.randomUUID(), null); - String filename = getRandomName(); - VFSLeaf file = rootTest.createChildLeaf(filename); - int byteCopied = copyTestTxt(file); - 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); - inv.close(); - } - - VFSItem retrievedFile = rootTest.resolve(filename); - Versions versions = versionsManager.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(0); - waitForCondition(new SetMaxNumberOfVersions(versioningConfigurator, 0l), 2000); - - //create a file - VFSContainer rootTest = VFSManager.olatRootContainer("/test_" + UUID.randomUUID(), null); - String filename = getRandomName(); - VFSLeaf file = rootTest.createChildLeaf(filename); - int byteCopied = copyTestTxt(file); - 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); - inv.close(); - } - - VFSItem retrievedFile = rootTest.resolve(filename); - Versions versions = versionsManager.createVersionsFor((VFSLeaf)retrievedFile); - List<VFSRevision> revisions = versions.getRevisions(); - assertNotNull(revisions); - assertTrue(revisions.isEmpty()); - } - - @Test - public void testVersionChecksum() throws IOException { - VFSContainer rootTest = VFSManager.olatRootContainer("/ver-" + UUID.randomUUID(), null); - String filename = getRandomName(); - VFSLeaf file = rootTest.createChildLeaf(filename); - int byteCopied = copyTestTxt(file); - assertFalse(byteCopied == 0); - assertTrue(file instanceof Versionable); - - - //save a first version - Versionable versionedFile = (Versionable)file; - InputStream in1 = VersionManagerTest.class.getResourceAsStream("test.txt"); - versionedFile.getVersions().addVersion(id2, "Version 1", in1); - in1.close(); - - //save a second version - InputStream in2 = VersionManagerTest.class.getResourceAsStream("test.txt"); - versionedFile.getVersions().addVersion(id2, "Version 2", in2); - in2.close(); - - //save a third version - InputStream in3 = VersionManagerTest.class.getResourceAsStream("test.txt"); - versionedFile.getVersions().addVersion(id2, "Version 3", in2); - in3.close(); - - //check if there is only one backup file - VFSContainer versionContainer = versionsManager.getCanonicalVersionFolder(file.getParentContainer(), false); - Assert.assertNotNull(versionContainer); - List<VFSItem> items = versionContainer.getItems(new VFSSystemItemFilter()); - Assert.assertNotNull(items); - Assert.assertEquals(2, items.size()); - - //check number of versions - VFSItem reloadFile = rootTest.resolve(filename); - assertTrue(reloadFile instanceof Versionable); - Versionable reloadedVersionedFile = (Versionable)reloadFile; - List<VFSRevision> revisions = reloadedVersionedFile.getVersions().getRevisions(); - Assert.assertNotNull(revisions); - Assert.assertEquals(3, revisions.size()); - } - - /** - * The test create an original file and 3 revisions with exactly - * the same content. We delete the original and the first version. - * We check that version 2 and 3 survives and that the file exists. - * - * @throws IOException - */ - @Test - public void testDeleteRevisions_withSameFile() throws IOException { - VFSContainer rootTest = VFSManager.olatRootContainer("/ver-" + UUID.randomUUID(), null); - String filename = getRandomName(); - VFSLeaf file = rootTest.createChildLeaf(filename); - int byteCopied = copyTestTxt(file); - assertFalse(byteCopied == 0); - assertTrue(file instanceof Versionable); - - //save a first version - Versionable versionedFile = (Versionable)file; - InputStream in1 = VersionManagerTest.class.getResourceAsStream("test.txt"); - versionedFile.getVersions().addVersion(id2, "Version 1", in1); - in1.close(); - - //save a second version - InputStream in2 = VersionManagerTest.class.getResourceAsStream("test.txt"); - versionedFile.getVersions().addVersion(id2, "Version 2", in2); - in2.close(); - - //save a third version - InputStream in3 = VersionManagerTest.class.getResourceAsStream("test.txt"); - versionedFile.getVersions().addVersion(id2, "Version 3", in2); - in3.close(); - - //delete revisions - versionsManager.deleteRevisions(versionedFile, versionedFile.getVersions().getRevisions().subList(0, 2)); - - //check number of versions - VFSItem reloadFile = rootTest.resolve(filename); - assertTrue(reloadFile instanceof Versionable); - Versionable reloadedVersionedFile = (Versionable)reloadFile; - List<VFSRevision> revisions = reloadedVersionedFile.getVersions().getRevisions(); - Assert.assertNotNull(revisions); - Assert.assertEquals(1, revisions.size()); - //check surviving versions - Assert.assertEquals("Version 2", revisions.get(0).getComment()); - Assert.assertEquals("Version 3", reloadedVersionedFile.getVersions().getComment()); - //check that the last backup file exists - RevisionFileImpl revision2 = (RevisionFileImpl)revisions.get(0); - VFSLeaf revision2File = revision2.getFile(); - Assert.assertNotNull(revision2File); - Assert.assertTrue(revision2File.exists()); - - //check if there is only one backup file - VFSContainer versionContainer = versionsManager.getCanonicalVersionFolder(file.getParentContainer(), false); - Assert.assertNotNull(versionContainer); - List<VFSItem> items = versionContainer.getItems(new VFSSystemItemFilter()); - Assert.assertNotNull(items); - Assert.assertEquals(2, items.size()); - } - - /** - * The test create an original file and 5 versions. It manually - * delete the physical back up file. We delete the versions - * of the orginal, 1 and 2. At the end, there is only version 4 - * and 5. - * - * - * @throws IOException - */ - @Test - public void testDeleteRevisions_withMissingRevisionFile() throws IOException { - VFSContainer rootTest = VFSManager.olatRootContainer("/ver-" + UUID.randomUUID(), null); - String filename = getRandomName(); - VFSLeaf file = rootTest.createChildLeaf(filename); - int byteCopied = copyTestTxt(file); - assertFalse(byteCopied == 0); - assertTrue(file instanceof Versionable); - - //save a first version - Versionable versionedFile = (Versionable)file; - InputStream in1 = new ByteArrayInputStream("Hello version 1".getBytes()); - versionedFile.getVersions().addVersion(id2, "Version 1", in1); - in1.close(); - - //save a second version - InputStream in2 = new ByteArrayInputStream("Hello version 2".getBytes()); - versionedFile.getVersions().addVersion(id2, "Version 2", in2); - in2.close(); - - //save a third version - InputStream in3 = new ByteArrayInputStream("Hello version 3".getBytes()); - versionedFile.getVersions().addVersion(id2, "Version 3", in3); - in3.close(); - - //save a fourth version - InputStream in4 = new ByteArrayInputStream("Hello version 4".getBytes()); - versionedFile.getVersions().addVersion(id2, "Version 4", in4); - in4.close(); - - //save a fourth version - InputStream in5 = new ByteArrayInputStream("Hello version 5".getBytes()); - versionedFile.getVersions().addVersion(id2, "Version 5", in5); - in5.close(); - - //delete a specific - VFSRevision rev3 = versionedFile.getVersions().getRevisions().get(3); - RevisionFileImpl toDeleteVersionImpl = (RevisionFileImpl)rev3; - VFSContainer versionContainerAlt = versionsManager.getCanonicalVersionFolder(rootTest, false); - VFSItem itemToDelete = versionContainerAlt.resolve(toDeleteVersionImpl.getFilename()); - itemToDelete.deleteSilently(); - - //delete revisions - List<VFSRevision> toDelete = new ArrayList<>(versionedFile.getVersions().getRevisions().subList(0, 3)); - versionsManager.deleteRevisions(versionedFile, toDelete); - - //check number of versions - VFSItem reloadFile = rootTest.resolve(filename); - assertTrue(reloadFile instanceof Versionable); - Versionable reloadedVersionedFile = (Versionable)reloadFile; - List<VFSRevision> revisions = reloadedVersionedFile.getVersions().getRevisions(); - Assert.assertNotNull(revisions); - Assert.assertEquals(1, revisions.size()); - VFSRevision revision = revisions.get(0); - Assert.assertEquals("Version 4", revision.getComment()); - Assert.assertEquals("Version 5", reloadedVersionedFile.getVersions().getComment()); - - //check if there is only one backup file - VFSContainer versionContainer = versionsManager.getCanonicalVersionFolder(file.getParentContainer(), false); - Assert.assertNotNull(versionContainer); - List<VFSItem> items = versionContainer.getItems(new VFSSystemItemFilter()); - Assert.assertNotNull(items); - Assert.assertEquals(2, items.size()); - } - - @Test - public void testAuthorsAndCreators() throws IOException { - //create a file - VFSContainer rootTest = VFSManager.olatRootContainer("/test2", null); - String filename = getRandomName(); - VFSLeaf file = rootTest.createChildLeaf(filename); - int byteCopied = copyTestTxt(file); - assertFalse(byteCopied == 0); - assertTrue(file instanceof Versionable); - assertEquals(VFSConstants.YES, file.canMeta()); - - //set the author - VFSMetadata metaInfo = file.getMetaInfo(); - metaInfo.setAuthor(id1); - metaInfo.setCreator(id1.getName()); - metaInfo = vfsRepositoryService.updateMetadata(metaInfo); - - //save a first version -> id2 - Versionable versionedFile1 = (Versionable)file; - InputStream in1 = new ByteArrayInputStream("Hello version 1".getBytes()); - versionedFile1.getVersions().addVersion(id2, "Version 1", in1); - in1.close(); - - //save a second version -> id1 - Versionable versionedFile2 = (Versionable)file; - InputStream in2 = new ByteArrayInputStream("Hello version 2".getBytes()); - versionedFile2.getVersions().addVersion(id1, "Version 2", in2); - in2.close(); - - //save a third version -> id2 - Versionable versionedFile3 = (Versionable)file; - InputStream in3 = new ByteArrayInputStream("Hello version 3".getBytes()); - versionedFile3.getVersions().addVersion(id2, "Version 3", in3); - in3.close(); - - //make the checks - VFSItem retrievedFile = rootTest.resolve(filename); - assertTrue(retrievedFile instanceof Versionable); - assertTrue(retrievedFile instanceof VFSLeaf); - Versions versions = versionsManager.createVersionsFor((VFSLeaf)retrievedFile); - List<VFSRevision> revisions = versions.getRevisions(); - assertNotNull(revisions); - assertEquals(3, revisions.size()); - assertEquals(VFSConstants.YES, retrievedFile.canMeta()); - - VFSRevision revision0 = revisions.get(0); - //we don't set an author for the original file - assertEquals(id1.getName(), revision0.getAuthor()); - VFSRevision revision1 = revisions.get(1); - assertEquals(id2.getName(), revision1.getAuthor()); - VFSRevision revision2 = revisions.get(2); - assertEquals(id1.getName(), revision2.getAuthor()); - //current - assertEquals(id2.getName(), versions.getAuthor()); - } - - @Test - public void testMove() throws IOException { - //create a file - VFSContainer rootTest = VFSManager.olatRootContainer("/test2", null); - String filename = getRandomName(); - VFSLeaf file = rootTest.createChildLeaf(filename); - int byteCopied = copyTestTxt(file); - assertFalse(byteCopied == 0); - assertTrue(file instanceof Versionable); - assertEquals(VFSConstants.YES, file.canMeta()); - - //set the author - VFSMetadata metaInfo = file.getMetaInfo(); - metaInfo.setAuthor(id1); - metaInfo.setCreator(id1.getName()); - metaInfo = vfsRepositoryService.updateMetadata(metaInfo); - - //save a first version -> id2 - Versionable versionedFile1 = (Versionable)file; - InputStream in1 = new ByteArrayInputStream("Hello version 1".getBytes()); - versionedFile1.getVersions().addVersion(id2, "Version 1", in1); - in1.close(); - - //save a second version -> id1 - Versionable versionedFile2 = (Versionable)file; - InputStream in2 = new ByteArrayInputStream("Hello version 2".getBytes()); - versionedFile2.getVersions().addVersion(id1, "Version 2", in2); - in2.close(); - - //move the file - VFSLeaf retrievedLeaf = (VFSLeaf)rootTest.resolve(filename); - String copyFilename = getRandomName(); - VFSLeaf copyFile = rootTest.createChildLeaf(copyFilename); - OutputStream copyOutput = copyFile.getOutputStream(false); - InputStream copyInput = retrievedLeaf.getInputStream(); - IOUtils.copy(copyInput, copyOutput); - copyOutput.close(); - copyInput.close(); - //move the revisions - versionsManager.move(retrievedLeaf, copyFile, id2); - - //check if the revisions are moved - VFSLeaf retirevedCopyFile = (VFSLeaf)rootTest.resolve(copyFilename); - assertTrue(retirevedCopyFile instanceof Versionable); - Versions versions = versionsManager.createVersionsFor(retirevedCopyFile); - List<VFSRevision> revisions = versions.getRevisions(); - assertNotNull(revisions); - assertEquals(2, revisions.size()); - - VFSRevision revision0 = revisions.get(0); - //we don't set an author for the original file - assertEquals(id1.getName(), revision0.getAuthor()); - VFSRevision revision1 = revisions.get(1); - assertEquals(id2.getName(), revision1.getAuthor()); - //current - assertEquals(id1.getName(), versions.getCreator()); - assertEquals(id2.getName(), versions.getAuthor()); - } - - /** - * Create a file with 2 revision, move it to another name, move it to the primitive name: - * File A, change file A, change file A, move to file B, move to file A - * @throws IOException - */ - @Test - public void testCircleMove() throws IOException { - //create a file A - VFSContainer rootTest = VFSManager.olatRootContainer("/test2", null); - String filename = getRandomName(); - VFSLeaf file = rootTest.createChildLeaf(filename); - int byteCopied = copyTestTxt(file); - assertFalse(byteCopied == 0); - assertTrue(file instanceof Versionable); - assertEquals(VFSConstants.YES, file.canMeta()); - - //set the author - VFSMetadata metaInfo = file.getMetaInfo(); - metaInfo.setAuthor(id1); - metaInfo.setCreator(id1.getName()); - metaInfo = vfsRepositoryService.updateMetadata(metaInfo); - - //save a first version of file A -> id2 - Versionable versionedFile1 = (Versionable)file; - InputStream in1 = new ByteArrayInputStream("Hello version 1".getBytes()); - versionedFile1.getVersions().addVersion(id2, "Version 1", in1); - in1.close(); - - //save a second version of file A -> id1 - Versionable versionedFile2 = (Versionable)file; - InputStream in2 = new ByteArrayInputStream("Hello version 2".getBytes()); - versionedFile2.getVersions().addVersion(id1, "Version 2", in2); - in2.close(); - - //move the file A -> file B - VFSLeaf retrievedLeaf = (VFSLeaf)rootTest.resolve(filename); - String copyFilename = getRandomName(); - VFSLeaf copyFile = rootTest.createChildLeaf(copyFilename); - OutputStream copyOutput = copyFile.getOutputStream(false); - InputStream copyInput = retrievedLeaf.getInputStream(); - IOUtils.copy(copyInput, copyOutput); - copyOutput.close(); - copyInput.close(); - //move the revisions - versionsManager.move(retrievedLeaf, copyFile, id2); - - //move the file B -> file A - VFSLeaf retrievedCopyLeaf = (VFSLeaf)rootTest.resolve(copyFilename); - VFSLeaf originalFile = (VFSLeaf)rootTest.resolve(filename); - OutputStream originalOutput = originalFile.getOutputStream(false); - InputStream retrievedCopyInput = retrievedCopyLeaf.getInputStream(); - IOUtils.copy(retrievedCopyInput, originalOutput); - originalOutput.close(); - retrievedCopyInput.close(); - //move the revisions - versionsManager.move(retrievedCopyLeaf, originalFile, id2); - - - //check if the revisions are moved - VFSLeaf retirevedOriginalFile = (VFSLeaf)rootTest.resolve(filename); - assertTrue(retirevedOriginalFile instanceof Versionable); - Versions versions = versionsManager.createVersionsFor(retirevedOriginalFile); - List<VFSRevision> revisions = versions.getRevisions(); - assertNotNull(revisions); - assertEquals(2, revisions.size()); - - VFSRevision revision0 = revisions.get(0); - //we don't set an author for the original file - assertEquals(id1.getName(), revision0.getAuthor()); - VFSRevision revision1 = revisions.get(1); - assertEquals(id2.getName(), revision1.getAuthor()); - //current - assertEquals(id1.getName(), versions.getCreator()); - assertEquals(id2.getName(), versions.getAuthor()); - } - - private int copyTestTxt(VFSLeaf file) { - try(OutputStream out = file.getOutputStream(false); - InputStream in = VersionManagerTest.class.getResourceAsStream("test.txt")) { - return IOUtils.copy(in, out); - } catch(IOException e) { - return -1; - } - } - - private String getRandomName() { - return UUID.randomUUID().toString().replace("-", ""); - } -} \ No newline at end of file diff --git a/src/test/java/org/olat/modules/webFeed/manager/FeedFileStorgeTest.java b/src/test/java/org/olat/modules/webFeed/manager/FeedFileStorgeTest.java index 4b37ba4ea4852aeed2065fb1683a8131f56bd904..5773263cf4012c976c9391ebd3384f2374b538b4 100644 --- a/src/test/java/org/olat/modules/webFeed/manager/FeedFileStorgeTest.java +++ b/src/test/java/org/olat/modules/webFeed/manager/FeedFileStorgeTest.java @@ -28,6 +28,7 @@ import java.util.List; import org.junit.Before; import org.junit.Test; import org.olat.core.util.vfs.VFSContainer; +import org.olat.core.util.vfs.filters.VFSSystemItemFilter; import org.olat.fileresource.FileResourceManager; import org.olat.fileresource.types.BlogFileResource; import org.olat.fileresource.types.FeedFileResource; @@ -499,7 +500,7 @@ public class FeedFileStorgeTest extends OlatTestCase { sut.deleteFeedXML(feed); // check if there is no file in the feed container - assertThat(sut.getOrCreateFeedContainer(feed).getItems().size()).isEqualTo(0); + assertThat(sut.getOrCreateFeedContainer(feed).getItems(new VFSSystemItemFilter()).size()).isEqualTo(0); fileResourceManager.deleteFileResource(resource); } @@ -714,7 +715,7 @@ public class FeedFileStorgeTest extends OlatTestCase { sut.deleteItemXML(item); // check if there is no file in the item container - assertThat(sut.getOrCreateItemContainer(item).getItems().size()).isEqualTo(0); + assertThat(sut.getOrCreateItemContainer(item).getItems(new VFSSystemItemFilter()).size()).isEqualTo(0); fileResourceManager.deleteFileResource(resource); } diff --git a/src/test/java/org/olat/restapi/FolderTest.java b/src/test/java/org/olat/restapi/FolderTest.java index 63e08bdab9fb78c2d5438b92335b8449a514b318..8e39a27cdef2bb0d3750f7f49b48acf3b99a9494 100644 --- a/src/test/java/org/olat/restapi/FolderTest.java +++ b/src/test/java/org/olat/restapi/FolderTest.java @@ -28,7 +28,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; -import org.olat.core.util.vfs.restapi.VFSWebservice; +import org.olat.core.commons.services.vfs.restapi.VFSWebservice; /** * * <h3>Description:</h3> diff --git a/src/test/java/org/olat/test/AllTestsJunit4.java b/src/test/java/org/olat/test/AllTestsJunit4.java index 55285c10e93983e6b4f0e74d095eb6a0a21c1571..ddb8225e42480f46b5a82adfbbfa84ce20c12e4f 100644 --- a/src/test/java/org/olat/test/AllTestsJunit4.java +++ b/src/test/java/org/olat/test/AllTestsJunit4.java @@ -98,10 +98,11 @@ import org.junit.runners.Suite; org.olat.commons.coordinate.cluster.lock.LockTest.class, org.olat.commons.coordinate.CoordinatorTest.class, org.olat.core.commons.services.csp.manager.CSPManagerTest.class, + org.olat.core.commons.services.vfs.manager.VFSXStreamTest.class, org.olat.core.commons.services.vfs.manager.VFSMetadataDAOTest.class, - org.olat.core.commons.services.vfs.manager.VFSRepositoryServiceTest.class, + org.olat.core.commons.services.vfs.manager.VFSRevisionDAOTest.class, org.olat.core.commons.services.vfs.manager.VFSThumbnailDAOTest.class, - org.olat.core.commons.services.vfs.manager.VFSXStreamTest.class, + org.olat.core.commons.services.vfs.manager.VFSRepositoryServiceTest.class, org.olat.core.commons.services.help.ConfluenceHelperTest.class, org.olat.core.commons.services.help.spi.ConfluenceLinkSPITest.class, org.olat.core.commons.services.license.manager.LicenseTypeActivationDAOTest.class, @@ -420,7 +421,6 @@ import org.junit.runners.Suite; org.olat.resource.accesscontrol.ACTransactionManagerTest.class, org.olat.resource.accesscontrol.ACReservationDAOTest.class, org.olat.resource.accesscontrol.provider.auto.manager.AdvanceOrderDAOTest.class, - org.olat.core.util.vfs.version.VersionManagerTest.class, /** * Pure JUnit test without need of framework */ diff --git a/src/test/java/org/olat/test/VFSJavaIOFile.java b/src/test/java/org/olat/test/VFSJavaIOFile.java index 703845216d1e313ab024a0cf323cf2aa2875c5d9..7f9482c8e449c69c72f8bf11e9f80ce5c97f5cef 100644 --- a/src/test/java/org/olat/test/VFSJavaIOFile.java +++ b/src/test/java/org/olat/test/VFSJavaIOFile.java @@ -158,6 +158,11 @@ public class VFSJavaIOFile implements VFSLeaf, JavaIOItem { return VFSConstants.NO; } + @Override + public VFSStatus canVersion() { + return VFSConstants.NO; + } + @Override public VFSMetadata getMetaInfo() { return null;