/** * OLAT - Online Learning and Training
* http://www.olat.org *

* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at *

* http://www.apache.org/licenses/LICENSE-2.0 *

* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License. *

* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),
* University of Zurich, Switzerland. *

*/ package org.olat.repository.controllers; import org.olat.basesecurity.BaseSecurity; import org.olat.basesecurity.BaseSecurityManager; import org.olat.basesecurity.Constants; import org.olat.basesecurity.SecurityGroup; import org.olat.core.commons.persistence.DBFactory; 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.id.Identity; import org.olat.core.id.OLATResourceable; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.util.Util; import org.olat.repository.DetailsReadOnlyForm; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryManager; import org.olat.repository.handlers.RepositoryHandler; import org.olat.repository.handlers.RepositoryHandlerFactory; import org.olat.resource.OLATResource; import org.olat.resource.OLATResourceManager; import org.olat.resource.references.ReferenceManager; /** * Description:
* * * @author Felix Jost */ public class RepositoryCopyController extends BasicController { OLog log = Tracing.createLoggerFor(this.getClass()); private static final String PACKAGE = Util.getPackageName(RepositoryManager.class); private static final String VELOCITY_ROOT = Util.getPackageVelocityRoot(RepositoryManager.class); private VelocityContainer mainContainer; private Link cancelButton; private Link forwardButton; private RepositoryEditDescriptionController descriptionController; private BaseSecurity securityManager; private RepositoryEntry sourceEntry; private RepositoryEntry newEntry; // flag is true when workflow has been finished successfully, // otherwhise when disposing the controller or in a case of // user abort / cancel the system will delete temporary data private boolean workflowSuccessful = false; /** * Create a repository add controller that adds the given resourceable. * @param ureq * @param wControl * @param sourceEntry */ public RepositoryCopyController(UserRequest ureq, WindowControl wControl, RepositoryEntry sourceEntry) { super(ureq, wControl); setBasePackage(RepositoryManager.class); this.sourceEntry = sourceEntry; this.newEntry = null; securityManager = BaseSecurityManager.getInstance(); mainContainer = createVelocityContainer("copy"); cancelButton = LinkFactory.createButton("cmd.cancel", mainContainer, this); forwardButton = LinkFactory.createButton("cmd.forward", mainContainer, this); forwardButton.setEnabled(false); LinkFactory.markDownloadLink(forwardButton); // TODO:cg: for copy of large repositoryEntries => Remove when new long-running task is implemented forwardButton.setTextReasonForDisabling(translate("disabledforwardreason")); newEntry = createNewRepositoryEntry(sourceEntry, ureq); descriptionController = new RepositoryEditDescriptionController(ureq, getWindowControl(), newEntry, true); listenTo(descriptionController); mainContainer.put("details", descriptionController.getInitialComponent()); putInitialPanel(mainContainer); } /** * @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) */ public void event(UserRequest ureq, Controller source, Event event) { if (source == descriptionController) { if (event == Event.CANCELLED_EVENT) { // abort transaction cleanup(); fireEvent(ureq, Event.CANCELLED_EVENT); return; } else if (event == Event.DONE_EVENT) { forwardButton.setEnabled(true); } } } /** * @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) */ public void event(UserRequest ureq, Component source, Event event) { if (source == forwardButton){ // check if repository entry is still available RepositoryManager rm = RepositoryManager.getInstance(); RepositoryEntry checkEntry = rm.lookupRepositoryEntry(sourceEntry.getKey()); if (checkEntry == null) { // entry has been deleted meanwhile showError("error.createcopy"); fireEvent(ureq, Event.FAILED_EVENT); fireEvent(ureq, new EntryChangedEvent(sourceEntry, EntryChangedEvent.DELETED)); return; } RepositoryHandler typeToCopy = RepositoryHandlerFactory.getInstance().getRepositoryHandler(sourceEntry); OLATResourceable newResourceable = typeToCopy.createCopy(sourceEntry.getOlatResource(), ureq); if (newResourceable == null) { showError("error.createcopy"); fireEvent(ureq, Event.FAILED_EVENT); return; } // Set the resource on the repository entry and save the entry. newEntry = descriptionController.getRepositoryEntry(); OLATResource ores = OLATResourceManager.getInstance().findOrPersistResourceable(newResourceable); newEntry.setOlatResource(ores); rm.updateRepositoryEntry(newEntry); IAddController addController = typeToCopy.createAddController(null, null, ureq, getWindowControl()); addController.repositoryEntryCreated(newEntry); // dispose immediately (cleanup temp files), not really used // as a controller, should be in a business logic frontend manager instead! addController.dispose(); showInfo("add.success"); workflowSuccessful = true; fireEvent(ureq, Event.DONE_EVENT); return; } else if (source == cancelButton){ // abort transaction cleanup(); fireEvent(ureq, Event.CANCELLED_EVENT); return; } } private RepositoryEntry createNewRepositoryEntry(RepositoryEntry src, UserRequest ureq) { RepositoryEntry preparedEntry = RepositoryManager.getInstance() .createRepositoryEntryInstance(ureq.getIdentity().getName()); preparedEntry.setCanDownload(src.getCanDownload()); preparedEntry.setCanLaunch(src.getCanLaunch()); // FIXME:pb:ms translation for COPY OF String newDispalyname = "Copy of " + src.getDisplayname(); if (newDispalyname.length() > DetailsReadOnlyForm.MAX_DISPLAYNAME) newDispalyname = newDispalyname.substring(0, DetailsReadOnlyForm.MAX_DISPLAYNAME - 1); preparedEntry.setDisplayname(newDispalyname); preparedEntry.setDescription(src.getDescription()); String resName = src.getResourcename(); if (resName == null) resName = ""; preparedEntry.setResourcename(resName); RepositoryHandler typeToCopy = RepositoryHandlerFactory.getInstance().getRepositoryHandler(src); OLATResourceable newResourceable = typeToCopy.createCopy(sourceEntry.getOlatResource(), ureq); if (newResourceable == null) { getWindowControl().setError(this.getTranslator().translate("error.createcopy")); fireEvent(ureq, Event.FAILED_EVENT); return null; } OLATResource ores = OLATResourceManager.getInstance().findOrPersistResourceable(newResourceable); preparedEntry.setOlatResource(ores); // create security group SecurityGroup newGroup = securityManager.createAndPersistSecurityGroup(); // member of this group may modify member's membership securityManager.createAndPersistPolicy(newGroup, Constants.PERMISSION_ACCESS, newGroup); // members of this group are always authors also securityManager.createAndPersistPolicy(newGroup, Constants.PERMISSION_HASROLE, Constants.ORESOURCE_AUTHOR); securityManager.addIdentityToSecurityGroup(ureq.getIdentity(), newGroup); preparedEntry.setOwnerGroup(newGroup); RepositoryManager.getInstance().saveRepositoryEntry(preparedEntry); // copy image if available RepositoryEntryImageController.copyImage(src, preparedEntry); return preparedEntry; } protected RepositoryEntry getNewEntry() { return newEntry; } private void cleanup() { log.debug("Cleanup : newEntry=" + newEntry); // load newEntry again from DB because it could be changed (Exception object modified) //o_clusterREVIEW RepositoryEntry entry = RepositoryManager.getInstance().lookupRepositoryEntry(newEntry.getKey()); if (entry != null) { SecurityGroup secGroup = newEntry.getOwnerGroup(); if (secGroup != null) { // delete owner group securityManager.deleteSecurityGroup(secGroup); } newEntry = (RepositoryEntry) DBFactory.getInstance().loadObject(newEntry,true); ReferenceManager.getInstance().deleteAllReferencesOf(newEntry.getOlatResource()); RepositoryManager.getInstance().deleteRepositoryEntry(newEntry); OLATResourceManager.getInstance().deleteOLATResource(newEntry.getOlatResource()); } log.debug("Cleanup : DONE."); } /** * * @see org.olat.core.gui.control.DefaultController#doDispose(boolean) */ protected void doDispose() { log.debug("doDispose : newEntry=" + newEntry); if (!workflowSuccessful) { cleanup(); } } }