/** * <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.repository.ui; import java.util.Collections; import java.util.Date; import java.util.List; import org.olat.core.commons.persistence.DB; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.link.Link; import org.olat.core.gui.components.link.LinkFactory; import org.olat.core.gui.components.velocity.VelocityContainer; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.BasicController; import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController; import org.olat.core.gui.control.generic.modal.DialogBoxController; import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory; import org.olat.core.logging.OLATSecurityException; import org.olat.core.util.Formatter; import org.olat.core.util.Util; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryEntryLifeCycleValue; import org.olat.repository.RepositoryEntryManagedFlag; import org.olat.repository.RepositoryEntryStatus; import org.olat.repository.RepositoryManager; import org.olat.repository.RepositoryModule; import org.olat.repository.RepositoryService; import org.olat.repository.controllers.EntryChangedEvent; import org.olat.repository.controllers.EntryChangedEvent.Change; import org.olat.repository.handlers.RepositoryHandler; import org.olat.repository.model.RepositoryEntrySecurity; import org.olat.repository.ui.author.ConfirmCloseController; import org.olat.repository.ui.author.ConfirmDeleteSoftlyController; import org.springframework.beans.factory.annotation.Autowired; /** * Offers a way to change the repo entry life cycle / status: close and delete a * resource * * Initial date: 19.05.2016<br> * * @author gnaegi, gnaegi@frentix.com, http://www.frentix.com * */ public class RepositoryEntryLifeCycleChangeController extends BasicController{ public static final Event closedEvent = new Event("closed"); public static final Event deletedEvent = new Event("deleted"); public static final Event unclosedEvent = new Event("unclosed"); private Link closeLink, uncloseLink, deleteLink; private VelocityContainer lifeCycleVC; private RepositoryEntry re; private final RepositoryEntrySecurity reSecurity; private CloseableModalController cmc; private DialogBoxController confirmUncloseCtrl; private ConfirmCloseController confirmCloseCtrl; private ConfirmDeleteSoftlyController confirmDeleteCtrl; @Autowired private DB dbInstance; @Autowired private RepositoryModule repositoryModule; @Autowired private RepositoryService repositoryService; @Autowired private RepositoryManager repositoryManager; public RepositoryEntryLifeCycleChangeController(UserRequest ureq, WindowControl wControl, RepositoryEntry re, RepositoryEntrySecurity reSecurity, RepositoryHandler handler) { super(ureq, wControl); setTranslator(Util.createPackageTranslator(RepositoryService.class, getLocale(), getTranslator())); this.re = re; this.reSecurity = reSecurity; lifeCycleVC = createVelocityContainer("lifecycle_change"); putInitialPanel(lifeCycleVC); RepositoryEntryStatus reStatus = repositoryManager.createRepositoryEntryStatus(re.getStatusCode()); boolean isClosed = reStatus.isClosed(); boolean closeManaged = RepositoryEntryManagedFlag.isManaged(re, RepositoryEntryManagedFlag.close); if (!closeManaged) { closeLink = LinkFactory.createButton("close", lifeCycleVC, this); closeLink.setCustomDisplayText(translate("details.close.ressoure")); closeLink.setIconLeftCSS("o_icon o_icon-fw o_icon_close_resource"); closeLink.setElementCssClass("o_sel_repo_close"); closeLink.setVisible(!isClosed); uncloseLink = LinkFactory.createButton("unclose", lifeCycleVC, this); uncloseLink.setCustomDisplayText(translate("details.unclose.resource")); uncloseLink.setElementCssClass("o_sel_repo_unclose"); uncloseLink.setVisible(isClosed); RepositoryEntryLifeCycleValue autoCloseVal = repositoryModule.getLifecycleAutoCloseValue(); if(autoCloseVal != null && re.getLifecycle() != null && re.getLifecycle().getValidTo() != null) { Date autoCloseDate = autoCloseVal.toDate(re.getLifecycle().getValidTo()); lifeCycleVC.contextPut("autoCloseDate", Formatter.getInstance(getLocale()).formatDate(autoCloseDate)); } } boolean deleteManaged = RepositoryEntryManagedFlag.isManaged(re, RepositoryEntryManagedFlag.delete); if (!deleteManaged) { deleteLink = LinkFactory.createButton("delete", lifeCycleVC, this); String type = translate(handler.getSupportedType()); deleteLink.setCustomDisplayText(translate("details.delete.alt", new String[]{ type })); deleteLink.setIconLeftCSS("o_icon o_icon-fw o_icon_delete_item"); deleteLink.setElementCssClass("o_sel_repo_close"); RepositoryEntryLifeCycleValue autoDeleteVal = repositoryModule.getLifecycleAutoDeleteValue(); if(autoDeleteVal != null && re.getLifecycle() != null && re.getLifecycle().getValidTo() != null) { Date autoDeleteDate = autoDeleteVal.toDate(re.getLifecycle().getValidTo()); lifeCycleVC.contextPut("autoDeleteDate", Formatter.getInstance(getLocale()).formatDate(autoDeleteDate)); } } } @Override protected void event(UserRequest ureq, Component source, Event event) { if (source == deleteLink) { doDelete(ureq); } else if (source == closeLink) { doConfirmCloseResource(ureq); } else if (source == uncloseLink) { doConfirmUncloseResource(ureq); } } @Override protected void event(UserRequest ureq, Controller source, Event event) { if(confirmDeleteCtrl == source) { cmc.deactivate(); if(event == Event.CANCELLED_EVENT) { cleanUp(); } else if (event == Event.DONE_EVENT || event == Event.CHANGED_EVENT) { cleanUp(); dbInstance.commit();//commit before sending events fireEvent(ureq, deletedEvent); EntryChangedEvent e = new EntryChangedEvent(re, getIdentity(), Change.deleted, "runtime"); ureq.getUserSession().getSingleUserEventCenter().fireEventToListenersOf(e, RepositoryService.REPOSITORY_EVENT_ORES); } } else if(confirmCloseCtrl == source) { cmc.deactivate(); if(event == Event.CANCELLED_EVENT) { cleanUp(); } else if (event == Event.DONE_EVENT || event == Event.CHANGED_EVENT) { cleanUp(); dbInstance.commit();//commit before sending events doCloseResource(); fireEvent(ureq, closedEvent); EntryChangedEvent e = new EntryChangedEvent(re, getIdentity(), Change.closed, "runtime"); ureq.getUserSession().getSingleUserEventCenter().fireEventToListenersOf(e, RepositoryService.REPOSITORY_EVENT_ORES); } } else if(confirmUncloseCtrl == source) { if(DialogBoxUIFactory.isOkEvent(event) || DialogBoxUIFactory.isYesEvent(event)) { cleanUp(); doUncloseResource(); dbInstance.commit();//commit before sending events fireEvent(ureq, unclosedEvent); EntryChangedEvent e = new EntryChangedEvent(re, getIdentity(), Change.unclosed, "runtime"); ureq.getUserSession().getSingleUserEventCenter().fireEventToListenersOf(e, RepositoryService.REPOSITORY_EVENT_ORES); } } else if(cmc == source) { cleanUp(); } } private void cleanUp() { removeAsListenerAndDispose(confirmDeleteCtrl); removeAsListenerAndDispose(confirmCloseCtrl); removeAsListenerAndDispose(cmc); confirmDeleteCtrl = null; confirmCloseCtrl = null; cmc = null; } private void doConfirmCloseResource(UserRequest ureq) { if (!reSecurity.isEntryAdmin()) { throw new OLATSecurityException("Trying to close, but not allowed: user = " + ureq.getIdentity()); } List<RepositoryEntry> entryToClose = Collections.singletonList(re); confirmCloseCtrl = new ConfirmCloseController(ureq, getWindowControl(), entryToClose); listenTo(confirmCloseCtrl); String title = translate("read.only.header", re.getDisplayname()); cmc = new CloseableModalController(getWindowControl(), "close", confirmCloseCtrl.getInitialComponent(), true, title); listenTo(cmc); cmc.activate(); } /** * Remove close and edit tools, if in edit mode, pop-up-to root * @param ureq */ private void doCloseResource() { re = repositoryService.loadByKey(re.getKey()); closeLink.setVisible(false); uncloseLink.setVisible(true); lifeCycleVC.setDirty(true); } private void doConfirmUncloseResource(UserRequest ureq) { if (!reSecurity.isEntryAdmin()) { throw new OLATSecurityException("Trying to reactivate, but not allowed: user = " + ureq.getIdentity()); } String title = translate("warning.unclose.title"); String text = translate("warning.unclose.text"); confirmUncloseCtrl = activateOkCancelDialog(ureq, title, text, confirmUncloseCtrl); } /** * Remove close and edit tools, if in edit mode, pop-up-to root * @param ureq */ private void doUncloseResource() { re = repositoryService.uncloseRepositoryEntry(re); closeLink.setVisible(true); uncloseLink.setVisible(false); lifeCycleVC.setDirty(true); } private void doDelete(UserRequest ureq) { if (!reSecurity.isEntryAdmin()) { throw new OLATSecurityException("Trying to delete, but not allowed: user = " + ureq.getIdentity()); } List<RepositoryEntry> entryToDelete = Collections.singletonList(re); confirmDeleteCtrl = new ConfirmDeleteSoftlyController(ureq, getWindowControl(), entryToDelete, false); listenTo(confirmDeleteCtrl); String title = translate("del.header", re.getDisplayname()); cmc = new CloseableModalController(getWindowControl(), "close", confirmDeleteCtrl.getInitialComponent(), true, title); listenTo(cmc); cmc.activate(); } @Override protected void doDispose() { // nothing to dispose } }