From 312023be934399ac378bac93174f393385ae0404 Mon Sep 17 00:00:00 2001 From: uhensler <none@none> Date: Mon, 5 Mar 2018 10:24:23 +0100 Subject: [PATCH] OO-3170: Licenses in the folder course node --- .../modules/bc/FileUploadController.java | 9 - .../modules/bc/FolderLicenseHandler.java | 49 ++++ .../modules/bc/FolderRunController.java | 10 - .../bc/_i18n/LocalStrings_de.properties | 3 +- .../bc/_i18n/LocalStrings_en.properties | 3 +- .../modules/bc/commands/CmdEditMeta.java | 16 +- .../bc/components/FolderComponent.java | 18 +- .../modules/bc/components/ListRenderer.java | 17 +- .../commons/modules/bc/meta/MetaInfo.java | 16 ++ .../modules/bc/meta/MetaInfoController.java | 94 ++++---- .../modules/bc/meta/MetaInfoFactory.java | 52 +++++ .../modules/bc/meta/MetaInfoFileImpl.java | 209 +++++++++--------- .../bc/meta/MetaInfoFormController.java | 142 ++++++++++-- .../bc/meta/_i18n/LocalStrings_de.properties | 3 + .../bc/meta/_i18n/LocalStrings_en.properties | 3 + .../commons/services/license/License.java | 9 +- .../services/license/LicenseService.java | 38 +++- .../services/license/ResourceLicense.java | 38 ++++ .../license/manager/LicenseServiceImpl.java | 49 +++- .../license/manager/LicenseTypeDAO.java | 15 +- ...icenseDAO.java => ResourceLicenseDAO.java} | 24 +- .../services/license/model/LicenseImpl.java | 133 +---------- .../license/model/ResourceLicenseImpl.java | 176 +++++++++++++++ .../ui/LicenseQuickviewController.java | 71 ------ .../services/license/ui/LicenseRenderer.java | 77 +++---- .../license/ui/LicenseSelectionConfig.java | 9 +- .../services/license/ui/LicenseUIFactory.java | 4 +- .../ui/_i18n/LocalStrings_de.properties | 6 +- .../ui/_i18n/LocalStrings_en.properties | 6 +- .../ui/author/AuthorListController.java | 33 +-- .../ui/author/AuthoringEntryDataSource.java | 6 +- .../RepositoryEditDescriptionController.java | 6 +- src/main/resources/META-INF/persistence.xml | 2 +- .../modules/bc/meta/MetaInfoFactoryTest.java | 104 +++++++++ .../license/manager/LicenseCleaner.java | 51 +++++ .../manager/LicenseTypeActivationDAOTest.java | 13 +- .../license/manager/LicenseTypeDAOTest.java | 40 +++- ...OTest.java => ResourceLicenseDAOTest.java} | 32 ++- .../ui/LicenseSelectionConfigTest.java | 20 +- .../java/org/olat/test/AllTestsJunit4.java | 3 +- 40 files changed, 1023 insertions(+), 586 deletions(-) create mode 100644 src/main/java/org/olat/core/commons/modules/bc/FolderLicenseHandler.java create mode 100644 src/main/java/org/olat/core/commons/services/license/ResourceLicense.java rename src/main/java/org/olat/core/commons/services/license/manager/{LicenseDAO.java => ResourceLicenseDAO.java} (80%) create mode 100644 src/main/java/org/olat/core/commons/services/license/model/ResourceLicenseImpl.java delete mode 100644 src/main/java/org/olat/core/commons/services/license/ui/LicenseQuickviewController.java create mode 100644 src/test/java/org/olat/core/commons/modules/bc/meta/MetaInfoFactoryTest.java create mode 100644 src/test/java/org/olat/core/commons/services/license/manager/LicenseCleaner.java rename src/test/java/org/olat/core/commons/services/license/manager/{LicenseDAOTest.java => ResourceLicenseDAOTest.java} (82%) 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 32b534fa6a7..b42279e48f0 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 @@ -363,18 +363,12 @@ public class FileUploadController extends FormBasicController { } } - /** - * @see org.olat.core.gui.components.form.flexible.impl.FormBasicController#formCancelled(org.olat.core.gui.UserRequest) - */ @Override protected void formCancelled(UserRequest ureq) { status = FolderCommandStatus.STATUS_CANCELED; fireEvent(ureq, Event.CANCELLED_EVENT); } - /** - * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest, org.olat.core.gui.control.Controller, org.olat.core.gui.control.Event) - */ @Override public void event(UserRequest ureq, Controller source, Event event) { if (source == overwriteDialog) { @@ -759,9 +753,6 @@ public class FileUploadController extends FormBasicController { } } - /** - * @see org.olat.core.gui.components.form.flexible.impl.FormBasicController#doDispose() - */ @Override protected void doDispose() { // diff --git a/src/main/java/org/olat/core/commons/modules/bc/FolderLicenseHandler.java b/src/main/java/org/olat/core/commons/modules/bc/FolderLicenseHandler.java new file mode 100644 index 00000000000..9cd01ce1754 --- /dev/null +++ b/src/main/java/org/olat/core/commons/modules/bc/FolderLicenseHandler.java @@ -0,0 +1,49 @@ +/** + * <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; + +import java.util.Locale; + +import org.olat.core.commons.services.license.LicenseHandler; +import org.olat.core.gui.translator.Translator; +import org.olat.core.util.Util; +import org.springframework.stereotype.Component; + +/** + * + * Initial date: 02.03.2018<br> + * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com + * + */ +@Component +public class FolderLicenseHandler implements LicenseHandler { + + @Override + public String getType() { + return "folder"; + } + + @Override + public String getTitle(Locale locale) { + Translator translator = Util.createPackageTranslator(FolderModule.class, locale); + return translator.translate("license.admin.title"); + } + +} diff --git a/src/main/java/org/olat/core/commons/modules/bc/FolderRunController.java b/src/main/java/org/olat/core/commons/modules/bc/FolderRunController.java index 216e9957eed..5524f488635 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/FolderRunController.java +++ b/src/main/java/org/olat/core/commons/modules/bc/FolderRunController.java @@ -439,12 +439,6 @@ public class FolderRunController extends BasicController implements Activateable } } - /** - * @seec org.olat removeAsListenerAndDispose(folderCommandController); - * folderCommandController = null; removeAsListenerAndDispose(cmc); cmc = - * null; .UserRequest, org.olat.core.gui.components.Component, - * org.olat.core.gui.control.Event) - */ @Override public void event(UserRequest ureq, Component source, Event event) { if (source == folderComponent || source == folderContainer || source == editQuotaButton) { @@ -545,10 +539,6 @@ public class FolderRunController extends BasicController implements Activateable return null; } - /** - * - * @see org.olat.core.gui.control.DefaultController#doDispose(boolean) - */ @Override protected void doDispose() { // diff --git a/src/main/java/org/olat/core/commons/modules/bc/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/core/commons/modules/bc/_i18n/LocalStrings_de.properties index 841b14b2a85..b191aa18f9a 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/core/commons/modules/bc/_i18n/LocalStrings_de.properties @@ -68,14 +68,15 @@ eportfolio=Diese Datei als Artefakt dem ePortfolio hinzuf\u00FCgen. failed=Operation fehlgeschlagen file=Datei header.Info=Metadaten +header.license=Lizenz header.Modified=Ge\u00E4ndert header.Name=Name header.Size=Gr\u00F6sse header.Status=Status header.Type=Typ header.Version=Version - invalid.file.names=Folgende Dateinamen sind ung\u00FCltig, weil sie unzul\u00E4ssige Zeichen enthalten (/,\:, etc.). Bitte \u00E4ndern Sie die Namen entsprechend. +license.admin.title=Ordner lock.description=Eine oder mehrere Dateien sind gesperrt. lock.title=Datei(en) gesperrt mc.copy=Objekte kopieren diff --git a/src/main/java/org/olat/core/commons/modules/bc/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/core/commons/modules/bc/_i18n/LocalStrings_en.properties index caf359feb75..23a384a182d 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/core/commons/modules/bc/_i18n/LocalStrings_en.properties @@ -68,14 +68,15 @@ eportfolio=Add this file as artefact to a portfolio. failed=Operation failed file=File header.Info=Metadata +header.license=License header.Modified=Modified header.Name=Name header.Size=Size header.Status=Status header.Type=Type header.Version=Version - invalid.file.names=The following file names are invalid since they contain special characters (/, \:, etc.). Please modify your names accordingly. +license.admin.title=Folder lock.description=One or more files are locked. lock.title=Locked file(s) mc.copy=Copy object diff --git a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdEditMeta.java b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdEditMeta.java index e1669b743fe..9742ac28855 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdEditMeta.java +++ b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdEditMeta.java @@ -139,21 +139,11 @@ public class CmdEditMeta extends BasicController implements FolderCommand { return translate("mf.metadata.title"); } - /** - * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest, - * org.olat.core.gui.components.Component, - * org.olat.core.gui.control.Event) - */ @Override public void event(UserRequest ureq, Component source, Event event) { // nothing to do here } - /** - * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest, - * org.olat.core.gui.control.Controller, - * org.olat.core.gui.control.Event) - */ @Override public void event(UserRequest ureq, Controller source, Event event) { if (source == metaInfoCtr && event == Event.DONE_EVENT) { @@ -169,9 +159,7 @@ public class CmdEditMeta extends BasicController implements FolderCommand { getWindowControl().setError(translator.translate("TargetNameAlreadyUsed")); status = FolderCommandStatus.STATUS_FAILED; } else { - if (meta != null) { - meta.rename(fileName); - } + meta.rename(fileName); if(VFSConstants.NO.equals(currentItem.rename(fileName))) { getWindowControl().setError(translator.translate("FileRenameFailed", new String[]{fileName})); status = FolderCommandStatus.STATUS_FAILED; @@ -198,10 +186,12 @@ public class CmdEditMeta extends BasicController implements FolderCommand { fireEvent(ureq, FOLDERCOMMAND_FINISHED); } + @Override protected void doDispose() { // metaInfoCtr should be auto-disposed } + @Override public boolean runsModal() { return false; } 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 9f6f47d25bc..d35548768ec 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 @@ -140,9 +140,7 @@ public class FolderComponent extends AbstractComponent { dateTimeFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale); } - /** - * @see org.olat.core.gui.components.Component#dispatchRequest(org.olat.core.gui.UserRequest) - */ + @Override protected void doDispatchRequest(UserRequest ureq) { if (ureq.getParameter(ListRenderer.PARAM_EDTID) != null) { fireEvent(ureq, new Event(FolderCommandFactory.COMMAND_EDIT)); @@ -212,6 +210,7 @@ public class FolderComponent extends AbstractComponent { currentSortOrder = col; if (col.equals(SORT_NAME)) { // sort after file name? comparator = new Comparator<VFSItem>() { + @Override public int compare(VFSItem o1, VFSItem o2) { if (sortAsc) { if ((o1 instanceof VFSLeaf && o2 instanceof VFSLeaf) || (!(o1 instanceof VFSLeaf) && !(o2 instanceof VFSLeaf))) { @@ -240,6 +239,7 @@ public class FolderComponent extends AbstractComponent { }; } else if (col.equals(SORT_DATE)) { // sort after modification date (if same, then name) comparator = new Comparator<VFSItem>() { + @Override public int compare(VFSItem o1, VFSItem o2) { if (o1.getLastModified() < o2.getLastModified()) return ((sortAsc) ? -1 : 1); else if (o1.getLastModified() > o2.getLastModified()) return ((sortAsc) ? 1 : -1); @@ -251,6 +251,7 @@ public class FolderComponent extends AbstractComponent { }; } else if (col.equals(SORT_SIZE)) { // sort after file size, folders always on top comparator = new Comparator<VFSItem>() { + @Override public int compare(VFSItem o1, VFSItem o2) { VFSLeaf leaf1 = null; if (o1 instanceof VFSLeaf) { @@ -272,6 +273,7 @@ public class FolderComponent extends AbstractComponent { }; } else if (col.equals(SORT_REV)) { // sort after revision number, folders always on top comparator = new Comparator<VFSItem>() { + @Override public int compare(VFSItem o1, VFSItem o2) { Versionable v1 = null; Versionable v2 = null; @@ -303,16 +305,10 @@ public class FolderComponent extends AbstractComponent { if (currentContainerChildren != null) updateChildren(); // if not empty the update list } - /** - * @return VFSContainer - */ public VFSContainer getRootContainer() { return rootContainer; } - /** - * @return VFSContainer - */ public VFSContainer getCurrentContainer() { return currentContainer; } @@ -374,9 +370,6 @@ public class FolderComponent extends AbstractComponent { currentContainerChildren = children; } - /** - * @param relPath - */ public boolean setCurrentContainerPath(String relPath) { // get the container setDirty(true); @@ -421,6 +414,7 @@ public class FolderComponent extends AbstractComponent { return externContainerForCopy; } + @Override public ComponentRenderer getHTMLRendererSingleton() { return RENDERER; } 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 6f14fc9371e..4afdaf71bcd 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,10 @@ import org.olat.core.commons.modules.bc.FileSelection; import org.olat.core.commons.modules.bc.FolderConfig; import org.olat.core.commons.modules.bc.FolderManager; import org.olat.core.commons.modules.bc.meta.MetaInfo; +import org.olat.core.commons.modules.bc.meta.MetaInfoFactory; import org.olat.core.commons.modules.bc.meta.tagged.MetaTagged; +import org.olat.core.commons.services.license.License; +import org.olat.core.commons.services.license.ui.LicenseRenderer; 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; @@ -129,8 +132,9 @@ public class ListRenderer { sb.append("<table class=\"table table-condensed table-striped table-hover o_bc_table\">") .append("<thead><tr><th><a class='o_orderby ").append(sortCss,FolderComponent.SORT_NAME.equals(sortOrder)).append("' "); ubu.buildHrefAndOnclick(sb, null, iframePostEnabled, false, false, new NameValuePair(PARAM_SORTID, FolderComponent.SORT_NAME)) - .append(">").append(translator.translate("header.Name")).append("</a>") - .append("</th><th><a class='o_orderby ").append(sortCss,FolderComponent.SORT_SIZE.equals(sortOrder)).append("' "); + .append(">").append(translator.translate("header.Name")).append("</a>").append("</th>"); + sb.append("<th>").append(translator.translate("header.license")).append("</th>"); + sb.append("<th><a class='o_orderby ").append(sortCss,FolderComponent.SORT_SIZE.equals(sortOrder)).append("' "); ubu.buildHrefAndOnclick(sb, null, iframePostEnabled, false, false, new NameValuePair(PARAM_SORTID, FolderComponent.SORT_SIZE)) .append(">").append(translator.translate("header.Size")).append("</a>") .append("</th><th><a class='o_orderby ").append(sortCss,FolderComponent.SORT_DATE.equals(sortOrder)).append("' "); @@ -339,6 +343,15 @@ public class ListRenderer { } sb.append("</td><td>"); + // license + MetaInfoFactory metaInfoFactory = CoreSpringFactory.getImpl(MetaInfoFactory.class); + License license = metaInfoFactory.getLicense(metaInfo); + if (license != null) { + LicenseRenderer licenseRenderer = new LicenseRenderer(translator.getLocale()); + licenseRenderer.render(sb, license); + } + sb.append("</td><td>"); + // filesize if (!isContainer) { // append filesize diff --git a/src/main/java/org/olat/core/commons/modules/bc/meta/MetaInfo.java b/src/main/java/org/olat/core/commons/modules/bc/meta/MetaInfo.java index 112b9108a4a..7f9f31ffa02 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/meta/MetaInfo.java +++ b/src/main/java/org/olat/core/commons/modules/bc/meta/MetaInfo.java @@ -205,6 +205,22 @@ public interface MetaInfo { public void setPublicationDate(String month, String year); + public String getLicenseTypeKey(); + + public void setLicenseTypeKey(String key); + + public String getLicenseTypeName(); + + public void setLicenseTypeName(String name); + + public String getLicenseText(); + + public void setLicenseText(String text); + + public String getLicensor(); + + public void setLicensor(String licensor); + public boolean isThumbnailAvailable(); diff --git a/src/main/java/org/olat/core/commons/modules/bc/meta/MetaInfoController.java b/src/main/java/org/olat/core/commons/modules/bc/meta/MetaInfoController.java index 9adc03173e1..38aea3f7df0 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/meta/MetaInfoController.java +++ b/src/main/java/org/olat/core/commons/modules/bc/meta/MetaInfoController.java @@ -24,6 +24,11 @@ import java.util.HashSet; import java.util.Set; import org.olat.core.CoreSpringFactory; +import org.olat.core.commons.modules.bc.FolderLicenseHandler; +import org.olat.core.commons.services.license.License; +import org.olat.core.commons.services.license.LicenseModule; +import org.olat.core.commons.services.license.LicenseService; +import org.olat.core.commons.services.license.ui.LicenseUIFactory; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItemContainer; @@ -57,7 +62,10 @@ import org.springframework.beans.factory.annotation.Autowired; public class MetaInfoController extends FormBasicController { private VFSItem item; private FormLink moreMetaDataLink; - private StaticTextElement publisher, creator, sourceEl, city, pages, language, url; + private StaticTextElement publisher, creator, sourceEl, city, pages, language, url, publicationDateEl;; + private StaticTextElement licenseEl; + private StaticTextElement licensorEl; + private StaticTextElement licenseFreetextEl; private SingleSelection locked; private Set<FormItem> metaFields; private String resourceUrl; @@ -66,6 +74,12 @@ public class MetaInfoController extends FormBasicController { private UserManager userManager; @Autowired private VFSLockManager vfsLockManager; + @Autowired + private LicenseModule licenseModule; + @Autowired + private LicenseService licenseService; + @Autowired + private FolderLicenseHandler licenseHandler; /** * Use this controller for editing meta data of an existing file. @@ -80,35 +94,21 @@ public class MetaInfoController extends FormBasicController { initForm(ureq); } - /** - * @see org.olat.core.gui.components.form.flexible.impl.FormBasicController#doDispose() - */ @Override protected void doDispose() { // nothing so far } - /** - * @see org.olat.core.gui.components.form.flexible.impl.FormBasicController#formOK(org.olat.core.gui.UserRequest) - */ @Override protected void formOK(UserRequest ureq) { //do nothing } - /** - * @see org.olat.core.gui.components.form.flexible.impl.FormBasicController#formCancelled(org.olat.core.gui.UserRequest) - */ @Override protected void formCancelled(UserRequest ureq) { fireEvent(ureq, Event.CANCELLED_EVENT); } - /** - * @see org.olat.core.gui.components.form.flexible.impl.FormBasicController#formInnerEvent(org.olat.core.gui.UserRequest, - * org.olat.core.gui.components.form.flexible.FormItem, - * org.olat.core.gui.components.form.flexible.impl.FormEvent) - */ @Override protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { if (source == moreMetaDataLink && event.wasTriggerdBy(FormEvent.ONCLICK)) { @@ -120,10 +120,6 @@ public class MetaInfoController extends FormBasicController { } } - /** - * @see org.olat.core.gui.components.form.flexible.impl.FormBasicController#initForm(org.olat.core.gui.components.form.flexible.FormItemContainer, - * org.olat.core.gui.control.Controller, org.olat.core.gui.UserRequest) - */ @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { setFormTitle("mf.metadata.title"); @@ -159,15 +155,10 @@ public class MetaInfoController extends FormBasicController { String cityVal = StringHelper.escapeHtml(meta != null ? meta.getCity() : null); city = uifactory.addStaticTextElement("mf.city", cityVal, formLayout); - // publish date - FormLayoutContainer publicationDate = FormLayoutContainer.createHorizontalFormLayout("publicationDateLayout", getTranslator()); - publicationDate.setLabel("mf.publishDate", null); - formLayout.add(publicationDate); - String[] pubDate = (meta != null ? meta.getPublicationDate() : new String[] { "", "" }); - uifactory.addStaticTextElement("mf.month", StringHelper.escapeHtml(pubDate[1]), publicationDate); - uifactory.addStaticTextElement("mf.year", StringHelper.escapeHtml(pubDate[0]), publicationDate); - + String publicationDate = new StringBuilder().append(translate("mf.month")).append(pubDate[0]).append(", ") + .append(translate("mf.year")).append(pubDate[1]).toString(); + publicationDateEl = uifactory.addStaticTextElement("mf.publishDate", publicationDate, formLayout); // number of pages String pageVal = StringHelper.escapeHtml(meta != null ? meta.getPages() : null); @@ -180,6 +171,24 @@ public class MetaInfoController extends FormBasicController { // url/link String urlVal = StringHelper.escapeHtml(meta != null ? meta.getUrl() : null); url = uifactory.addStaticTextElement("mf.url", urlVal, formLayout); + + // license + if (licenseModule.isEnabled(licenseHandler)) { + MetaInfoFactory metaInfoFactory = CoreSpringFactory.getImpl(MetaInfoFactory.class); + License license = metaInfoFactory.getOrCreateLicense(meta, getIdentity()); + boolean isNoLicense = !licenseService.isNoLicense(license.getLicenseType()); + boolean isFreetext = licenseService.isFreetext(license.getLicenseType()); + + licenseEl = uifactory.addStaticTextElement("mf.license", + LicenseUIFactory.translate(license.getLicenseType(), getLocale()), formLayout); + if (isNoLicense) { + licensorEl = uifactory.addStaticTextElement("mf.licensor", license.getLicensor(), formLayout); + } + if (isFreetext) { + licenseFreetextEl = uifactory.addStaticTextElement("mf.freetext", + LicenseUIFactory.getFormattedLicenseText(license), formLayout); + } + } /* static fields */ String sizeText, typeText; @@ -192,15 +201,24 @@ public class MetaInfoController extends FormBasicController { } // Targets to hide - metaFields = new HashSet<FormItem>(); + metaFields = new HashSet<>(); metaFields.add(creator); metaFields.add(publisher); metaFields.add(sourceEl); metaFields.add(city); - metaFields.add(publicationDate); + metaFields.add(publicationDateEl); metaFields.add(pages); metaFields.add(language); metaFields.add(url); + if (licenseEl != null) { + metaFields.add(licenseEl); + } + if (licensorEl != null) { + metaFields.add(licensorEl); + } + if (licenseFreetextEl != null) { + metaFields.add(licenseFreetextEl); + } if (!hasMetadata(meta)) { moreMetaDataLink = uifactory.addFormLink("mf.more.meta.link", formLayout, Link.LINK_CUSTOM_CSS); @@ -239,25 +257,22 @@ public class MetaInfoController extends FormBasicController { uifactory.addStaticTextElement("mf.lockedBy", lockedDetails, formLayout); // username - String author = StringHelper.escapeHtml(meta == null ? "" : meta.getHTMLFormattedAuthor()); + String author = StringHelper.escapeHtml(meta.getHTMLFormattedAuthor()); uifactory.addStaticTextElement("mf.author", author, formLayout); // filesize uifactory.addStaticTextElement("mf.size", StringHelper.escapeHtml(sizeText), formLayout); // last modified date - String lastModified = meta == null ? "" : StringHelper.formatLocaleDate(meta.getLastModified(), getLocale()); + String lastModified = StringHelper.formatLocaleDate(meta.getLastModified(), getLocale()); uifactory.addStaticTextElement("mf.lastModified", lastModified, formLayout); // file type uifactory.addStaticTextElement("mf.type", StringHelper.escapeHtml(typeText), formLayout); - String downloads = meta == null ? "" : String.valueOf(meta.getDownloadCount()); + String downloads = String.valueOf(meta.getDownloadCount()); uifactory.addStaticTextElement("mf.downloads", downloads, formLayout); - - // Don't show any meta data except title and comment if the item is - // a directory. - // Hide the metadata. + } else { setMetaFieldsVisible(false); if (moreMetaDataLink != null) { moreMetaDataLink.setVisible(false); @@ -292,8 +307,10 @@ public class MetaInfoController extends FormBasicController { || StringHelper.containsNonWhitespace(meta.getPublisher()) || StringHelper.containsNonWhitespace(meta.getSource()) || StringHelper.containsNonWhitespace(meta.getCity()) || StringHelper.containsNonWhitespace(meta.getPublicationDate()[0]) || StringHelper.containsNonWhitespace(meta.getPublicationDate()[1]) || StringHelper.containsNonWhitespace(meta.getPages()) - || StringHelper.containsNonWhitespace(meta.getLanguage()) || StringHelper.containsNonWhitespace(meta.getUrl()); - } + || StringHelper.containsNonWhitespace(meta.getLanguage()) || StringHelper.containsNonWhitespace(meta.getUrl()) + || StringHelper.containsNonWhitespace(meta.getLicenseTypeKey()) || StringHelper.containsNonWhitespace(meta.getLicenseTypeName()) + || StringHelper.containsNonWhitespace(meta.getLicenseText()) || StringHelper.containsNonWhitespace(meta.getLicensor()); + } return false; } @@ -307,4 +324,5 @@ public class MetaInfoController extends FormBasicController { formItem.setVisible(visible); } } + } \ No newline at end of file diff --git a/src/main/java/org/olat/core/commons/modules/bc/meta/MetaInfoFactory.java b/src/main/java/org/olat/core/commons/modules/bc/meta/MetaInfoFactory.java index b96b1b339a8..e83077d43a5 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/meta/MetaInfoFactory.java +++ b/src/main/java/org/olat/core/commons/modules/bc/meta/MetaInfoFactory.java @@ -26,10 +26,18 @@ package org.olat.core.commons.modules.bc.meta; import java.io.File; +import org.olat.core.CoreSpringFactory; import org.olat.core.commons.modules.bc.FolderConfig; +import org.olat.core.commons.modules.bc.FolderLicenseHandler; +import org.olat.core.commons.services.license.License; +import org.olat.core.commons.services.license.LicenseHandler; +import org.olat.core.commons.services.license.LicenseService; +import org.olat.core.commons.services.license.LicenseType; import org.olat.core.commons.services.thumbnail.ThumbnailService; +import org.olat.core.id.Identity; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; +import org.olat.core.util.StringHelper; import org.olat.core.util.vfs.OlatRelPathImpl; @@ -91,4 +99,48 @@ public class MetaInfoFactory { protected static File getOriginFile(OlatRelPathImpl olatRelPathImpl) { return new File(FolderConfig.getCanonicalRoot() + olatRelPathImpl.getRelPath()); } + + /** + * Get the license of the MetaInfo + * + * @param meta + * @return the license or null if no license is stored in the MetaInfo + */ + public License getLicense(MetaInfo meta) { + LicenseService licenseService = CoreSpringFactory.getImpl(LicenseService.class); + License license = null; + boolean hasLicense = meta != null && StringHelper.containsNonWhitespace(meta.getLicenseTypeName()); + if (hasLicense) { + String licenseTypeName = meta.getLicenseTypeName(); + LicenseType licenseType = licenseService.loadLicenseTypeByName(licenseTypeName); + if (licenseType == null) { + licenseType = licenseService.createLicenseType(licenseTypeName); + licenseType.setText(meta.getLicenseText()); + licenseService.saveLicenseType(licenseType); + } + license = licenseService.createLicense(licenseType); + license.setLicensor(meta.getLicensor()); + if (licenseService.isFreetext(licenseType)) { + license.setFreetext(meta.getLicenseText()); + } + } + return license; + } + + /** + * Get the license of the MetaInfo or create a new default license: + * + * @param meta + * @param itentity the current user + * @return + */ + public License getOrCreateLicense(MetaInfo meta, Identity itentity) { + LicenseHandler licenseHandler = CoreSpringFactory.getImpl(FolderLicenseHandler.class); + LicenseService licenseService = CoreSpringFactory.getImpl(LicenseService.class); + License license = getLicense(meta); + if (license == null) { + license = licenseService.createDefaultLicense(licenseHandler, itentity); + } + return license; + } } \ No newline at end of file diff --git a/src/main/java/org/olat/core/commons/modules/bc/meta/MetaInfoFileImpl.java b/src/main/java/org/olat/core/commons/modules/bc/meta/MetaInfoFileImpl.java index afb81ea0f9c..2eca8d3ea27 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/meta/MetaInfoFileImpl.java +++ b/src/main/java/org/olat/core/commons/modules/bc/meta/MetaInfoFileImpl.java @@ -103,6 +103,10 @@ public class MetaInfoFileImpl extends DefaultHandler implements MetaInfo { private Long lockedByIdentKey = null; private String comment = ""; private String title, publisher, creator, source, city, pages, language, url, pubMonth, pubYear; + private String licenseTypeKey; + private String licenseTypeName; + private String licenseText; + private String licensor; private Date lockedDate; private int downloadCount; private boolean locked; @@ -112,7 +116,7 @@ public class MetaInfoFileImpl extends DefaultHandler implements MetaInfo { private File metaFile = null; private boolean cannotGenerateThumbnail = false; - private List<Thumbnail> thumbnails = new ArrayList<Thumbnail>(); + private List<Thumbnail> thumbnails = new ArrayList<>(); private ThumbnailService thumbnailService; @@ -150,6 +154,7 @@ public class MetaInfoFileImpl extends DefaultHandler implements MetaInfo { * @param meta * @param newName */ + @Override public void rename(String newName) { // rename meta info file name if (isDirectory()) { // rename the directory, which is the parent of the actual ".xml" file @@ -165,6 +170,7 @@ public class MetaInfoFileImpl extends DefaultHandler implements MetaInfo { * @param targetDir * @param move */ + @Override public void moveCopyToDir(OlatRelPathImpl target, boolean move) { File fSource = metaFile; File fTarget = new File(MetaInfoFactory.getCanonicalMetaPath(target)); @@ -181,7 +187,7 @@ public class MetaInfoFileImpl extends DefaultHandler implements MetaInfo { if (move) FileUtils.moveFileToDir(fSource, fTarget); else { //copy - Map<String,String> pathToUuid = new HashMap<String,String>(); + Map<String,String> pathToUuid = new HashMap<>(); File mTarget = new File(fTarget, fSource.getName()); collectUUIDRec(mTarget, pathToUuid); @@ -242,6 +248,7 @@ public class MetaInfoFileImpl extends DefaultHandler implements MetaInfo { * Delete all associated meta info including sub files/directories * @param meta */ + @Override public void deleteAll() { if (isDirectory()) { // delete whole meta directory (where the ".xml" resides within) FileUtils.deleteDirsAndFiles(metaFile.getParentFile(), true, true); @@ -254,6 +261,7 @@ public class MetaInfoFileImpl extends DefaultHandler implements MetaInfo { * Copy values from froMeta into this object except name. * @param fromMeta */ + @Override public void copyValues(MetaInfo fromMeta) { this.setAuthor(fromMeta.getAuthor()); this.setComment(fromMeta.getComment()); @@ -309,6 +317,7 @@ public class MetaInfoFileImpl extends DefaultHandler implements MetaInfo { * does not write anything. * @return True upon success. */ + @Override public boolean write() { BufferedOutputStream bos = null; if (metaFile == null) return false; @@ -332,6 +341,10 @@ public class MetaInfoFileImpl extends DefaultHandler implements MetaInfo { sw.write("<pages><![CDATA[" + filterForCData(pages) + "]]></pages>"); sw.write("<language><![CDATA[" + filterForCData(language) + "]]></language>"); sw.write("<url><![CDATA[" + filterForCData(url) + "]]></url>"); + sw.write("<licenseTypeKey><![CDATA[" + filterForCData(licenseTypeKey) + "]]></licenseTypeKey>"); + sw.write("<licenseTypeName><![CDATA[" + filterForCData(licenseTypeName) + "]]></licenseTypeName>"); + sw.write("<licenseText><![CDATA[" + filterForCData(licenseText) + "]]></licenseText>"); + sw.write("<licensor><![CDATA[" + filterForCData(licensor) + "]]></licensor>"); sw.write("<publicationDate><month><![CDATA[" + (pubMonth != null ? pubMonth.trim() : "") + "]]></month><year><![CDATA[" + (pubYear != null ? pubYear.trim() : "") + "]]></year></publicationDate>"); sw.write("<downloadCount><![CDATA[" + downloadCount + "]]></downloadCount>"); sw.write("<thumbnails cannotGenerateThumbnail=\"" + cannotGenerateThumbnail + "\">"); @@ -377,6 +390,7 @@ public class MetaInfoFileImpl extends DefaultHandler implements MetaInfo { * * @return True upon success. */ + @Override public boolean delete() { if (metaFile == null) return false; for(Thumbnail thumbnail:thumbnails) { @@ -391,7 +405,7 @@ public class MetaInfoFileImpl extends DefaultHandler implements MetaInfo { /** * The parser is synchronized. Normally for such small files, this is * the quicker way. Creation of a SAXParser is really time consuming. - * An other possibilty would be to use a pool of parser. + * An other possibility would be to use a pool of parser. * @param fMeta * @return */ @@ -511,6 +525,14 @@ public class MetaInfoFileImpl extends DefaultHandler implements MetaInfo { language = (n != null) ? n.getText() : ""; n = root.element("url"); url = (n != null) ? n.getText() : ""; + n = root.element("licenseTypeKey"); + licenseTypeKey = (n != null) ? n.getText() : ""; + n = root.element("licenseName"); + licenseTypeName = (n != null) ? n.getText() : ""; + n = root.element("licenseText"); + licenseText = (n != null) ? n.getText() : ""; + n = root.element("licensor"); + licensor = (n != null) ? n.getText() : ""; n = root.element("downloadCount"); downloadCount = (n != null) ? Integer.valueOf(n.getText()) : 0; n = root.element("publicationDate"); @@ -532,6 +554,7 @@ public class MetaInfoFileImpl extends DefaultHandler implements MetaInfo { /** * @return name of the initial author */ + @Override public String getAuthor() { if (authorIdentKey == null) { return "-"; @@ -563,9 +586,6 @@ public class MetaInfoFileImpl extends DefaultHandler implements MetaInfo { return authorIdentKey; } - /** - * @see org.olat.core.commons.modules.bc.meta.MetaInfo#getAuthorIdentity() - */ @Override public Identity getAuthorIdentity() { if (authorIdentKey == null) { @@ -580,9 +600,7 @@ public class MetaInfoFileImpl extends DefaultHandler implements MetaInfo { return (authorIdentKey != null); } - /** - * @see org.olat.core.commons.modules.bc.meta.MetaInfo#getHTMLFormattedAuthor() - */ + @Override public String getHTMLFormattedAuthor() { if (authorIdentKey == null) { return "-"; @@ -596,28 +614,20 @@ public class MetaInfoFileImpl extends DefaultHandler implements MetaInfo { } } - /** - * @return comment - */ + @Override public String getComment() { return comment; } + @Override public String getName() { return originFile.getName(); } - /** - * @return True if this is a directory - */ + + @Override public boolean isDirectory() { return originFile.isDirectory(); } - /** - * @return Last modified timestamp - */ @Override public long getLastModified() { return originFile.lastModified(); } - /** - * @return The last modification date of the metadata - */ @Override public Date getMetaLastModified() { if(metaFile == null) return null; @@ -625,21 +635,13 @@ public class MetaInfoFileImpl extends DefaultHandler implements MetaInfo { return lastModified > 0 ? new Date(lastModified) : null; } - /** - * @return size of file - */ + @Override public long getSize() { return originFile.length(); } - /** - * @return formatted representation of size of file - */ + @Override public String getFormattedSize() { return Formatter.formatBytes(getSize()); } - /* ------------------------- Setters ------------------------------ */ - - /** - * @param string - */ + @Override public void setAuthor(String username) { Identity identity = BaseSecurityManager.getInstance().findIdentityByName(username); if (identity == null) { @@ -660,14 +662,9 @@ public class MetaInfoFileImpl extends DefaultHandler implements MetaInfo { authorIdentKey = identity.getKey(); } - /** - * @param string - */ + @Override public void setComment(String string) { comment = string; } - /** - * @see java.lang.Object#toString() - */ @Override public String toString() { StringBuilder sb = new StringBuilder(); @@ -680,140 +677,142 @@ public class MetaInfoFileImpl extends DefaultHandler implements MetaInfo { return sb.toString(); } - /** - * @see org.olat.core.commons.modules.bc.meta.MetaInfo#getCity() - */ + @Override public String getCity() { return city; } - /** - * @see org.olat.core.commons.modules.bc.meta.MetaInfo#getLanguage() - */ + @Override public String getLanguage() { return language; } - /** - * @see org.olat.core.commons.modules.bc.meta.MetaInfo#getPages() - */ + @Override public String getPages() { return pages; } - /** - * @see org.olat.core.commons.modules.bc.meta.MetaInfo#getPublishDate() - */ + @Override public String[] getPublicationDate() { return new String[] { pubYear, pubMonth }; } - /** - * @see org.olat.core.commons.modules.bc.meta.MetaInfo#getPublisher() - */ + @Override public String getPublisher() { return publisher; } - /** - * @see org.olat.core.commons.modules.bc.meta.MetaInfo#getCreator() - */ + @Override public String getCreator() { return creator; } - /** - * @see org.olat.core.commons.modules.bc.meta.MetaInfo#getSource() - */ + @Override public String getSource() { return source; } - /** - * @see org.olat.core.commons.modules.bc.meta.MetaInfo#getTitle() - */ + @Override public String getTitle() { return title; } - /** - * @see org.olat.core.commons.modules.bc.meta.MetaInfo#getUrl() - */ + @Override public String getUrl() { return url; } - /** - * @see org.olat.core.commons.modules.bc.meta.MetaInfo#setCity(java.lang.String) - */ + @Override public void setCity(String city) { this.city = city; } - /** - * @see org.olat.core.commons.modules.bc.meta.MetaInfo#setLanguage(java.lang.String) - */ + @Override public void setLanguage(String language) { this.language = language; } - /** - * @see org.olat.core.commons.modules.bc.meta.MetaInfo#setPages(java.lang.String) - */ + @Override public void setPages(String pages) { this.pages = pages; } - /** - * @see org.olat.core.commons.modules.bc.meta.MetaInfo#setPublishDate(java.lang.String) - */ + @Override public void setPublicationDate(String month, String year) { this.pubMonth = month; this.pubYear = year; } - /** - * @see org.olat.core.commons.modules.bc.meta.MetaInfo#setPublisher(java.lang.String) - */ + @Override public void setPublisher(String publisher) { this.publisher = publisher; } - /** - * @see org.olat.core.commons.modules.bc.meta.MetaInfo#setWriter(java.lang.String) - */ public void setWriter(String writer) { this.creator = writer; } - /** - * @see org.olat.core.commons.modules.bc.meta.MetaInfo#setWriter(java.lang.String) - */ + @Override public void setCreator(String creator) { this.creator = creator; } - /** - * @see org.olat.core.commons.modules.bc.meta.MetaInfo#setSource(java.lang.String) - */ + @Override public void setSource(String source) { this.source = source; } - /** - * @see org.olat.core.commons.modules.bc.meta.MetaInfo#setTitle(java.lang.String) - */ + @Override public void setTitle(String title) { this.title = title; } - /** - * @see org.olat.core.commons.modules.bc.meta.MetaInfo#setUrl(java.lang.String) - */ + @Override public void setUrl(String url) { this.url = url; } + + @Override + public String getLicenseTypeKey() { + return licenseTypeKey; + } + + @Override + public void setLicenseTypeKey(String key) { + this.licenseTypeKey = key; + } + + @Override + public String getLicenseTypeName() { + return licenseTypeName; + } + + @Override + public void setLicenseTypeName(String name) { + this.licenseTypeName = name; + } + + @Override + public String getLicenseText() { + return licenseText; + } + + @Override + public void setLicenseText(String text) { + this.licenseText = text; + } + + @Override + public String getLicensor() { + return licensor; + } + + @Override + public void setLicensor(String licensor) { + this.licensor = licensor; + } + @Override public boolean isThumbnailAvailable() { if(isDirectory()) return false; if(originFile.isHidden()) return false; @@ -824,6 +823,7 @@ public class MetaInfoFileImpl extends DefaultHandler implements MetaInfo { return false; } + @Override public VFSLeaf getThumbnail(int maxWidth, int maxHeight, boolean fill) { if(isDirectory()) return null; Thumbnail thumbnailInfo = getThumbnailInfo(maxWidth, maxHeight, fill); @@ -922,16 +922,12 @@ public class MetaInfoFileImpl extends DefaultHandler implements MetaInfo { return "jpg"; } - /** - * @see org.olat.core.commons.modules.bc.meta.MetaInfo#increaseDownloadCount() - */ + @Override public void increaseDownloadCount() { this.downloadCount++; } - /** - * @see org.olat.core.commons.modules.bc.meta.MetaInfo#getDownloadCount() - */ + @Override public int getDownloadCount() { return downloadCount; } @@ -1025,6 +1021,14 @@ public class MetaInfoFileImpl extends DefaultHandler implements MetaInfo { this.creator = current.toString(); } else if (qName.equals("url")) { this.url = current.toString(); + } else if (qName.equals("licenseTypeKey")) { + this.licenseTypeKey = current.toString(); + } else if (qName.equals("licenseTypeName")) { + this.licenseTypeName = current.toString(); + } else if (qName.equals("licenseText")) { + this.licenseText = current.toString(); + } else if (qName.equals("licensor")) { + this.licensor = current.toString(); } else if (qName.equals("thumbnail")) { String finalName = current.toString(); File thumbnailFile = new File(metaFile.getParentFile(), finalName); @@ -1033,9 +1037,6 @@ public class MetaInfoFileImpl extends DefaultHandler implements MetaInfo { current = null; } - /** - * @see org.olat.core.commons.modules.bc.meta.MetaInfo#getIconCssClass() - */ @Override public String getIconCssClass() { String cssClass; diff --git a/src/main/java/org/olat/core/commons/modules/bc/meta/MetaInfoFormController.java b/src/main/java/org/olat/core/commons/modules/bc/meta/MetaInfoFormController.java index 4547083bc51..e3d7fc03f9f 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/meta/MetaInfoFormController.java +++ b/src/main/java/org/olat/core/commons/modules/bc/meta/MetaInfoFormController.java @@ -29,11 +29,19 @@ import java.util.HashSet; import java.util.Set; import org.olat.core.CoreSpringFactory; +import org.olat.core.commons.modules.bc.FolderLicenseHandler; +import org.olat.core.commons.services.license.License; +import org.olat.core.commons.services.license.LicenseModule; +import org.olat.core.commons.services.license.LicenseService; +import org.olat.core.commons.services.license.LicenseType; +import org.olat.core.commons.services.license.ui.LicenseSelectionConfig; +import org.olat.core.commons.services.license.ui.LicenseUIFactory; 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.FormLink; import org.olat.core.gui.components.form.flexible.elements.SingleSelection; +import org.olat.core.gui.components.form.flexible.elements.TextAreaElement; import org.olat.core.gui.components.form.flexible.elements.TextElement; import org.olat.core.gui.components.form.flexible.impl.Form; import org.olat.core.gui.components.form.flexible.impl.FormBasicController; @@ -72,6 +80,9 @@ public class MetaInfoFormController extends FormBasicController { private FormLink moreMetaDataLink; private String initialFilename; private TextElement filename, title, publisher, creator, sourceEl, city, pages, language, url, comment, publicationMonth, publicationYear; + private SingleSelection licenseEl; + private TextElement licensorEl; + private TextAreaElement licenseFreetextEl; private SingleSelection locked; // Fields needed for upload dialog private boolean isSubform; @@ -86,6 +97,12 @@ public class MetaInfoFormController extends FormBasicController { private VFSLockManager vfsLockManager; @Autowired private MetaInfoFactory metaInfoFactory; + @Autowired + private LicenseModule licenseModule; + @Autowired + private LicenseService licenseService; + @Autowired + private FolderLicenseHandler licenseHandler; /** * Use this controller for editing meta data of an existing file. @@ -134,36 +151,22 @@ public class MetaInfoFormController extends FormBasicController { initForm(ureq); } - /** - * @see org.olat.core.gui.components.form.flexible.impl.FormBasicController#doDispose() - */ @Override protected void doDispose() { // nothing so far } - /** - * @see org.olat.core.gui.components.form.flexible.impl.FormBasicController#formOK(org.olat.core.gui.UserRequest) - */ @Override protected void formOK(UserRequest ureq) { // done, parent controller takes care of saving metadata... fireEvent(ureq, Event.DONE_EVENT); } - /** - * @see org.olat.core.gui.components.form.flexible.impl.FormBasicController#formCancelled(org.olat.core.gui.UserRequest) - */ @Override protected void formCancelled(UserRequest ureq) { fireEvent(ureq, Event.CANCELLED_EVENT); } - /** - * @see org.olat.core.gui.components.form.flexible.impl.FormBasicController#formInnerEvent(org.olat.core.gui.UserRequest, - * org.olat.core.gui.components.form.flexible.FormItem, - * org.olat.core.gui.components.form.flexible.impl.FormEvent) - */ @Override protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { if (source == moreMetaDataLink && event.wasTriggerdBy(FormEvent.ONCLICK)) { @@ -172,13 +175,11 @@ public class MetaInfoFormController extends FormBasicController { setMetaFieldsVisible(true); flc.setDirty(true); moreMetaDataLink.setVisible(false); + } else if (source == licenseEl) { + updateLicenseUI(); } } - /** - * @see org.olat.core.gui.components.form.flexible.impl.FormBasicController#initForm(org.olat.core.gui.components.form.flexible.FormItemContainer, - * org.olat.core.gui.control.Controller, org.olat.core.gui.UserRequest) - */ @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { if(isSubform) { @@ -247,6 +248,28 @@ public class MetaInfoFormController extends FormBasicController { // url/link String urlVal = (meta != null ? meta.getUrl() : null); url = uifactory.addTextElement("url", "mf.url", -1, urlVal, formLayout); + + if (licenseModule.isEnabled(licenseHandler)) { + MetaInfoFactory metaInfoFactory = CoreSpringFactory.getImpl(MetaInfoFactory.class); + License license = metaInfoFactory.getOrCreateLicense(meta, getIdentity()); + + LicenseSelectionConfig licenseSelectionConfig = LicenseUIFactory + .createLicenseSelectionConfig(licenseHandler, license.getLicenseType()); + licenseEl = uifactory.addDropdownSingleselect("mf.license", formLayout, + licenseSelectionConfig.getLicenseTypeKeys(), + licenseSelectionConfig.getLicenseTypeValues(getLocale())); + licenseEl.setMandatory(licenseSelectionConfig.isLicenseMandatory()); + if (licenseSelectionConfig.getSelectionLicenseTypeKey() != null) { + licenseEl.select(licenseSelectionConfig.getSelectionLicenseTypeKey(), true); + } + licenseEl.addActionListener(FormEvent.ONCHANGE); + + licensorEl = uifactory.addTextElement("mf.licensor", 1000, license.getLicensor(), formLayout); + + String freetext = licenseService.isFreetext(license.getLicenseType()) ? license.getFreetext() : ""; + licenseFreetextEl = uifactory.addTextAreaElement("mf.freetext", 4, 72, freetext, formLayout); + updateLicenseUI(); + } /* static fields */ String sizeText, typeText; @@ -259,7 +282,7 @@ public class MetaInfoFormController extends FormBasicController { } // Targets to hide - metaFields = new HashSet<FormItem>(); + metaFields = new HashSet<>(); metaFields.add(creator); metaFields.add(publisher); metaFields.add(sourceEl); @@ -268,6 +291,15 @@ public class MetaInfoFormController extends FormBasicController { metaFields.add(pages); metaFields.add(language); metaFields.add(url); + if (licenseEl != null) { + metaFields.add(licenseEl); + } + if (licensorEl != null) { + metaFields.add(licensorEl); + } + if (licenseFreetextEl != null) { + metaFields.add(licenseFreetextEl); + } if (!hasMetadata(meta)) { moreMetaDataLink = uifactory.addFormLink("mf.more.meta.link", formLayout, Link.LINK_CUSTOM_CSS); @@ -358,6 +390,23 @@ public class MetaInfoFormController extends FormBasicController { } } + private void updateLicenseUI() { + boolean licenseSelected = false; + boolean freetextSelected = false; + if (licenseEl != null && licenseEl.isOneSelected()) { + String selectedKey = licenseEl.getSelectedKey(); + LicenseType licenseType = licenseService.loadLicenseTypeByKey(selectedKey); + licenseSelected = !licenseService.isNoLicense(licenseType); + freetextSelected = licenseService.isFreetext(licenseType); + } + if (licensorEl != null) { + licensorEl.setVisible(licenseSelected); + } + if (licenseFreetextEl != null) { + licenseFreetextEl.setVisible(freetextSelected); + } + } + /** * @return True if one or more metadata fields are non-emtpy. */ @@ -366,7 +415,9 @@ public class MetaInfoFormController extends FormBasicController { || StringHelper.containsNonWhitespace(meta.getPublisher()) || StringHelper.containsNonWhitespace(meta.getSource()) || StringHelper.containsNonWhitespace(meta.getCity()) || StringHelper.containsNonWhitespace(meta.getPublicationDate()[0]) || StringHelper.containsNonWhitespace(meta.getPublicationDate()[1]) || StringHelper.containsNonWhitespace(meta.getPages()) - || StringHelper.containsNonWhitespace(meta.getLanguage()) || StringHelper.containsNonWhitespace(meta.getUrl()); + || StringHelper.containsNonWhitespace(meta.getLanguage()) || StringHelper.containsNonWhitespace(meta.getUrl()) + || StringHelper.containsNonWhitespace(meta.getLicenseTypeKey()) || StringHelper.containsNonWhitespace(meta.getLicenseTypeName()) + || StringHelper.containsNonWhitespace(meta.getLicenseText()) || StringHelper.containsNonWhitespace(meta.getLicensor()); } return false; } @@ -380,6 +431,9 @@ public class MetaInfoFormController extends FormBasicController { for (FormItem formItem : metaFields) { formItem.setVisible(visible); } + if (visible) { + updateLicenseUI(); + } } /** @@ -418,8 +472,37 @@ public class MetaInfoFormController extends FormBasicController { meta.setSource(sourceEl.getValue()); meta.setUrl(url.getValue()); meta.setPages(pages.getValue()); + License license = getLicenseFromFormItems(); + meta.setLicenseTypeKey(license.getLicenseType() != null? String.valueOf(license.getLicenseType().getKey()): ""); + meta.setLicenseTypeName(license.getLicenseType() != null? license.getLicenseType().getName(): ""); + meta.setLicensor(license.getLicensor()); + meta.setLicenseText(LicenseUIFactory.getLicenseText(license)); return meta; } + + private License getLicenseFromFormItems() { + License license = licenseService.createLicense(null); + String licensor = ""; + String freetext = ""; + if (licenseModule.isEnabled(licenseHandler)) { + if (licenseEl != null && licenseEl.isOneSelected()) { + String licenseTypeKey = licenseEl.getSelectedKey(); + LicenseType licneseType = licenseService.loadLicenseTypeByKey(licenseTypeKey); + license.setLicenseType(licneseType); + } + if (licensorEl != null && licensorEl.isVisible() && StringHelper.containsNonWhitespace(licensorEl.getValue())) { + licensor = licensorEl.getValue(); + } + if (licenseFreetextEl != null && licenseFreetextEl.isVisible() && StringHelper.containsNonWhitespace(licenseFreetextEl.getValue())) { + freetext = licenseFreetextEl.getValue(); + } + licensorEl.setValue(license.getLicensor()); + licenseFreetextEl.setValue(license.getFreetext()); + } + license.setLicensor(licensor); + license.setFreetext(freetext); + return license; + } /** * @return The updated MeatInfo object @@ -446,9 +529,6 @@ public class MetaInfoFormController extends FormBasicController { return getMetaInfo(meta); } - /** - * @see org.olat.core.gui.components.form.flexible.impl.FormBasicController#validateFormLogic(org.olat.core.gui.UserRequest) - */ @Override protected boolean validateFormLogic(UserRequest ureq) { boolean valid = true; @@ -493,8 +573,24 @@ public class MetaInfoFormController extends FormBasicController { } } + licenseEl.clearError(); + if (licenseEl != null && licenseEl.isMandatory() && isLicenseTypeNotSelected()) { + licenseEl.setErrorKey("form.legende.mandatory", null); + valid &= false; + } + return valid; } + + private boolean isLicenseTypeNotSelected() { + boolean isNoLicenseSelected = false; + if (licenseEl != null && licenseEl.isOneSelected()) { + String selectedKey = licenseEl.getSelectedKey(); + LicenseType selectedLicenseType = licenseService.loadLicenseTypeByKey(selectedKey); + isNoLicenseSelected = licenseService.isNoLicense(selectedLicenseType); + } + return isNoLicenseSelected; + } /** * Get the form item representing this form diff --git a/src/main/java/org/olat/core/commons/modules/bc/meta/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/core/commons/modules/bc/meta/_i18n/LocalStrings_de.properties index c3f25a80628..0378d3ea66e 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/meta/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/core/commons/modules/bc/meta/_i18n/LocalStrings_de.properties @@ -16,9 +16,12 @@ mf.error.filename.invalidchars=Der Name des Objektes enth\u00E4lt ung\u00FCltige mf.file=Datei mf.filename=Dateiname mf.filename.warning=<i class\="o_icon o_icon_warn"> </i> Der Dateiname enthielt unzul\u00E4ssige Zeichen. Diese wurden entfernt. +mf.freetext=Lizenztext mf.header=Metadaten Datei/Ordner mf.language=Sprache mf.lastModified=Datum letzte \u00C4nderung +mf.license=Lizenz +mf.licensor=Lizenzgeber mf.locked=Gesperrt mf.locked.description={0} am {1} mf.lockedBy=Gesperrt von diff --git a/src/main/java/org/olat/core/commons/modules/bc/meta/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/core/commons/modules/bc/meta/_i18n/LocalStrings_en.properties index f2efe0a5b29..7dc14d61612 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/meta/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/core/commons/modules/bc/meta/_i18n/LocalStrings_en.properties @@ -16,9 +16,12 @@ mf.error.filename.invalidchars=The object's name contains invalid characters. mf.file=File mf.filename=File name mf.filename.warning=<i class\="o_icon o_icon_warn"> </i> This file name contained invalid characters which were removed. +mf.freetext=License text mf.header=Metadata file/folder mf.language=Language mf.lastModified=Last modified\: +mf.license=License +mf.licensor=Licensor mf.locked=Locked mf.locked.description={0} on {1} mf.lockedBy=Locked by diff --git a/src/main/java/org/olat/core/commons/services/license/License.java b/src/main/java/org/olat/core/commons/services/license/License.java index 633eb598813..2a45bc5cbb6 100644 --- a/src/main/java/org/olat/core/commons/services/license/License.java +++ b/src/main/java/org/olat/core/commons/services/license/License.java @@ -19,20 +19,13 @@ */ package org.olat.core.commons.services.license; -import org.olat.core.id.CreateInfo; -import org.olat.core.id.ModifiedInfo; - /** * * Initial date: 21.02.2018<br> * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com * */ -public interface License extends CreateInfo, ModifiedInfo { - - public String getResName(); - - public Long getResId(); +public interface License { public String getLicensor(); diff --git a/src/main/java/org/olat/core/commons/services/license/LicenseService.java b/src/main/java/org/olat/core/commons/services/license/LicenseService.java index e7bd7aabcd5..1d1d1ac2a25 100644 --- a/src/main/java/org/olat/core/commons/services/license/LicenseService.java +++ b/src/main/java/org/olat/core/commons/services/license/LicenseService.java @@ -40,16 +40,33 @@ import org.olat.resource.OLATResource; */ public interface LicenseService { + /** + * Create a new license. + * @param licenseType TODO + * + * @return + */ + public License createLicense(LicenseType licenseType); + + /** + * Create a new license with the default license type. + * + * @param licenseHandler + * @param identity + */ + public License createDefaultLicense(LicenseHandler licenseHandler, Identity identity); + /** * Create a new license with the default license type. This method should be - * used if a license is created for a new object e.g. a new learning resource. + * used if a license is created for a new resourceable object e.g. a new + * learning resource. * * @param ores * @param handler * @param licensor * @return */ - public License createDefaultLicense(OLATResourceable ores, LicenseHandler handler, Identity licensor); + public ResourceLicense createDefaultLicense(OLATResourceable ores, LicenseHandler handler, Identity licensor); /** * Load the license of a resource. If no license was found, a new license with @@ -61,7 +78,7 @@ public interface LicenseService { * @param ores * @return */ - public License loadOrCreateLicense(OLATResourceable ores); + public ResourceLicense loadOrCreateLicense(OLATResourceable ores); /** * Load the licenses for the resources. @@ -69,7 +86,7 @@ public interface LicenseService { * @param resources * @return */ - public List<License> loadLicenses(Collection<OLATResourceable> resources); + public List<ResourceLicense> loadLicenses(Collection<OLATResourceable> resources); /** * Save the license. @@ -77,7 +94,7 @@ public interface LicenseService { * @param license * @return */ - public License update(License license); + public ResourceLicense update(ResourceLicense license); /** * Check whether a license type with that name exists. @@ -106,11 +123,20 @@ public interface LicenseService { /** * Load a license type by its key. * - * @param licenseTypeKey the key of the license type as a String. + * @param licenseTypeKey the key of the license type as a String * @return the license type or null if no license type was found for the key */ public LicenseType loadLicenseTypeByKey(String licenseTypeKey); + + /** + * Load a license type by its name + * + * @param name the name of the license type + * @return the license type or null if no license type was found for the name + */ + public LicenseType loadLicenseTypeByName(String name); + /** * Load all license types. This method is primarily intended for the * administration of license types. Regular clients of the license service diff --git a/src/main/java/org/olat/core/commons/services/license/ResourceLicense.java b/src/main/java/org/olat/core/commons/services/license/ResourceLicense.java new file mode 100644 index 00000000000..6d8e0d6352c --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/license/ResourceLicense.java @@ -0,0 +1,38 @@ +/** + * <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.license; + +import org.olat.core.id.CreateInfo; +import org.olat.core.id.ModifiedInfo; + +/** + * License for a OLATResource. A ResourceLicense can be stored in the database. + * + * Initial date: 21.02.2018<br> + * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com + * + */ +public interface ResourceLicense extends CreateInfo, ModifiedInfo, License { + + public String getResName(); + + public Long getResId(); + +} diff --git a/src/main/java/org/olat/core/commons/services/license/manager/LicenseServiceImpl.java b/src/main/java/org/olat/core/commons/services/license/manager/LicenseServiceImpl.java index 3ee7672c9e0..f8a167acabf 100644 --- a/src/main/java/org/olat/core/commons/services/license/manager/LicenseServiceImpl.java +++ b/src/main/java/org/olat/core/commons/services/license/manager/LicenseServiceImpl.java @@ -27,6 +27,8 @@ import org.olat.core.commons.services.license.LicenseHandler; import org.olat.core.commons.services.license.LicenseModule; import org.olat.core.commons.services.license.LicenseService; import org.olat.core.commons.services.license.LicenseType; +import org.olat.core.commons.services.license.ResourceLicense; +import org.olat.core.commons.services.license.model.LicenseImpl; import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; import org.springframework.beans.factory.annotation.Autowired; @@ -45,7 +47,7 @@ class LicenseServiceImpl implements LicenseService { @Autowired private LicenseModule licenseModule; @Autowired - private LicenseDAO licenseDao; + private ResourceLicenseDAO licenseDao; @Autowired private LicenseTypeDAO licenseTypeDao; @Autowired @@ -54,16 +56,42 @@ class LicenseServiceImpl implements LicenseService { private LicensorFactory licensorFactory; @Override - public License createDefaultLicense(OLATResourceable ores, LicenseHandler handler, Identity licensor) { - String defaultLicenseTypeKey = licenseModule.getDefaultLicenseTypeKey(handler); - LicenseType defautlLicenseType = loadLicenseTypeByKey(defaultLicenseTypeKey); + public License createLicense(LicenseType licenseType) { + License license = new LicenseImpl(); + license.setLicenseType(licenseType); + return license; + + } + + @Override + public License createDefaultLicense(LicenseHandler handler, Identity licensor) { + LicenseType defautlLicenseType = getDefaultLicenseType(handler); + String licensorName = licensorFactory.create(handler, licensor); + License license = new LicenseImpl(); + license.setLicenseType(defautlLicenseType); + license.setLicensor(licensorName); + return license; + } + + @Override + public ResourceLicense createDefaultLicense(OLATResourceable ores, LicenseHandler handler, Identity licensor) { + LicenseType defautlLicenseType = getDefaultLicenseType(handler); String licensorName = licensorFactory.create(handler, licensor); return licenseDao.createAndPersist(ores, defautlLicenseType, licensorName); } + + private LicenseType getDefaultLicenseType(LicenseHandler handler) { + String defaultLicenseTypeKey = licenseModule.getDefaultLicenseTypeKey(handler); + LicenseType defautlLicenseType = loadLicenseTypeByKey(defaultLicenseTypeKey); + if (defautlLicenseType == null) { + defautlLicenseType = licenseTypeDao.loadNoLicenseType(); + } + return defautlLicenseType; + } @Override - public License loadOrCreateLicense(OLATResourceable ores) { - License license = licenseDao.loadByResource(ores); + public ResourceLicense loadOrCreateLicense(OLATResourceable ores) { + ResourceLicense license = licenseDao.loadByResource(ores); if (license == null) { LicenseType licenseType = licenseTypeDao.loadNoLicenseType(); license = licenseDao.createAndPersist(ores, licenseType); @@ -72,12 +100,12 @@ class LicenseServiceImpl implements LicenseService { } @Override - public License update(License license) { + public ResourceLicense update(ResourceLicense license) { return licenseDao.save(license); } @Override - public List<License> loadLicenses(Collection<OLATResourceable> resources) { + public List<ResourceLicense> loadLicenses(Collection<OLATResourceable> resources) { return licenseDao.loadLicenses(resources); } @@ -106,6 +134,11 @@ class LicenseServiceImpl implements LicenseService { } return licenseTypeDao.loadLicenseTypeByKey(key); } + + @Override + public LicenseType loadLicenseTypeByName(String name) { + return licenseTypeDao.loadLicenseTypeByName(name); + } @Override public List<LicenseType> loadLicenseTypes() { diff --git a/src/main/java/org/olat/core/commons/services/license/manager/LicenseTypeDAO.java b/src/main/java/org/olat/core/commons/services/license/manager/LicenseTypeDAO.java index 1f88a984639..21f2b95c2d2 100644 --- a/src/main/java/org/olat/core/commons/services/license/manager/LicenseTypeDAO.java +++ b/src/main/java/org/olat/core/commons/services/license/manager/LicenseTypeDAO.java @@ -26,6 +26,7 @@ import org.olat.core.commons.persistence.DB; import org.olat.core.commons.services.license.LicenseHandler; import org.olat.core.commons.services.license.LicenseType; import org.olat.core.commons.services.license.model.LicenseTypeImpl; +import org.olat.core.util.StringHelper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -109,6 +110,18 @@ class LicenseTypeDAO { return licenseTypes == null || licenseTypes.isEmpty() ? null : licenseTypes.get(0); } + LicenseType loadLicenseTypeByName(String name) { + if (!StringHelper.containsNonWhitespace(name)) return null; + + String query = "select licensetype from licensetype licensetype where licensetype.name=:name"; + List<LicenseType> licenseTypes = dbInstance.getCurrentEntityManager() + .createQuery(query, LicenseType.class) + .setParameter("name", name) + .getResultList(); + return licenseTypes == null || licenseTypes.isEmpty() ? null : licenseTypes.get(0); + } + + List<LicenseType> loadLicenseTypes() { String query = "select licensetype from licensetype licensetype"; return dbInstance.getCurrentEntityManager() @@ -144,5 +157,5 @@ class LicenseTypeDAO { return number != null && number > 0; } - + } diff --git a/src/main/java/org/olat/core/commons/services/license/manager/LicenseDAO.java b/src/main/java/org/olat/core/commons/services/license/manager/ResourceLicenseDAO.java similarity index 80% rename from src/main/java/org/olat/core/commons/services/license/manager/LicenseDAO.java rename to src/main/java/org/olat/core/commons/services/license/manager/ResourceLicenseDAO.java index 800167c88dd..2a0ccf2dc6b 100644 --- a/src/main/java/org/olat/core/commons/services/license/manager/LicenseDAO.java +++ b/src/main/java/org/olat/core/commons/services/license/manager/ResourceLicenseDAO.java @@ -27,9 +27,9 @@ import java.util.List; import java.util.Set; import org.olat.core.commons.persistence.DB; -import org.olat.core.commons.services.license.License; +import org.olat.core.commons.services.license.ResourceLicense; import org.olat.core.commons.services.license.LicenseType; -import org.olat.core.commons.services.license.model.LicenseImpl; +import org.olat.core.commons.services.license.model.ResourceLicenseImpl; import org.olat.core.id.OLATResourceable; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -41,17 +41,17 @@ import org.springframework.stereotype.Service; * */ @Service -class LicenseDAO { +class ResourceLicenseDAO { @Autowired private DB dbInstance; - License createAndPersist(OLATResourceable ores, LicenseType licenseType) { + ResourceLicense createAndPersist(OLATResourceable ores, LicenseType licenseType) { return createAndPersist(ores, licenseType, null); } - License createAndPersist(OLATResourceable ores, LicenseType licenseType, String licensor) { - LicenseImpl license = new LicenseImpl(); + ResourceLicense createAndPersist(OLATResourceable ores, LicenseType licenseType, String licensor) { + ResourceLicenseImpl license = new ResourceLicenseImpl(); Date now = new Date(); license.setCreationDate(now); license.setLastModified(now); @@ -62,13 +62,13 @@ class LicenseDAO { return license; } - License save(License license) { + ResourceLicense save(ResourceLicense license) { license.setLastModified(new Date()); license = dbInstance.getCurrentEntityManager().merge(license); return license; } - License loadByResource(OLATResourceable ores) { + ResourceLicense loadByResource(OLATResourceable ores) { if (ores == null) return null; String query = new StringBuilder(256) @@ -77,15 +77,15 @@ class LicenseDAO { .append(" inner join fetch license.licenseType as licenseType") .append(" where license.resName=:resName and license.resId=:resId") .toString(); - List<License> licenses = dbInstance.getCurrentEntityManager() - .createQuery(query, License.class) + List<ResourceLicense> licenses = dbInstance.getCurrentEntityManager() + .createQuery(query, ResourceLicense.class) .setParameter("resName", ores.getResourceableTypeName()) .setParameter("resId", ores.getResourceableId()) .getResultList(); return licenses == null || licenses.isEmpty() ? null : licenses.get(0); } - List<License> loadLicenses(Collection<OLATResourceable> resources) { + List<ResourceLicense> loadLicenses(Collection<OLATResourceable> resources) { if (resources == null || resources.isEmpty()) return new ArrayList<>(); Set<String> resNames = new HashSet<>(); @@ -103,7 +103,7 @@ class LicenseDAO { .append(" and license.resId in (:resIds)") .toString(); return dbInstance.getCurrentEntityManager() - .createQuery(query, License.class) + .createQuery(query, ResourceLicense.class) .setParameter("resNames", resNames) .setParameter("resIds", resIds) .getResultList(); diff --git a/src/main/java/org/olat/core/commons/services/license/model/LicenseImpl.java b/src/main/java/org/olat/core/commons/services/license/model/LicenseImpl.java index 4a18c4b4cf2..acad760c614 100644 --- a/src/main/java/org/olat/core/commons/services/license/model/LicenseImpl.java +++ b/src/main/java/org/olat/core/commons/services/license/model/LicenseImpl.java @@ -19,158 +19,49 @@ */ package org.olat.core.commons.services.license.model; -import java.util.Date; - -import javax.persistence.Column; -import javax.persistence.Entity; -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.core.commons.services.license.License; import org.olat.core.commons.services.license.LicenseType; -import org.olat.core.id.OLATResourceable; -import org.olat.core.id.Persistable; /** * - * Initial date: 22.02.2018<br> + * Initial date: 02.03.2018<br> * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com * */ -@Entity(name="license") -@Table(name="o_lic_license") -public class LicenseImpl implements License, Persistable { - - private static final long serialVersionUID = -2044258667835611801L; - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name="id", nullable=false, unique=true, insertable=true, updatable=false) - private Long key; +public class LicenseImpl implements License { - @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="l_resname", nullable=false, insertable=true, updatable=false) - private String resName; - @Column(name="l_resid", nullable=false, insertable=true, updatable=false) - private Long resId; - @Column(name="l_licensor", nullable=true, insertable=true, updatable=true) + private LicenseType licenseType; private String licensor; - @Column(name="l_freetext", nullable=true, insertable=true, updatable=true) private String freetext; - @ManyToOne(targetEntity=LicenseTypeImpl.class, optional=false) - @JoinColumn(name="fk_license_type_id", nullable=false, insertable=true, updatable=true) - private LicenseType licenseType; - - @Override - public Long getKey() { - return key; - }; - - @Override - public Date getCreationDate() { - return creationDate; - } - - public void setCreationDate(Date creationDate) { - this.creationDate = creationDate; - } - - @Override - public Date getLastModified() { - return lastModified; - } - @Override - public void setLastModified(Date lastModified) { - this.lastModified = lastModified; + public LicenseType getLicenseType() { + return licenseType; } @Override - public String getResName() { - return resName; - } - - @Override - public Long getResId() { - return resId; - } - - public void setOLATResourceable(OLATResourceable ores) { - this.resName = ores.getResourceableTypeName(); - this.resId = ores.getResourceableId(); + public void setLicenseType(LicenseType licenseType) { + this.licenseType = licenseType; } - + @Override public String getLicensor() { return licensor; } - + @Override public void setLicensor(String licensor) { this.licensor = licensor; } - + @Override public String getFreetext() { return freetext; } - + @Override public void setFreetext(String freetext) { this.freetext = freetext; } - - @Override - public LicenseType getLicenseType() { - return licenseType; - } - - @Override - public void setLicenseType(LicenseType licenseType) { - this.licenseType = licenseType; - } - - @Override - public boolean equalsByPersistableKey(Persistable persistable) { - return equals(persistable); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((key == null) ? 0 : key.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - LicenseImpl other = (LicenseImpl) obj; - if (key == null) { - if (other.key != null) - return false; - } else if (!key.equals(other.key)) - return false; - return true; - } - + } diff --git a/src/main/java/org/olat/core/commons/services/license/model/ResourceLicenseImpl.java b/src/main/java/org/olat/core/commons/services/license/model/ResourceLicenseImpl.java new file mode 100644 index 00000000000..ecfd605dc14 --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/license/model/ResourceLicenseImpl.java @@ -0,0 +1,176 @@ +/** + * <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.license.model; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +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.core.commons.services.license.ResourceLicense; +import org.olat.core.commons.services.license.LicenseType; +import org.olat.core.id.OLATResourceable; +import org.olat.core.id.Persistable; + +/** + * + * Initial date: 22.02.2018<br> + * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com + * + */ +@Entity(name="license") +@Table(name="o_lic_license") +public class ResourceLicenseImpl implements ResourceLicense, Persistable { + + private static final long serialVersionUID = -2044258667835611801L; + + @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="l_resname", nullable=false, insertable=true, updatable=false) + private String resName; + @Column(name="l_resid", nullable=false, insertable=true, updatable=false) + private Long resId; + @Column(name="l_licensor", nullable=true, insertable=true, updatable=true) + private String licensor; + @Column(name="l_freetext", nullable=true, insertable=true, updatable=true) + private String freetext; + + @ManyToOne(targetEntity=LicenseTypeImpl.class, optional=false) + @JoinColumn(name="fk_license_type_id", nullable=false, insertable=true, updatable=true) + private LicenseType licenseType; + + @Override + public Long getKey() { + return key; + }; + + @Override + public Date getCreationDate() { + return creationDate; + } + + public void setCreationDate(Date creationDate) { + this.creationDate = creationDate; + } + + @Override + public Date getLastModified() { + return lastModified; + } + + @Override + public void setLastModified(Date lastModified) { + this.lastModified = lastModified; + } + + @Override + public String getResName() { + return resName; + } + + @Override + public Long getResId() { + return resId; + } + + public void setOLATResourceable(OLATResourceable ores) { + this.resName = ores.getResourceableTypeName(); + this.resId = ores.getResourceableId(); + } + + @Override + public String getLicensor() { + return licensor; + } + + @Override + public void setLicensor(String licensor) { + this.licensor = licensor; + } + + @Override + public String getFreetext() { + return freetext; + } + + @Override + public void setFreetext(String freetext) { + this.freetext = freetext; + } + + @Override + public LicenseType getLicenseType() { + return licenseType; + } + + @Override + public void setLicenseType(LicenseType licenseType) { + this.licenseType = licenseType; + } + + @Override + public boolean equalsByPersistableKey(Persistable persistable) { + return equals(persistable); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((key == null) ? 0 : key.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ResourceLicenseImpl other = (ResourceLicenseImpl) obj; + if (key == null) { + if (other.key != null) + return false; + } else if (!key.equals(other.key)) + return false; + return true; + } + +} diff --git a/src/main/java/org/olat/core/commons/services/license/ui/LicenseQuickviewController.java b/src/main/java/org/olat/core/commons/services/license/ui/LicenseQuickviewController.java deleted file mode 100644 index 2785db08d84..00000000000 --- a/src/main/java/org/olat/core/commons/services/license/ui/LicenseQuickviewController.java +++ /dev/null @@ -1,71 +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.services.license.ui; - -import org.olat.core.commons.services.license.License; -import org.olat.core.commons.services.license.LicenseType; -import org.olat.core.gui.UserRequest; -import org.olat.core.gui.components.form.flexible.FormItemContainer; -import org.olat.core.gui.components.form.flexible.impl.FormBasicController; -import org.olat.core.gui.control.Controller; -import org.olat.core.gui.control.WindowControl; -import org.olat.core.util.StringHelper; - -/** - * - * Initial date: 27.02.2018<br> - * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com - * - */ -public class LicenseQuickviewController extends FormBasicController { - - private final License license; - private final LicenseType licenseType; - - public LicenseQuickviewController(UserRequest ureq, WindowControl wControl, License license) { - super(ureq, wControl, LAYOUT_VERTICAL); - this.license = license; - this.licenseType = license.getLicenseType(); - initForm(ureq); - } - - @Override - protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { - String type = licenseType != null? LicenseUIFactory.translate(licenseType, getLocale()): ""; - uifactory.addStaticTextElement("license.quickview.type", type, formLayout); - - String licensor = StringHelper.containsNonWhitespace(license.getLicensor())? license.getLicensor(): ""; - uifactory.addStaticTextElement("license.quickview.licensor", licensor, formLayout); - - uifactory.addStaticTextElement("license.quickview.text", LicenseUIFactory.getFormattedLicenseText(license), - formLayout); - } - - @Override - protected void formOK(UserRequest ureq) { - // - } - - @Override - protected void doDispose() { - // - } - -} diff --git a/src/main/java/org/olat/core/commons/services/license/ui/LicenseRenderer.java b/src/main/java/org/olat/core/commons/services/license/ui/LicenseRenderer.java index 9f3bd5bfb67..c71bd271774 100644 --- a/src/main/java/org/olat/core/commons/services/license/ui/LicenseRenderer.java +++ b/src/main/java/org/olat/core/commons/services/license/ui/LicenseRenderer.java @@ -21,7 +21,6 @@ package org.olat.core.commons.services.license.ui; import java.util.Locale; -import org.apache.commons.lang.StringEscapeUtils; import org.olat.core.commons.services.license.License; import org.olat.core.commons.services.license.LicenseType; import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiCellRenderer; @@ -30,7 +29,8 @@ 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.util.StringHelper; +import org.olat.core.util.CodeHelper; +import org.olat.core.util.Util; /** * @@ -40,67 +40,56 @@ import org.olat.core.util.StringHelper; */ public class LicenseRenderer implements FlexiCellRenderer { - private final String idPrefix; private final Locale locale; + private final Translator translator; public LicenseRenderer(Locale locale) { - this(locale, null); - } - - public LicenseRenderer(Locale locale, String idPrefix) { this.locale = locale; - this.idPrefix = idPrefix; + translator = Util.createPackageTranslator(LicenseAdminConfigController.class, locale); } @Override public void render(Renderer renderer, StringOutput target, Object cellValue, int row, FlexiTableComponent source, URLBuilder ubu, Translator translator) { if (cellValue instanceof License) { License license = (License) cellValue; - LicenseType licenseType = license.getLicenseType(); if (renderer == null) { // render for export - if (licenseType != null) { - target.append(LicenseUIFactory.translate(licenseType, locale)); - } + target.append(LicenseUIFactory.translate(license.getLicenseType(), locale)); } else { - target.append("<div"); - target.append(" style='white-space: nowrap;'"); - String hoverText = getHoverText(licenseType); - if (StringHelper.containsNonWhitespace(hoverText)) { - target.append(" title=\""); - target.append(StringEscapeUtils.escapeHtml(hoverText)); - } - target.append("\">"); - target.append("<i"); - String id = getId(row); - if (StringHelper.containsNonWhitespace(id)) { - target.append(" id='").append(id).append("'"); - } - target.append(" class='").append(getCssClass(licenseType)).append("'> </i>"); - target.append("</div>"); + render(target, license); } } } - protected String getCssClass(LicenseType licenseType) { - if (licenseType != null) { - return "o_icon o_icon-lg " + LicenseUIFactory.getCssOrDefault(licenseType); - } - return null; - } - - private String getHoverText(LicenseType licenseType) { - if (licenseType != null) { - return LicenseUIFactory.translate(licenseType, locale); - } - return null; + public void render(StringOutput sb, License license) { + LicenseType licenseType = license.getLicenseType(); + long id = CodeHelper.getRAMUniqueID(); + + // license icon + sb.append("<a id='o_lic_").append(id).append("' href='javascript:;'><i class='o_icon o_icon-lg "); + sb.append(LicenseUIFactory.getCssOrDefault(licenseType)); + sb.append("'></i></a>"); + + // popup with license informations + sb.append("<div id='o_lic_pop_").append(id).append("' style='display:none;'><div>"); + appendStaticcontrol(sb, "license.popup.type", LicenseUIFactory.translate(licenseType, locale)); + appendStaticcontrol(sb, "license.popup.licensor", license.getLicensor()); + appendStaticcontrol(sb, "license.popup.text", LicenseUIFactory.getFormattedLicenseText(license)); + sb.append("</div>"); + + // JavaScript to pup up the popup + sb.append("<script type='text/javascript'>") + .append("/* <![CDATA[ */") + .append("jQuery(function() {\n") + .append(" o_popover('o_lic_").append(id).append("','o_lic_pop_").append(id).append("','top');\n") + .append("});") + .append("/* ]]> */") + .append("</script>"); } - private String getId(int row) { - if (StringHelper.containsNonWhitespace(idPrefix)) { - return idPrefix + String.valueOf(row); - } - return null; + private void appendStaticcontrol(StringOutput sb, String i18n, String text) { + sb.append("<label class='control-label'>").append(translator.translate(i18n)) .append("</label>"); + sb.append("<p class='form-control-static'>").append(text).append("</p>"); } } diff --git a/src/main/java/org/olat/core/commons/services/license/ui/LicenseSelectionConfig.java b/src/main/java/org/olat/core/commons/services/license/ui/LicenseSelectionConfig.java index 016efc26936..6d41e286c77 100644 --- a/src/main/java/org/olat/core/commons/services/license/ui/LicenseSelectionConfig.java +++ b/src/main/java/org/olat/core/commons/services/license/ui/LicenseSelectionConfig.java @@ -24,7 +24,6 @@ import java.util.List; import java.util.Locale; import org.olat.core.CoreSpringFactory; -import org.olat.core.commons.services.license.License; import org.olat.core.commons.services.license.LicenseHandler; import org.olat.core.commons.services.license.LicenseService; import org.olat.core.commons.services.license.LicenseType; @@ -49,14 +48,14 @@ public class LicenseSelectionConfig { private final LicenseService licenseService; - public LicenseSelectionConfig(LicenseHandler licenseHandler, License license) { - this(CoreSpringFactory.getImpl(LicenseService.class), licenseHandler, license); + public LicenseSelectionConfig(LicenseHandler licenseHandler, LicenseType actualLicenseType) { + this(CoreSpringFactory.getImpl(LicenseService.class), licenseHandler, actualLicenseType); } // Used for testing - LicenseSelectionConfig(LicenseService licenseService, LicenseHandler licenseHandler, License license) { + LicenseSelectionConfig(LicenseService licenseService, LicenseHandler licenseHandler, LicenseType actualLicenseType) { this.licenseService = licenseService; - this.actualLicenseType = license.getLicenseType(); + this.actualLicenseType = actualLicenseType; init(licenseHandler); } diff --git a/src/main/java/org/olat/core/commons/services/license/ui/LicenseUIFactory.java b/src/main/java/org/olat/core/commons/services/license/ui/LicenseUIFactory.java index ae1b97ca91a..53ad1e4a46f 100644 --- a/src/main/java/org/olat/core/commons/services/license/ui/LicenseUIFactory.java +++ b/src/main/java/org/olat/core/commons/services/license/ui/LicenseUIFactory.java @@ -45,8 +45,8 @@ public class LicenseUIFactory { // should not be instantiated } - public static LicenseSelectionConfig createLicenseSelectionConfig(LicenseHandler handler, License license) { - return new LicenseSelectionConfig(handler, license); + public static LicenseSelectionConfig createLicenseSelectionConfig(LicenseHandler handler, LicenseType actualLicenseType) { + return new LicenseSelectionConfig(handler, actualLicenseType); } public static String translate(LicenseType licenseType, Locale locale) { diff --git a/src/main/java/org/olat/core/commons/services/license/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/core/commons/services/license/ui/_i18n/LocalStrings_de.properties index 886751d32c0..0411b4e3a65 100644 --- a/src/main/java/org/olat/core/commons/services/license/ui/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/core/commons/services/license/ui/_i18n/LocalStrings_de.properties @@ -13,9 +13,9 @@ admin.title=Lizenzen edit.license.type=Lizenz bearbeiten error.is.default.license.type=Sie k\u00f6nnen diese Lizenz nicht deaktivieren, da diese Lizenz die iniziale Lizenz ist. \u00c4ndern Sie bitte zuerst die iniziale Lizenz. error.license.type.name.exists=Dieser Name existiert bereits. Der Name muss eindeutig sein. -license.quickview.text=Lizenztext -license.quickview.licensor=Lizenzgeber -license.quickview.type=Lizenz +license.popup.text=Lizenztext +license.popup.licensor=Lizenzgeber +license.popup.type=Lizenz license.type.css.class=CSS Klasse license.type.down=Runter license.type.text=Lizenztext diff --git a/src/main/java/org/olat/core/commons/services/license/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/core/commons/services/license/ui/_i18n/LocalStrings_en.properties index c214a2d3989..487530198ab 100644 --- a/src/main/java/org/olat/core/commons/services/license/ui/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/core/commons/services/license/ui/_i18n/LocalStrings_en.properties @@ -13,9 +13,9 @@ admin.title=Licenses edit.license.type=Edit license error.is.default.license.type=You can not deactivate this license, because it is the initial license. Please previously change the initial license. error.license.type.name.exists=This name already exists. The name has to be unique. -license.quickview.text=License text -license.quickview.licensor=Licensor -license.quickview.type=License +license.popup.text=License text +license.popup.licensor=Licensor +license.popup.type=License license.type.css.class=CSS class license.type.down=Down license.type.text=License text diff --git a/src/main/java/org/olat/repository/ui/author/AuthorListController.java b/src/main/java/org/olat/repository/ui/author/AuthorListController.java index 23d9cb55676..059fdc19547 100644 --- a/src/main/java/org/olat/repository/ui/author/AuthorListController.java +++ b/src/main/java/org/olat/repository/ui/author/AuthorListController.java @@ -32,9 +32,7 @@ import org.olat.basesecurity.events.MultiIdentityChosenEvent; import org.olat.basesecurity.events.SingleIdentityChosenEvent; import org.olat.core.commons.persistence.DB; import org.olat.core.commons.persistence.SortKey; -import org.olat.core.commons.services.license.License; import org.olat.core.commons.services.license.LicenseModule; -import org.olat.core.commons.services.license.ui.LicenseQuickviewController; import org.olat.core.commons.services.license.ui.LicenseRenderer; import org.olat.core.commons.services.mark.Mark; import org.olat.core.commons.services.mark.MarkManager; @@ -137,8 +135,6 @@ public class AuthorListController extends FormBasicController implements Activat private AuthoringEntryDataSource dataSource; private final SearchAuthorRepositoryEntryViewParams searchParams; - private CloseableCalloutWindowController licenseCalloutCtrl; - private LicenseQuickviewController licenseCtrl; private ToolsController toolsCtrl; protected CloseableModalController cmc; private SendMailController sendMailCtrl; @@ -299,7 +295,7 @@ public class AuthorListController extends FormBasicController implements Activat true, OrderBy.authors.name())); if (licenseModule.isEnabled(licenseHandler)) { columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Cols.license.i18nKey(), Cols.license.ordinal(), "license", - new StaticFlexiCellRenderer("license", new LicenseRenderer(getLocale(), "lic-")))); + new StaticFlexiCellRenderer("license", new LicenseRenderer(getLocale())))); } columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(false, Cols.location.i18nKey(), Cols.location.ordinal(), true, OrderBy.location.name())); @@ -529,11 +525,6 @@ public class AuthorListController extends FormBasicController implements Activat toolsCalloutCtrl.deactivate(); cleanUp(); } - } else if(licenseCtrl == source) { - if(event == Event.DONE_EVENT) { - licenseCalloutCtrl.deactivate(); - cleanUp(); - } } else if(referencesCtrl == source) { if(event == Event.DONE_EVENT) { toolsCalloutCtrl.deactivate(); @@ -569,24 +560,20 @@ public class AuthorListController extends FormBasicController implements Activat } protected void cleanUp() { - removeAsListenerAndDispose(licenseCalloutCtrl); removeAsListenerAndDispose(confirmDeleteCtrl); removeAsListenerAndDispose(toolsCalloutCtrl); removeAsListenerAndDispose(userSearchCtr); removeAsListenerAndDispose(sendMailCtrl); - removeAsListenerAndDispose(licenseCtrl); removeAsListenerAndDispose(createCtrl); removeAsListenerAndDispose(importCtrl); removeAsListenerAndDispose(wizardCtrl); removeAsListenerAndDispose(toolsCtrl); removeAsListenerAndDispose(closeCtrl); removeAsListenerAndDispose(cmc); - licenseCalloutCtrl = null; confirmDeleteCtrl = null; toolsCalloutCtrl = null; userSearchCtr = null; sendMailCtrl = null; - licenseCtrl = null; createCtrl = null; importCtrl = null; wizardCtrl = null; @@ -660,8 +647,6 @@ public class AuthorListController extends FormBasicController implements Activat launchEditor(ureq, row); } else if("select".equals(cmd)) { launch(ureq, row); - } else if("license".equals(cmd)) { - showLicenseDetails(ureq, row, se.getIndex()); } } else if(event instanceof FlexiTableSearchEvent) { AuthorListState stateEntry = new AuthorListState(); @@ -1097,22 +1082,6 @@ public class AuthorListController extends FormBasicController implements Activat NewControllerFactory.getInstance().launch(businessPath, ureq, getWindowControl()); } - private void showLicenseDetails(UserRequest ureq, AuthoringEntryRow row, int index) { - removeAsListenerAndDispose(licenseCtrl); - removeAsListenerAndDispose(licenseCalloutCtrl); - - License license = row.getLicense(); - if (license != null) { - licenseCtrl = new LicenseQuickviewController(ureq, getWindowControl(), license); - listenTo(licenseCtrl); - - licenseCalloutCtrl = new CloseableCalloutWindowController(ureq, getWindowControl(), - licenseCtrl.getInitialComponent(), "lic-" + index, "", true, ""); - listenTo(licenseCalloutCtrl); - licenseCalloutCtrl.activate(); - } - } - private void launchDetails(UserRequest ureq, RepositoryEntryRef ref) { String businessPath = "[RepositoryEntry:" + ref.getKey() + "][Infos:0]"; if(!NewControllerFactory.getInstance().launch(businessPath, ureq, getWindowControl())) { diff --git a/src/main/java/org/olat/repository/ui/author/AuthoringEntryDataSource.java b/src/main/java/org/olat/repository/ui/author/AuthoringEntryDataSource.java index 504d94f7f9f..c5489f44474 100644 --- a/src/main/java/org/olat/repository/ui/author/AuthoringEntryDataSource.java +++ b/src/main/java/org/olat/repository/ui/author/AuthoringEntryDataSource.java @@ -32,7 +32,7 @@ import org.olat.core.CoreSpringFactory; import org.olat.core.commons.persistence.DefaultResultInfos; import org.olat.core.commons.persistence.ResultInfos; import org.olat.core.commons.persistence.SortKey; -import org.olat.core.commons.services.license.License; +import org.olat.core.commons.services.license.ResourceLicense; import org.olat.core.commons.services.license.LicenseService; import org.olat.core.gui.components.form.flexible.elements.FlexiTableFilter; import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableDataSourceDelegate; @@ -154,7 +154,7 @@ public class AuthoringEntryDataSource implements FlexiTableDataSourceDelegate<Au List<OLATResourceAccess> resourcesWithOffer = acService.filterResourceWithAC(resourcesWithAC); Collection<OLATResourceable> resources = repoEntries.stream().map(RepositoryEntryAuthorView::getOlatResource).collect(Collectors.toList()); - List<License> licenses = licenseService.loadLicenses(resources); + List<ResourceLicense> licenses = licenseService.loadLicenses(resources); List<AuthoringEntryRow> items = new ArrayList<>(); for(RepositoryEntryAuthorView entry:repoEntries) { @@ -192,7 +192,7 @@ public class AuthoringEntryDataSource implements FlexiTableDataSourceDelegate<Au } // license - for (License license: licenses) { + for (ResourceLicense license: licenses) { OLATResource resource = entry.getOlatResource(); if (license.getResId().equals(resource.getResourceableId()) && license.getResName().equals(resource.getResourceableTypeName())) { row.setLicense(license); diff --git a/src/main/java/org/olat/repository/ui/author/RepositoryEditDescriptionController.java b/src/main/java/org/olat/repository/ui/author/RepositoryEditDescriptionController.java index 9f5997a7b40..74ebb58b30a 100644 --- a/src/main/java/org/olat/repository/ui/author/RepositoryEditDescriptionController.java +++ b/src/main/java/org/olat/repository/ui/author/RepositoryEditDescriptionController.java @@ -36,7 +36,7 @@ import java.util.Set; import java.util.UUID; import org.olat.NewControllerFactory; -import org.olat.core.commons.services.license.License; +import org.olat.core.commons.services.license.ResourceLicense; import org.olat.core.commons.services.license.LicenseModule; import org.olat.core.commons.services.license.LicenseService; import org.olat.core.commons.services.license.LicenseType; @@ -104,7 +104,7 @@ public class RepositoryEditDescriptionController extends FormBasicController { private VFSContainer mediaContainer; private RepositoryEntry repositoryEntry; private final String repoEntryType; - private License license; + private ResourceLicense license; private static final int picUploadlimitKB = 5120; private static final int movieUploadlimitKB = 102400; @@ -216,7 +216,7 @@ public class RepositoryEditDescriptionController extends FormBasicController { license = licenseService.loadOrCreateLicense(res); LicenseSelectionConfig licenseSelectionConfig = LicenseUIFactory - .createLicenseSelectionConfig(licenseHandler, license); + .createLicenseSelectionConfig(licenseHandler, license.getLicenseType()); licenseEl = uifactory.addDropdownSingleselect("cif.license", formLayout, licenseSelectionConfig.getLicenseTypeKeys(), licenseSelectionConfig.getLicenseTypeValues(getLocale())); diff --git a/src/main/resources/META-INF/persistence.xml b/src/main/resources/META-INF/persistence.xml index 400d05d469b..a7aeb12f3c5 100644 --- a/src/main/resources/META-INF/persistence.xml +++ b/src/main/resources/META-INF/persistence.xml @@ -80,7 +80,7 @@ <class>org.olat.commons.info.model.InfoMessageImpl</class> <class>org.olat.core.commons.services.license.model.LicenseTypeActivation</class> <class>org.olat.core.commons.services.license.model.LicenseTypeImpl</class> - <class>org.olat.core.commons.services.license.model.LicenseImpl</class> + <class>org.olat.core.commons.services.license.model.ResourceLicenseImpl</class> <class>org.olat.core.commons.services.lock.pessimistic.PLockImpl</class> <class>org.olat.core.commons.services.notifications.model.SubscriberImpl</class> <class>org.olat.core.commons.services.notifications.model.PublisherImpl</class> diff --git a/src/test/java/org/olat/core/commons/modules/bc/meta/MetaInfoFactoryTest.java b/src/test/java/org/olat/core/commons/modules/bc/meta/MetaInfoFactoryTest.java new file mode 100644 index 00000000000..8e1e2249530 --- /dev/null +++ b/src/test/java/org/olat/core/commons/modules/bc/meta/MetaInfoFactoryTest.java @@ -0,0 +1,104 @@ +/** + * <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.meta; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; + +import org.junit.Before; +import org.junit.Test; +import org.olat.core.commons.persistence.DB; +import org.olat.core.commons.services.license.License; +import org.olat.core.commons.services.license.LicenseService; +import org.olat.core.commons.services.license.LicenseType; +import org.olat.core.commons.services.license.manager.LicenseCleaner; +import org.olat.test.OlatTestCase; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * + * Initial date: 05.03.2018<br> + * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com + * + */ +public class MetaInfoFactoryTest extends OlatTestCase { + + @Autowired + private DB dbInstance; + @Autowired + private MetaInfoFactory metaInfoFactory; + @Autowired + private LicenseService licenseService; + @Autowired + private LicenseCleaner licenseCleaner; + + @Before + public void cleanUp() { + licenseCleaner.deleteAll(); + } + + @Test + public void shouldLoadExistingLicenseType() { + String typeName = "name"; + LicenseType licenseType = licenseService.createLicenseType(typeName); + licenseType = licenseService.saveLicenseType(licenseType); + dbInstance.commitAndCloseSession(); + String licensor = "licensor"; + String name = licenseType.getName(); + File file = new File(""); + MetaInfo meta = new MetaInfoFileImpl(file); + meta.setLicenseTypeName(name); + meta.setLicensor(licensor); + + License license = metaInfoFactory.getLicense(meta); + + assertThat(license.getLicensor()).isEqualTo(licensor); + LicenseType loadedLicenseType = license.getLicenseType(); + assertThat(loadedLicenseType).isEqualTo(licenseType); + } + + @Test + public void shouldCreateNonExistingLicenseType() { + String typeName = "name"; + LicenseType licenseType = licenseService.createLicenseType(typeName); + licenseType = licenseService.saveLicenseType(licenseType); + dbInstance.commitAndCloseSession(); + String licensor = "licensor"; + String name = "new"; + String text = "text"; + File file = new File(""); + MetaInfo meta = new MetaInfoFileImpl(file); + meta.setLicenseTypeName(name); + meta.setLicensor(licensor); + meta.setLicenseText(text); + + License license = metaInfoFactory.getLicense(meta); + + assertThat(license.getLicensor()).isEqualTo(licensor); + LicenseType loadedLicenseType = license.getLicenseType(); + assertThat(loadedLicenseType.getName()).isEqualTo(name); + assertThat(loadedLicenseType.getText()).isEqualTo(text); + + LicenseType createdLicenseType = licenseService.loadLicenseTypeByName(name); + assertThat(createdLicenseType).isNotNull(); + } + +} diff --git a/src/test/java/org/olat/core/commons/services/license/manager/LicenseCleaner.java b/src/test/java/org/olat/core/commons/services/license/manager/LicenseCleaner.java new file mode 100644 index 00000000000..4926b94b299 --- /dev/null +++ b/src/test/java/org/olat/core/commons/services/license/manager/LicenseCleaner.java @@ -0,0 +1,51 @@ +/** + * <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.license.manager; + +import org.olat.core.commons.persistence.DB; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * + * Initial date: 05.03.2018<br> + * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com + * + */ +@Component +public class LicenseCleaner { + + @Autowired + private DB dbInstance; + + public void deleteAll() { + dbInstance.getCurrentEntityManager() + .createQuery("delete from license") + .executeUpdate(); + dbInstance.getCurrentEntityManager() + .createQuery("delete from licensetypeactivation") + .executeUpdate(); + dbInstance.getCurrentEntityManager() + .createQuery("delete from licensetype") + .executeUpdate(); + dbInstance.commitAndCloseSession(); + } + +} diff --git a/src/test/java/org/olat/core/commons/services/license/manager/LicenseTypeActivationDAOTest.java b/src/test/java/org/olat/core/commons/services/license/manager/LicenseTypeActivationDAOTest.java index c8c9cd5373a..e39e19d1100 100644 --- a/src/test/java/org/olat/core/commons/services/license/manager/LicenseTypeActivationDAOTest.java +++ b/src/test/java/org/olat/core/commons/services/license/manager/LicenseTypeActivationDAOTest.java @@ -45,19 +45,12 @@ public class LicenseTypeActivationDAOTest extends OlatTestCase { private LicenseTypeDAO licenseTypeDao; @Autowired private LicenseTypeActivationDAO licenseTypeActivationDao; + @Autowired + private LicenseCleaner licenseCleaner; @Before public void cleanUp() { - dbInstance.getCurrentEntityManager() - .createQuery("delete from license") - .executeUpdate(); - dbInstance.getCurrentEntityManager() - .createQuery("delete from licensetypeactivation") - .executeUpdate(); - dbInstance.getCurrentEntityManager() - .createQuery("delete from licensetype") - .executeUpdate(); - dbInstance.commitAndCloseSession(); + licenseCleaner.deleteAll(); } @Test diff --git a/src/test/java/org/olat/core/commons/services/license/manager/LicenseTypeDAOTest.java b/src/test/java/org/olat/core/commons/services/license/manager/LicenseTypeDAOTest.java index 9ab0bcf54ba..a296b79b925 100644 --- a/src/test/java/org/olat/core/commons/services/license/manager/LicenseTypeDAOTest.java +++ b/src/test/java/org/olat/core/commons/services/license/manager/LicenseTypeDAOTest.java @@ -49,19 +49,12 @@ public class LicenseTypeDAOTest extends OlatTestCase { private LicenseTypeDAO licenseTypeDao; @Autowired private LicenseTypeActivationDAO licenseTypeActivationDao; + @Autowired + private LicenseCleaner licenseCleaner; @Before public void cleanUp() { - dbInstance.getCurrentEntityManager() - .createQuery("delete from license") - .executeUpdate(); - dbInstance.getCurrentEntityManager() - .createQuery("delete from licensetypeactivation") - .executeUpdate(); - dbInstance.getCurrentEntityManager() - .createQuery("delete from licensetype") - .executeUpdate(); - dbInstance.commitAndCloseSession(); + licenseCleaner.deleteAll(); } @Test @@ -147,6 +140,33 @@ public class LicenseTypeDAOTest extends OlatTestCase { assertThat(noLicenseType.getName()).isEqualTo(LicenseTypeDAO.NO_LICENSE_NAME); } + @Test + public void shouldLoadLicenseTypeByKey() { + LicenseType licenseType = licenseTypeDao.create(UUID.randomUUID().toString()); + licenseType = licenseTypeDao.save(licenseType); + LicenseType otherLicenseType = licenseTypeDao.create(UUID.randomUUID().toString()); + licenseTypeDao.save(otherLicenseType); + dbInstance.commitAndCloseSession(); + + LicenseType loadedLicenseType = licenseTypeDao.loadLicenseTypeByKey(licenseType.getKey()); + + assertThat(loadedLicenseType).isEqualTo(licenseType); + } + + @Test + public void shouldLoadLicenseTypeByName() { + LicenseType licenseType = licenseTypeDao.create(UUID.randomUUID().toString()); + licenseType = licenseTypeDao.save(licenseType); + LicenseType otherLicenseType = licenseTypeDao.create(UUID.randomUUID().toString()); + licenseTypeDao.save(otherLicenseType); + dbInstance.commitAndCloseSession(); + + LicenseType loadedLicenseType = licenseTypeDao.loadLicenseTypeByName(licenseType.getName()); + + assertThat(loadedLicenseType).isEqualTo(licenseType); + } + + @Test public void shouldLoadAllLicensesTypes() { LicenseType licenseType1 = licenseTypeDao.create(UUID.randomUUID().toString()); diff --git a/src/test/java/org/olat/core/commons/services/license/manager/LicenseDAOTest.java b/src/test/java/org/olat/core/commons/services/license/manager/ResourceLicenseDAOTest.java similarity index 82% rename from src/test/java/org/olat/core/commons/services/license/manager/LicenseDAOTest.java rename to src/test/java/org/olat/core/commons/services/license/manager/ResourceLicenseDAOTest.java index 8a8964c4a5c..5a19851f07c 100644 --- a/src/test/java/org/olat/core/commons/services/license/manager/LicenseDAOTest.java +++ b/src/test/java/org/olat/core/commons/services/license/manager/ResourceLicenseDAOTest.java @@ -30,6 +30,7 @@ import org.junit.Test; import org.olat.core.commons.persistence.DB; import org.olat.core.commons.services.license.License; import org.olat.core.commons.services.license.LicenseType; +import org.olat.core.commons.services.license.ResourceLicense; import org.olat.core.id.OLATResourceable; import org.olat.core.util.resource.OresHelper; import org.olat.test.JunitTestHelper; @@ -43,27 +44,20 @@ import org.springframework.beans.factory.annotation.Autowired; * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com * */ -public class LicenseDAOTest extends OlatTestCase { +public class ResourceLicenseDAOTest extends OlatTestCase { @Autowired private DB dbInstance; @Autowired - private LicenseDAO licenseDao; + private ResourceLicenseDAO licenseDao; @Autowired private LicenseTypeDAO licenseTypeDao; + @Autowired + private LicenseCleaner licenseCleaner; @Before public void cleanUp() { - dbInstance.getCurrentEntityManager() - .createQuery("delete from license") - .executeUpdate(); - dbInstance.getCurrentEntityManager() - .createQuery("delete from licensetypeactivation") - .executeUpdate(); - dbInstance.getCurrentEntityManager() - .createQuery("delete from licensetype") - .executeUpdate(); - dbInstance.commitAndCloseSession(); + licenseCleaner.deleteAll(); } @Test @@ -73,7 +67,7 @@ public class LicenseDAOTest extends OlatTestCase { licenseType = licenseTypeDao.save(licenseType); String licensor = "licensor"; - License license = licenseDao.createAndPersist(ores, licenseType, licensor); + ResourceLicense license = licenseDao.createAndPersist(ores, licenseType, licensor); dbInstance.commitAndCloseSession(); assertThat(license.getResName()).isEqualTo(ores.getResourceableTypeName()); @@ -89,7 +83,7 @@ public class LicenseDAOTest extends OlatTestCase { OLATResourceable ores = JunitTestHelper.createRandomResource(); LicenseType licenseType = licenseTypeDao.create("name"); licenseType = licenseTypeDao.save(licenseType); - License license = licenseDao.createAndPersist(ores, licenseType); + ResourceLicense license = licenseDao.createAndPersist(ores, licenseType); dbInstance.commitAndCloseSession(); String freetext = "freetext"; license.setFreetext(freetext); @@ -111,7 +105,7 @@ public class LicenseDAOTest extends OlatTestCase { License license = licenseDao.createAndPersist(ores, licenseType); dbInstance.commitAndCloseSession(); - License loadedLicense = licenseDao.loadByResource(ores); + ResourceLicense loadedLicense = licenseDao.loadByResource(ores); assertThat(loadedLicense).isEqualTo(license); } @@ -122,18 +116,18 @@ public class LicenseDAOTest extends OlatTestCase { LicenseType licenseType = licenseTypeDao.create("name"); licenseType = licenseTypeDao.save(licenseType); OLATResourceable ores1 = OresHelper.createOLATResourceableInstance(resName, (new Random()).nextLong()); - License license1 = licenseDao.createAndPersist(ores1, licenseType); + ResourceLicense license1 = licenseDao.createAndPersist(ores1, licenseType); OLATResourceable ores2 = OresHelper.createOLATResourceableInstance(resName, (new Random()).nextLong()); - License license2 = licenseDao.createAndPersist(ores2, licenseType); + ResourceLicense license2 = licenseDao.createAndPersist(ores2, licenseType); OLATResourceable ores3 = OresHelper.createOLATResourceableInstance(resName, (new Random()).nextLong()); - License license3 = licenseDao.createAndPersist(ores3, licenseType); + ResourceLicense license3 = licenseDao.createAndPersist(ores3, licenseType); OLATResourceable oresSameName = OresHelper.createOLATResourceableInstance(resName, (new Random()).nextLong()); licenseDao.createAndPersist(oresSameName, licenseType); OLATResourceable oresSameId = OresHelper.createOLATResourceableInstance("other", ores1.getResourceableId()); licenseDao.createAndPersist(oresSameId, licenseType); dbInstance.commitAndCloseSession(); - List<License> loadedLicenses = licenseDao.loadLicenses(Arrays.asList(ores1, ores2, ores3)); + List<ResourceLicense> loadedLicenses = licenseDao.loadLicenses(Arrays.asList(ores1, ores2, ores3)); assertThat(loadedLicenses).containsExactly(license1, license2, license3); } diff --git a/src/test/java/org/olat/core/commons/services/license/ui/LicenseSelectionConfigTest.java b/src/test/java/org/olat/core/commons/services/license/ui/LicenseSelectionConfigTest.java index 563ac78e6f6..e69666843d3 100644 --- a/src/test/java/org/olat/core/commons/services/license/ui/LicenseSelectionConfigTest.java +++ b/src/test/java/org/olat/core/commons/services/license/ui/LicenseSelectionConfigTest.java @@ -35,7 +35,7 @@ import org.olat.core.commons.services.license.LicenseHandler; import org.olat.core.commons.services.license.LicenseService; import org.olat.core.commons.services.license.LicenseType; import org.olat.core.commons.services.license.manager.TestableLicenseHandler; -import org.olat.core.commons.services.license.model.LicenseImpl; +import org.olat.core.commons.services.license.model.ResourceLicenseImpl; import org.olat.core.commons.services.license.model.LicenseTypeImpl; /** @@ -56,7 +56,7 @@ public class LicenseSelectionConfigTest { @Mock private LicenseService licenseServiceMock; - private License license = new LicenseImpl();; + private License license = new ResourceLicenseImpl();; private LicenseSelectionConfig sut; @@ -72,7 +72,7 @@ public class LicenseSelectionConfigTest { when(licenseServiceMock.isNoLicense(any())).thenReturn(Boolean.FALSE); license.setLicenseType(getActiveLicenseTypes().get(0)); - sut = new LicenseSelectionConfig(licenseServiceMock, LICENSE_HANDLER, license); + sut = new LicenseSelectionConfig(licenseServiceMock, LICENSE_HANDLER, license.getLicenseType()); boolean licenseMandatory = sut.isLicenseMandatory(); @@ -84,7 +84,7 @@ public class LicenseSelectionConfigTest { when(licenseServiceMock.isNoLicense(any())).thenReturn(Boolean.TRUE); license.setLicenseType(getActiveLicenseTypes().get(0)); - sut = new LicenseSelectionConfig(licenseServiceMock, LICENSE_HANDLER, license); + sut = new LicenseSelectionConfig(licenseServiceMock, LICENSE_HANDLER, license.getLicenseType()); boolean licenseMandatory = sut.isLicenseMandatory(); @@ -94,7 +94,7 @@ public class LicenseSelectionConfigTest { @Test public void shouldReturnActiveLicenseTypes() { license.setLicenseType(getActiveLicenseTypes().get(0)); - sut = new LicenseSelectionConfig(licenseServiceMock, LICENSE_HANDLER, license); + sut = new LicenseSelectionConfig(licenseServiceMock, LICENSE_HANDLER, license.getLicenseType()); String[] licenseTypeKeys = sut.getLicenseTypeKeys(); @@ -106,7 +106,7 @@ public class LicenseSelectionConfigTest { when(licenseServiceMock.isNoLicense(any())).thenReturn(Boolean.FALSE); license.setLicenseType(getInactiveLicenseType()); - sut = new LicenseSelectionConfig(licenseServiceMock, LICENSE_HANDLER, license); + sut = new LicenseSelectionConfig(licenseServiceMock, LICENSE_HANDLER, license.getLicenseType()); String[] licenseTypeKeys = sut.getLicenseTypeKeys(); @@ -118,7 +118,7 @@ public class LicenseSelectionConfigTest { when(licenseServiceMock.isNoLicense(any())).thenReturn(Boolean.TRUE); license.setLicenseType(getInactiveLicenseType()); - sut = new LicenseSelectionConfig(licenseServiceMock, LICENSE_HANDLER, license); + sut = new LicenseSelectionConfig(licenseServiceMock, LICENSE_HANDLER, license.getLicenseType()); String[] licenseTypeKeys = sut.getLicenseTypeKeys(); @@ -130,7 +130,7 @@ public class LicenseSelectionConfigTest { when(licenseServiceMock.isNoLicense(getInactiveLicenseType())).thenReturn(Boolean.FALSE); license.setLicenseType(getInactiveLicenseType()); - sut = new LicenseSelectionConfig(licenseServiceMock, LICENSE_HANDLER, license); + sut = new LicenseSelectionConfig(licenseServiceMock, LICENSE_HANDLER, license.getLicenseType()); String key = sut.getSelectionLicenseTypeKey(); @@ -142,7 +142,7 @@ public class LicenseSelectionConfigTest { when(licenseServiceMock.isNoLicense(getActiveLicenseTypes().get(0))).thenReturn(Boolean.TRUE); license.setLicenseType(getActiveLicenseTypes().get(0)); - sut = new LicenseSelectionConfig(licenseServiceMock, LICENSE_HANDLER, license); + sut = new LicenseSelectionConfig(licenseServiceMock, LICENSE_HANDLER, license.getLicenseType()); String key = sut.getSelectionLicenseTypeKey(); @@ -154,7 +154,7 @@ public class LicenseSelectionConfigTest { when(licenseServiceMock.isNoLicense(getInactiveLicenseType())).thenReturn(Boolean.TRUE); license.setLicenseType(getInactiveLicenseType()); - sut = new LicenseSelectionConfig(licenseServiceMock, LICENSE_HANDLER, license); + sut = new LicenseSelectionConfig(licenseServiceMock, LICENSE_HANDLER, license.getLicenseType()); String key = sut.getSelectionLicenseTypeKey(); diff --git a/src/test/java/org/olat/test/AllTestsJunit4.java b/src/test/java/org/olat/test/AllTestsJunit4.java index 2a6b13d9725..0095f54148d 100644 --- a/src/test/java/org/olat/test/AllTestsJunit4.java +++ b/src/test/java/org/olat/test/AllTestsJunit4.java @@ -92,11 +92,12 @@ import org.junit.runners.Suite; org.olat.commons.coordinate.cluster.jms.JMSTest.class, org.olat.commons.coordinate.cluster.lock.LockTest.class, org.olat.commons.coordinate.CoordinatorTest.class, + org.olat.core.commons.modules.bc.meta.MetaInfoFactoryTest.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, org.olat.core.commons.services.license.manager.LicenseTypeDAOTest.class, - org.olat.core.commons.services.license.manager.LicenseDAOTest.class, + org.olat.core.commons.services.license.manager.ResourceLicenseDAOTest.class, org.olat.core.commons.services.webdav.WebDAVCommandsTest.class, org.olat.core.commons.services.webdav.manager.DigestAuthenticationTest.class, org.olat.core.commons.services.webdav.manager.WebDAVManagerTest.class, -- GitLab