Package org.olat.repository.controllers

Source Code of org.olat.repository.controllers.RepositoryDetailsController

/**
* OLAT - Online Learning and Training<br>
* http://www.olat.org
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); <br>
* you may not use this file except in compliance with the License.<br>
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing,<br>
* software distributed under the License is distributed on an "AS IS" BASIS, <br>
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
* See the License for the specific language governing permissions and <br>
* limitations under the License.
* <p>
* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br>
* University of Zurich, Switzerland.
* <p>
*/

package org.olat.repository.controllers;

import java.util.Locale;

import org.olat.ControllerFactory;
import org.olat.admin.securitygroup.gui.GroupController;
import org.olat.admin.securitygroup.gui.IdentitiesAddEvent;
import org.olat.admin.securitygroup.gui.IdentitiesRemoveEvent;
import org.olat.basesecurity.Constants;
import org.olat.basesecurity.ManagerFactory;
import org.olat.basesecurity.SecurityGroup;
import org.olat.bookmark.AddAndEditBookmarkController;
import org.olat.bookmark.BookmarkManager;
import org.olat.catalog.ui.CatalogAjaxAddController;
import org.olat.catalog.ui.CatalogEntryAddController;
import org.olat.catalog.ui.RepoEntryCategoriesTableController;
import org.olat.core.commons.persistence.DBFactory;
import org.olat.core.dispatcher.DispatcherAction;
import org.olat.core.gui.UserRequest;
import org.olat.core.gui.Windows;
import org.olat.core.gui.components.Component;
import org.olat.core.gui.components.image.ImageComponent;
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.ControllerEventListener;
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.dtabs.DTab;
import org.olat.core.gui.control.generic.dtabs.DTabs;
import org.olat.core.gui.control.generic.modal.DialogBoxController;
import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory;
import org.olat.core.gui.control.generic.tool.ToolController;
import org.olat.core.gui.control.generic.tool.ToolFactory;
import org.olat.core.gui.media.MediaResource;
import org.olat.core.gui.translator.PackageTranslator;
import org.olat.core.helpers.Settings;
import org.olat.core.id.OLATResourceable;
import org.olat.core.id.context.BusinessControlFactory;
import org.olat.core.id.context.ContextEntry;
import org.olat.core.logging.AssertException;
import org.olat.core.logging.OLATRuntimeException;
import org.olat.core.logging.OLATSecurityException;
import org.olat.core.logging.OLog;
import org.olat.core.logging.Tracing;
import org.olat.core.util.Formatter;
import org.olat.core.util.coordinate.CoordinatorManager;
import org.olat.core.util.coordinate.LockResult;
import org.olat.core.util.event.GenericEventListener;
import org.olat.core.util.i18n.I18nManager;
import org.olat.core.util.resource.OresHelper;
import org.olat.course.CourseFactory;
import org.olat.course.CourseModule;
import org.olat.course.ICourse;
import org.olat.course.nodes.CourseNode;
import org.olat.course.run.RunMainController;
import org.olat.course.run.navigation.NavigationHandler;
import org.olat.course.run.userview.NodeEvaluation;
import org.olat.course.run.userview.TreeEvaluation;
import org.olat.course.run.userview.UserCourseEnvironmentImpl;
import org.olat.repository.DisplayCourseInfoForm;
import org.olat.repository.DisplayInfoForm;
import org.olat.repository.RepositoryEntry;
import org.olat.repository.RepositoryEntryIconRenderer;
import org.olat.repository.RepositoryEntryStatus;
import org.olat.repository.RepositoryManager;
import org.olat.repository.handlers.CourseHandler;
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: <br>
*
* @author Felix Jost
*/
public class RepositoryDetailsController extends BasicController implements ControllerEventListener,GenericEventListener {
  OLog log = Tracing.createLoggerFor(this.getClass());

  private static final String ACTION_CLOSE = "cmd.close";
  private static final String ACTION_DOWNLOAD = "dl";
  private static final String ACTION_LAUNCH = "lch";
  private static final String ACTION_COPY = "cp";
  private static final String ACTION_BOOKMARK = "bm";
  private static final String ACTION_EDIT = "edt";
  private static final String ACTION_DETAILSEDIT = "dtedt";
  private static final String ACTION_ADD_CATALOG = "add.cat";
  private static final String ACTION_DELETE = "del";
  private static final String ACTION_CLOSE_RESSOURCE = "close.ressource";
  private static final String ACTION_GROUPS = "grp";
  private static final String ACTION_EDITDESC = "chdesc";
  private static final String ACTION_EDITPROP = "chprop";

  private static final String TOOL_BOOKMARK = "b";
  private static final String TOOL_COPY = "c";
  private static final String TOOL_DOWNLOAD = "d";
  private static final String TOOL_EDIT = "e";
  private static final String TOOL_CATALOG = "cat";
  private static final String TOOL_CHDESC = "chd";
  private static final String TOOL_CHPROP = "chp";
  private static final String TOOL_LAUNCH = "l";
  private static final String TOOL_CLOSE_RESSOURCE = "cr";
 
  private VelocityContainer main;
  private Link downloadButton;
  private Link backLink;
  private Link launchButton;
  private Link loginLink;
 
  private GroupController groupController, groupEditController;
  private SecurityGroup ownerGroup;
  private AddAndEditBookmarkController bookmarkController;
  private ToolController detailsToolC = null;
  private RepositoryCopyController copyController;
  private RepositoryEditPropertiesController repositoryEditPropertiesController;
  private RepositoryEditDescriptionController repositoryEditDescriptionController;
  private RepoEntryCategoriesTableController repoEntryCategoriesTableController;
  private CloseableModalController closeableModalController;
  private DialogBoxController deleteDialogController;
  private Controller catalogAdddController;

  private RepositoryEntry repositoryEntry;
  private boolean isOwner;
  private boolean isAuthor;
  private boolean isOlatAdmin;
  private boolean isGuestOnly = false;
  private boolean jumpfromcourse = false;
  public static final String ACTIVATE_EDITOR = "activateEditor";
  public static final String ACTIVATE_RUN = "activateRun";
  private LockResult lockResult;
  private WizardCloseResourceController wc;
  private CloseableModalController cmc;
 
  //different instances for "copy" and "settings change", since it is important to know what triggered the CLOSE_MODAL_EVENT
  private CloseableModalController copyCloseableModalController;
  private CloseableModalController settingsCloseableModalController;

  /**
   * Controller displaying details of a given repository entry.
   *
   * @param ureq
   * @param wControl
   * @param mainPanel
   */
  public RepositoryDetailsController(UserRequest ureq, WindowControl wControl) {
    super(ureq, wControl);
    //sets velocity root and translator to RepositoryManager package
    setBasePackage(RepositoryManager.class);
    if (log.isDebug()){
      log.debug("Constructing ReposityMainController using velocity root " + velocity_root);
    }
    // main component layed out in panel
    main = createVelocityContainer("details");
   
    downloadButton = LinkFactory.createButton("details.download", main, this);
    LinkFactory.markDownloadLink(downloadButton);
    launchButton = LinkFactory.createButton("details.launch", main, this);
   
    backLink = LinkFactory.createLinkBack(main, this);
    loginLink = LinkFactory.createLink("repo.login", main, this);
   
    putInitialPanel(main);
  }

  /**
   * @param ureq
   */
  private void checkSecurity(UserRequest ureq) {
    if (ureq.getUserSession().getRoles().isOLATAdmin()) {
      isOwner = true;
      isAuthor = true;
      isOlatAdmin = true;
    } else {
      // load repositoryEntry again because the hibenate object is 'detached'.Otherwise you become an exception when you check owner-group.
      boolean isInstitutionalResourceManager = RepositoryManager.getInstance().isInstitutionalRessourceManagerFor(repositoryEntry, ureq.getIdentity());
      repositoryEntry = (RepositoryEntry) DBFactory.getInstance().loadObject(repositoryEntry);
      isOwner = ManagerFactory.getManager().isIdentityPermittedOnResourceable(ureq.getIdentity(), Constants.PERMISSION_ACCESS,
          repositoryEntry.getOwnerGroup())
          | isInstitutionalResourceManager;
      isAuthor = ureq.getUserSession().getRoles().isAuthor() | isInstitutionalResourceManager;
      isGuestOnly = ureq.getUserSession().getRoles().isGuestOnly();
      isOlatAdmin = false;
    }
  }

  /**
   * @param ureq
   */
  private void updateRepositoryEntryView(UserRequest ureq) {

    main.contextPut("isOwner", new Boolean(isOwner));
    main.contextPut("isAuthor", new Boolean(isAuthor));
    main.contextPut("isOlatAdmin", new Boolean(isOlatAdmin));
    main.contextPut("launchableTyp", new Boolean(checkIsRepositoryEntryTypeLaunchable()));
    String url = Settings.getServerContextPathURI() + "/url/RepositoryEntry/" + repositoryEntry.getKey();
    main.contextPut("extlink", url);
   
    String displayName = getDisplayName(ureq.getLocale());
    main.contextPut("title", displayName);

    boolean isLaunchable = checkIsRepositoryEntryLaunchable(ureq);
    launchButton.setEnabled(isLaunchable);
    launchButton.setTextReasonForDisabling(translate("launch.noaccess"));
    downloadButton.setEnabled(repositoryEntry.getCanDownload());
    downloadButton.setTextReasonForDisabling(translate("disabledexportreason"));
   
    if (repositoryEntry.getDescription() != null) {
      main.contextPut("description", Formatter.formatLatexFormulas(repositoryEntry.getDescription()));
    }
    ImageComponent ic = RepositoryEntryImageController.getImageComponentForRepositoryEntry("image", repositoryEntry);

    if (ic != null) {
      // display only within 600x300 - everything else looks ugly
      ic.setMaxWithAndHeightToFitWithin(600, 300);
      main.contextPut("hasImage", Boolean.TRUE);
      main.put("image", ic);
    } else {
      main.contextPut("hasImage", Boolean.FALSE);
    }

    main.contextPut("id", repositoryEntry.getResourceableId());
    main.contextPut("ores_id", repositoryEntry.getOlatResource().getResourceableId());
    main.contextPut("initialauthor", repositoryEntry.getInitialAuthor());
    main.contextPut("userlang", I18nManager.getInstance().getLocaleKey(ureq.getLocale()));
    main.contextPut("isGuestAllowed", (repositoryEntry.getAccess() >= RepositoryEntry.ACC_USERS_GUESTS ? Boolean.TRUE  : Boolean.FALSE));
    main.contextPut("isGuest", Boolean.valueOf(ureq.getUserSession().getRoles().isGuestOnly()));

    String typeName = repositoryEntry.getOlatResource().getResourceableTypeName();
    StringBuilder typeDisplayText = new StringBuilder(100);
    if (typeName != null) { // add image and typename code
      RepositoryEntryIconRenderer reir = new RepositoryEntryIconRenderer(ureq.getLocale());
      typeDisplayText.append("<span class=\"b_with_small_icon_left ");
      typeDisplayText.append(reir.getIconCssClass(repositoryEntry));
      typeDisplayText.append("\">");
      String tName = ControllerFactory.translateResourceableTypeName(typeName, getLocale());
      typeDisplayText.append(tName);
      if (repositoryEntry != null && RepositoryManager.getInstance().createRepositoryEntryStatus(repositoryEntry.getStatusCode()).isClosed()) {
        PackageTranslator pT = new PackageTranslator(RepositoryEntryStatus.class.getPackage().getName(), ureq.getLocale());
        typeDisplayText.append(" " + "(" + pT.translate("title.prefix.closed") + ")");
      }
      typeDisplayText.append("</span>");
    } else {
      typeDisplayText.append(translate("cif.type.na"));
    }
    main.contextPut("type", typeDisplayText.toString());
    VelocityContainer infopanelVC = createVelocityContainer("infopanel");
    // show how many users are currently using this resource
    String numUsers;
    OLATResourceable ores = repositoryEntry.getOlatResource();
    int cnt = 0;
    OLATResourceable courseRunOres = OresHelper.createOLATResourceableInstance(RunMainController.ORES_TYPE_COURSE_RUN, repositoryEntry.getOlatResource().getResourceableId());
    if (ores != null) cnt = CoordinatorManager.getCoordinator().getEventBus().getListeningIdentityCntFor(courseRunOres);
    numUsers = String.valueOf(cnt);
    infopanelVC.contextPut("numUsers", numUsers);
    // push addtl infos
    main.put("displayform", new DisplayInfoForm("displayform", getTranslator(), repositoryEntry));
    infopanelVC.contextPut("isAuthor", Boolean.valueOf(isAuthor));
    infopanelVC.contextPut("isOwner", Boolean.valueOf(isOwner));
    // init handler details
    RepositoryHandler handler = RepositoryHandlerFactory.getInstance().getRepositoryHandler(repositoryEntry);
    infopanelVC.contextPut("iscourse", new Boolean(handler instanceof CourseHandler));
    main.contextPut("iscourse", new Boolean(handler instanceof CourseHandler));
    //brasato:: review why such a type check was necessary
    if (handler instanceof CourseHandler) {
      infopanelVC
      .put("CourseInfoForm", new DisplayCourseInfoForm("CourseInfoForm", getTranslator(), CourseFactory.loadCourse(repositoryEntry.getOlatResource())));
    }
    Component comp = handler.getDetailsComponent(repositoryEntry.getOlatResource(), ureq);
    if (comp != null) { // push handler specific details view
      infopanelVC.contextPut("hasHandlerDetails", Boolean.valueOf("true"));
      infopanelVC.put("handlerDetails", comp);
    } else {
      infopanelVC.contextRemove("hasHandlerDetails");
    }
    // init reference usage
    // Where is it in use
    String referenceDetails = ReferenceManager.getInstance().getReferencesToSummary(repositoryEntry.getOlatResource(), ureq.getLocale());
    if (referenceDetails != null) {
      infopanelVC.contextPut("referenceDetails", referenceDetails);
    } else {
      infopanelVC.contextRemove("referenceDetails");
    }

    // Number of launches
    String numLaunches;
    if (repositoryEntry.getCanLaunch()) {
      numLaunches = String.valueOf(repositoryEntry.getLaunchCounter());
    } else {
      numLaunches = translate("cif.canLaunch.na");
    }
    infopanelVC.contextPut("numLaunches", numLaunches);

    // Number of downloads
    String numDownloads;
    if (repositoryEntry.getCanDownload()) {
      numDownloads = String.valueOf(repositoryEntry.getDownloadCounter());
    } else {
      numDownloads = translate("cif.canDownload.na");
    }

    infopanelVC.contextPut("numDownloads", numDownloads);

    if (repositoryEntry.getLastUsage() != null) {
      infopanelVC.contextPut("lastUsage", repositoryEntry.getLastUsage());
    } else {
      infopanelVC.contextPut("lastUsage", translate("cif.lastUsage.na"));
    }

    main.put(infopanelVC.getComponentName(), infopanelVC);

    if (groupController != null) groupController.dispose();
    groupController = new GroupController(ureq, getWindowControl(), false, true, false, repositoryEntry.getOwnerGroup());
    main.put("ownertable", groupController.getInitialComponent());

  }

  /**
   * @param ureq
   * @param newToolController
   */
  private void updateView(UserRequest ureq) {
    checkSecurity(ureq);
    updateRepositoryEntryView(ureq);
    updateDetailsToolC(ureq);
    updateCategoriesTableC(ureq);
  }

 
  private void updateCategoriesTableC(UserRequest ureq) {   
    // load category links
    removeAsListenerAndDispose(repoEntryCategoriesTableController);
    repoEntryCategoriesTableController = new RepoEntryCategoriesTableController(ureq, getWindowControl(), this.repositoryEntry, (isOlatAdmin || isOwner));
    listenTo(repoEntryCategoriesTableController);
    main.put("repoEntryCategoriesTable", repoEntryCategoriesTableController.getInitialComponent());
  }
  /**
   * @param newToolController
   */
  private void updateDetailsToolC(UserRequest ureq) {
    boolean isNewController = false;
    if (detailsToolC == null) {
      detailsToolC = ToolFactory.createToolController(getWindowControl());
      detailsToolC.addControllerListener(this);
      isNewController = true;
    }
    // init handler details
    RepositoryHandler handler = RepositoryHandlerFactory.getInstance().getRepositoryHandler(repositoryEntry);
    if (isNewController) {
      detailsToolC.addHeader(translate("tools.details.header"));
      detailsToolC.addLink(ACTION_LAUNCH, translate("details.launch"), TOOL_LAUNCH, null);
    }
    detailsToolC.setEnabled(TOOL_LAUNCH, checkIsRepositoryEntryLaunchable(ureq));
    if (!isGuestOnly) {
      if (isNewController) {
        //mark as download link
        detailsToolC.addLink(ACTION_DOWNLOAD, translate("details.download"), TOOL_DOWNLOAD, null, true);
        detailsToolC.addLink(ACTION_BOOKMARK, translate("details.bookmark"), TOOL_BOOKMARK, null);
      }
      boolean canDownload = repositoryEntry.getCanDownload() && handler.supportsDownload();
      // disable download for courses if not author or owner
      if (repositoryEntry.getOlatResource().getResourceableTypeName().equals(CourseModule.getCourseTypeName())
        && !(isOwner || isAuthor)) canDownload = false;
      // always enable download for owners
      if (isOwner && handler.supportsDownload()) canDownload = true;
      detailsToolC.setEnabled(TOOL_DOWNLOAD, canDownload);
      boolean canBookmark = true;
      if (BookmarkManager.getInstance().isResourceableBookmarked(ureq.getIdentity(), repositoryEntry) || !repositoryEntry.getCanLaunch())
        canBookmark = false;
      detailsToolC.setEnabled(TOOL_BOOKMARK, canBookmark);
    }
    if (isAuthor || isOwner) {
      boolean canCopy = repositoryEntry.getCanCopy();
      if (isOwner) {
        if (isNewController) {
          detailsToolC.addLink(ACTION_EDIT, translate("details.openeditor"), TOOL_EDIT, null);
          detailsToolC.addLink(ACTION_EDITDESC, translate("details.chdesc"), TOOL_CHDESC, null);
          detailsToolC.addLink(ACTION_EDITPROP, translate("details.chprop"), TOOL_CHPROP, null);
          detailsToolC.addLink(ACTION_ADD_CATALOG, translate("details.catadd"), TOOL_CATALOG, null);
          if ((OresHelper.isOfType(repositoryEntry.getOlatResource(), CourseModule.class)) && (!RepositoryManager.getInstance().createRepositoryEntryStatus(repositoryEntry.getStatusCode()).isClosed())) {
            detailsToolC.addLink(ACTION_CLOSE_RESSOURCE, translate("details.close.ressoure"), TOOL_CLOSE_RESSOURCE, null);
          }
        }
        // update catalog link
        detailsToolC.setEnabled(TOOL_CATALOG, (repositoryEntry.getAccess() >= RepositoryEntry.ACC_USERS));
      }
      if (isNewController)
        detailsToolC.addLink(ACTION_COPY, translate("details.copy"), TOOL_COPY, null);
      if (isOwner) {
        if (isNewController) {
          detailsToolC.addLink(ACTION_DELETE, translate("details.delete"));
          detailsToolC.addLink(ACTION_GROUPS, translate("details.groups"));
        }
        // enable
        detailsToolC.setEnabled(TOOL_EDIT, handler.supportsEdit());
        detailsToolC.setEnabled(TOOL_CHDESC, true);
        detailsToolC.setEnabled(TOOL_CHPROP, true);
        canCopy = true;
      }
      detailsToolC.setEnabled(TOOL_COPY, canCopy);
    }
    if (isNewController)
      detailsToolC.addLink(ACTION_CLOSE, translate("details.close"), null, "b_toolbox_close");
  }

  /**
   * Sets a repository entry for this details controller. Returns a
   * corresponding tools controller
   *
   * @param entry
   * @param ureq
   * @return A tool controller representing available tools for the given entry.
   */
  public ToolController setEntry(RepositoryEntry entry, UserRequest ureq, boolean jumpfromcourse) {
    this.jumpfromcourse = jumpfromcourse;
    if (repositoryEntry != null) {
      // The controller has already a repository-entry => do de-register it
      CoordinatorManager.getCoordinator().getEventBus().deregisterFor(this, repositoryEntry);
    }
    repositoryEntry = entry;
    CoordinatorManager.getCoordinator().getEventBus().registerFor(this, ureq.getIdentity(), repositoryEntry);
    checkSecurity(ureq);
    detailsToolC = null; // force recreation of tool controller
    updateView(ureq);
    return detailsToolC;
  }

  /**
   * @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) {
    String cmd = event.getCommand();

    if (source == main) {
      if (cmd.equals(ACTION_DETAILSEDIT)) {
        // detailsForm.setDisplayOnly(false);
        main.contextPut("enableEdit", Boolean.valueOf(false)); // disable edit
        // button
        return;
      } else if (cmd.equals(ACTION_CLOSE)) { // close details
        doCloseDetailView(ureq);
        return;
      } else if (cmd.equals(ACTION_LAUNCH)) { // launch resource

      }
    } else if (source == backLink){
      doCloseDetailView(ureq);
      return;
    } else if (source == downloadButton){
      doDownload(ureq);
    } else if (source == launchButton){
      doLaunch(ureq);
    } else if (source == loginLink){
      DispatcherAction.redirectToDefaultDispatcher(ureq.getHttpResp());
    }
  }

  private void doCloseDetailView(UserRequest ureq) {
    // REVIEW:pb:note:handles jumps from Catalog and Course
    if (jumpfromcourse && repositoryEntry.getCanLaunch()) {
      doLaunch(ureq);
    } else {
      fireEvent(ureq, Event.DONE_EVENT);
    }
  }

  void deleteRepositoryEntry(UserRequest ureq, WindowControl wControl, RepositoryEntry entry) {
    if (RepositoryManager.getInstance().deleteRepositoryEntryWithAllData( ureq, wControl, repositoryEntry ) ) {
      fireEvent(ureq, new EntryChangedEvent(entry, EntryChangedEvent.DELETED));
      showInfo("info.entry.deleted");
    } else {
      showInfo("info.could.not.delete.entry");
    }
  }
 
  /**
   * Get displayname of a repository entry. If repository entry a course
   * and is this course closed then add a prefix to the title.
   */
  private String getDisplayName(Locale locale) {
    // load repositoryEntry again because the hibernate object is 'detached'.
    // Otherwise you become an exception when you check owner-group.
    repositoryEntry = (RepositoryEntry) DBFactory.getInstance().loadObject(repositoryEntry);
    String displayName = repositoryEntry.getDisplayname();
    if (repositoryEntry != null && RepositoryManager.getInstance().createRepositoryEntryStatus(repositoryEntry.getStatusCode()).isClosed()) {
      PackageTranslator pT = new PackageTranslator(RepositoryEntryStatus.class.getPackage().getName(), locale);
      displayName = "[" + pT.translate("title.prefix.closed") + "] ".concat(displayName);
    }
   
    return displayName;
  }

  /**
   * Also used by RepositoryMainController
   *
   * @param ureq
   */
  void doLaunch(UserRequest ureq) {
    RepositoryHandler typeToLaunch = RepositoryHandlerFactory.getInstance().getRepositoryHandler(repositoryEntry);
    if (typeToLaunch == null){
      StringBuilder sb = new StringBuilder(translate("error.launch"));
      sb.append(": No launcher for repository entry: ");
      sb.append(repositoryEntry.getKey());
      throw new OLATRuntimeException(RepositoryDetailsController.class,sb.toString(), null);
    }
    if (RepositoryManager.getInstance().lookupRepositoryEntry(repositoryEntry.getKey()) == null) {
      showInfo("info.entry.deleted");
      return;
    }
   
    RepositoryManager.getInstance().incrementLaunchCounter(repositoryEntry);
    OLATResourceable ores = repositoryEntry.getOlatResource();
    String displayName = getDisplayName(ureq.getLocale());

    //was brasato:: DTabs dts = getWindowControl().getDTabs();
    DTabs dts = (DTabs)Windows.getWindows(ureq).getWindow(ureq).getAttribute("DTabs");
    DTab dt = dts.getDTab(ores);
    if (dt == null) {
      // does not yet exist -> create and add
      dt = dts.createDTab(ores, displayName);
      if (dt == null) return;
     
      // build up the context path
      OLATResourceable businessOres = repositoryEntry;
      ContextEntry ce = BusinessControlFactory.getInstance().createContextEntry(businessOres);
      WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ce, dt.getWindowControl());
     
      Controller ctrl = typeToLaunch.getLaunchController(ores, null, ureq, bwControl);
      // if resource is an image, PDF or eq. (e.g. served by resulting media request), no controller is returned.
      // FIXME:fj:test this
      if (ctrl == null) return;
      dt.setController(ctrl);
      dts.addDTab(dt);
    }
    dts.activate(ureq, dt, RepositoryDetailsController.ACTIVATE_RUN)
    /**
     * close detail page after resource is closed
     * DONE_EVENT will be catched by RepositoryMainController
     */
    fireEvent(ureq, Event.DONE_EVENT);
  }

  private boolean checkIsRepositoryEntryLaunchable(UserRequest ureq) {
    RepositoryHandler type = RepositoryHandlerFactory.getInstance().getRepositoryHandler(repositoryEntry);
    RepositoryManager rm = RepositoryManager.getInstance();
   
    if (rm.isAllowedToLaunch(ureq, repositoryEntry) || (type.supportsLaunch() && ureq.getUserSession().getRoles().isOLATAdmin())) {
      return true;
    } else if(!rm.isAllowedToLaunch(ureq, repositoryEntry)){
      return false;
    }   
    if (type instanceof CourseHandler) {
      // course
      ICourse course = CourseFactory.loadCourse(repositoryEntry.getOlatResource());
      CourseNode rootNode = course.getRunStructure().getRootNode();
      UserCourseEnvironmentImpl uce = new UserCourseEnvironmentImpl(ureq.getUserSession().getIdentityEnvironment(), course
          .getCourseEnvironment());
      NodeEvaluation nodeEval = rootNode.eval(uce.getConditionInterpreter(), new TreeEvaluation());
      boolean mayAccessWholeTreeUp = NavigationHandler.mayAccessWholeTreeUp(nodeEval);
      if (!mayAccessWholeTreeUp || !nodeEval.isVisible()) {
        String explan = rootNode.getNoAccessExplanation();
        String sExplan = (explan == null ? translate("launch.noaccess") : Formatter.formatLatexFormulas(explan));
        main.contextPut("disabledlaunchreason", sExplan);
        return false;
      }
    }
    return repositoryEntry.getCanLaunch();
  }

  private boolean checkIsRepositoryEntryTypeLaunchable() {
    RepositoryHandler handler = RepositoryHandlerFactory.getInstance().getRepositoryHandler(repositoryEntry);
    return handler.supportsLaunch();
  }

  /**
   * Activates the closeableModalController with the input controller's component, if not null
   * @param ureq
   * @param contentController
   */
  private void doEditSettings(UserRequest ureq, Controller contentController) {
    if (!isAuthor) throw new OLATSecurityException("Trying to edit properties , but user is not author: user = " + ureq.getIdentity());
    contentController.addControllerListener(this);
   
    Component component = contentController.getInitialComponent();
    if(component!=null) {
      removeAsListenerAndDispose(settingsCloseableModalController);
      settingsCloseableModalController = new CloseableModalController(getWindowControl(), translate("close"),
        contentController.getInitialComponent());
      listenTo(settingsCloseableModalController);
     
      settingsCloseableModalController.activate();
    }
    return;
  }
 
  private void doAddBookmark(Controller contentController) {
    removeAsListenerAndDispose(closeableModalController);   
    closeableModalController = new CloseableModalController(getWindowControl(), translate("close"),
        contentController.getInitialComponent());
    listenTo(closeableModalController);
    listenTo(contentController);
    closeableModalController.activate();
    return;
  }

  /**
   * Also used by RepositoryMainController
   *
   * @param ureq
   */
  void doDownload(UserRequest ureq) {
    RepositoryHandler typeToDownload = RepositoryHandlerFactory.getInstance().getRepositoryHandler(repositoryEntry);

    if (typeToDownload == null){
      StringBuilder sb = new StringBuilder(translate("error.download"));
      sb.append(": No download handler for repository entry: ");
      sb.append(repositoryEntry.getKey());
      throw new OLATRuntimeException(RepositoryDetailsController.class, sb.toString(), null);
    }
    OLATResource ores = OLATResourceManager.getInstance().findResourceable(repositoryEntry.getOlatResource());
    if (ores == null) {
      showError("error.download");
      return;
    }   
    boolean isAlreadyLocked = typeToDownload.isLocked(ores);
    try {     
      lockResult = typeToDownload.acquireLock(ores, ureq.getIdentity());
      if(lockResult==null || (lockResult!=null && lockResult.isSuccess() && !isAlreadyLocked)) {
        MediaResource mr = typeToDownload.getAsMediaResource(ores);
        if(mr!=null) {
          RepositoryManager.getInstance().incrementDownloadCounter(repositoryEntry);
          ureq.getDispatchResult().setResultingMediaResource(mr);
        } else {
          showError("error.export");
          fireEvent(ureq, Event.FAILED_EVENT);     
        }
      } else if(lockResult!=null && lockResult.isSuccess() && isAlreadyLocked) {
        showInfo("warning.course.alreadylocked.bySameUser", lockResult.getOwner().getName());
        lockResult = null; //invalid lock, it was already locked
      } else {
        showInfo("warning.course.alreadylocked", lockResult.getOwner().getName());
      }
    }
    finally
      if((lockResult!=null && lockResult.isSuccess() && !isAlreadyLocked)) {
        typeToDownload.releaseLock(lockResult);   
        lockResult = null;
      }
    }
  }
 
  /**
   * If lock successfully aquired start copy, else show warning.
   * @param ureq
   */
  private void doCopy(UserRequest ureq) {
    OLATResource ores = OLATResourceManager.getInstance().findResourceable(repositoryEntry.getOlatResource());
    boolean isAlreadyLocked = RepositoryHandlerFactory.getInstance().getRepositoryHandler(repositoryEntry).isLocked(ores);
    lockResult = RepositoryHandlerFactory.getInstance().getRepositoryHandler(repositoryEntry).acquireLock(ores, ureq.getIdentity());
    if(lockResult==null || (lockResult!=null && lockResult.isSuccess()) && !isAlreadyLocked) {
      removeAsListenerAndDispose(copyController);
      copyController = new RepositoryCopyController(ureq, getWindowControl(), repositoryEntry);
      listenTo(copyController);
     
      removeAsListenerAndDispose(copyCloseableModalController);
      copyCloseableModalController = new CloseableModalController(getWindowControl(), translate("close"), copyController.getInitialComponent());
      listenTo(copyCloseableModalController);
     
      copyCloseableModalController.activate();         
    } else if (lockResult!=null && lockResult.isSuccess() && isAlreadyLocked) {
      showWarning("warning.course.alreadylocked.bySameUser");
      lockResult = null;
    else {       
      showWarning("warning.course.alreadylocked", lockResult.getOwner().getName());
    }
  }
 

  /**
   * Also used by RepositoryMainController
   *
   * @param ureq
   */
  void doEdit(UserRequest ureq) {
    if (!isOwner) throw new OLATSecurityException("Trying to launch editor, but not allowed: user = " + ureq.getIdentity());
    RepositoryHandler typeToEdit = RepositoryHandlerFactory.getInstance().getRepositoryHandler(repositoryEntry);
    if (!typeToEdit.supportsEdit()){
      throw new AssertException("Trying to edit repository entry which has no assoiciated editor: "+ typeToEdit);
    }
       

    OLATResourceable ores = repositoryEntry.getOlatResource();
   
    //was brasato:: DTabs dts = getWindowControl().getDTabs();
    DTabs dts = (DTabs)Windows.getWindows(ureq).getWindow(ureq).getAttribute("DTabs");
    DTab dt = dts.getDTab(ores);
    if (dt == null) {
      // does not yet exist -> create and add
      dt = dts.createDTab(ores, repositoryEntry.getDisplayname());
      if (dt == null){
        //null means DTabs are full -> warning is shown
        return;
      }
      //user activity logger is set by course factory
      Controller editorController = typeToEdit.getEditorController(ores, ureq, dt.getWindowControl());
      if(editorController == null){
        //editor could not be created -> warning is shown
        return;
      }
      dt.setController(editorController);
      dts.addDTab(dt);
    }
    dts.activate(ureq, dt, RepositoryDetailsController.ACTIVATE_EDITOR);
  }


  /**
   * Internal helper to initiate the add to catalog workflow
   * @param ureq
   */
  private void doAddCatalog(UserRequest ureq) {
    removeAsListenerAndDispose(catalogAdddController);
    boolean ajax = getWindowControl().getWindowBackOffice().getWindowManager().isAjaxEnabled();
    if (ajax) {
      // fancy ajax tree
      catalogAdddController = new CatalogAjaxAddController(ureq, getWindowControl(), repositoryEntry);
    } else {
      // old-school selection tree
      catalogAdddController = new CatalogEntryAddController(ureq, getWindowControl(), repositoryEntry);
    }

   
   
    listenTo(catalogAdddController);
    removeAsListenerAndDispose(closeableModalController);
    closeableModalController = new CloseableModalController(getWindowControl(), "close", catalogAdddController.getInitialComponent());
    listenTo(closeableModalController);
    closeableModalController.activate();
  }

  /**
   * @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 (repositoryEntry != null) {
      repositoryEntry = RepositoryManager.getInstance().lookupRepositoryEntry(repositoryEntry.getKey());
    }
    String cmd = event.getCommand();
    if (source == groupEditController) {
      if(event instanceof IdentitiesAddEvent ) { //FIXME:chg: Move into seperate RepositoryOwnerGroupController like BusinessGroupEditController ?
        IdentitiesAddEvent identitiesAddedEvent = (IdentitiesAddEvent) event;
        RepositoryManager rm = RepositoryManager.getInstance();
        //add to group and also adds identities really added to the event.
        //this is then later used by the GroupController to determine if the
        //model should be updated or not.
        rm.addOwners(ureq.getIdentity(),identitiesAddedEvent,repositoryEntry);
      } else if (event instanceof IdentitiesRemoveEvent) {
        IdentitiesRemoveEvent identitiesRemoveEvent = (IdentitiesRemoveEvent) event;
        RepositoryManager rm = RepositoryManager.getInstance();
        rm.removeOwners(ureq.getIdentity(),identitiesRemoveEvent.getRemovedIdentities(), repositoryEntry);
      }
      updateView(ureq);
    } else if (source == detailsToolC) {
      if (cmd.equals(ACTION_DOWNLOAD)) { // download
        doDownload(ureq);
        return;
      } else if (cmd.equals(ACTION_LAUNCH)) { // launch resource
        doLaunch(ureq);
        return;
      } else if (cmd.equals(ACTION_EDIT)) { // start editor
        doEdit(ureq);
        return;
      } else if (cmd.equals(ACTION_EDITDESC)) { // change description
        repositoryEditDescriptionController = new RepositoryEditDescriptionController(ureq, getWindowControl(), repositoryEntry, false);
        doEditSettings(ureq, repositoryEditDescriptionController);
        return;
      } else if (cmd.equals(ACTION_ADD_CATALOG)) { // start add to catalog workflow
        doAddCatalog(ureq);
        return;
      } else if (cmd.equals(ACTION_EDITPROP)) { // change properties
        repositoryEditPropertiesController = new RepositoryEditPropertiesController(ureq, getWindowControl(), repositoryEntry, false);
        doEditSettings(ureq, repositoryEditPropertiesController);
        return;
      } else if (cmd.equals(ACTION_CLOSE)) {
        doCloseDetailView(ureq);
        return;
      } else if (cmd.equals(ACTION_BOOKMARK)) {
        bookmarkController = new AddAndEditBookmarkController(ureq, getWindowControl(), repositoryEntry.getDisplayname(), "",
            repositoryEntry, repositoryEntry.getOlatResource().getResourceableTypeName());
        doAddBookmark(bookmarkController);
        return;
      } else if (cmd.equals(ACTION_COPY)) { // copy
        if (!isAuthor) throw new OLATSecurityException("Trying to copy, but user is not author: user = " + ureq.getIdentity());
        doCopy(ureq);
        return;
      } else if (cmd.equals(ACTION_GROUPS)) { // edit authors group
        if (!isOwner) throw new OLATSecurityException("Trying to access groupmanagement, but not allowed: user = " + ureq.getIdentity());
        ownerGroup = repositoryEntry.getOwnerGroup();
        if (groupEditController != null) groupEditController.dispose();
        groupEditController = new GroupController(ureq, getWindowControl(), true, true, false, ownerGroup);
        groupEditController.addControllerListener(this);
        VelocityContainer groupContainer = createVelocityContainer("groups")
        groupContainer.put("groupcomp", groupEditController.getInitialComponent());
        CloseableModalController cmc = new CloseableModalController(getWindowControl(), translate("close"), groupContainer);
        cmc.activate();
        return;
      } else if (cmd.equals(ACTION_CLOSE_RESSOURCE)) {
        doCloseResource(ureq);
        return;
      } else if (cmd.equals(ACTION_DELETE)) { // delete
        if (!isOwner) throw new OLATSecurityException("Trying to delete, but not allowed: user = " + ureq.getIdentity());
        // show how many users are currently using this resource
        OLATResourceable ores = repositoryEntry.getOlatResource();
       
        String dialogTitle = translate("del.header", repositoryEntry.getDisplayname());
        OLATResourceable courseRunOres = OresHelper.createOLATResourceableInstance(RunMainController.ORES_TYPE_COURSE_RUN, repositoryEntry.getOlatResource().getResourceableId());
        int cnt = CoordinatorManager.getCoordinator().getEventBus().getListeningIdentityCntFor(courseRunOres);
       
        String dialogText = translate("del.confirm", String.valueOf(cnt));
        deleteDialogController = activateYesNoDialog(ureq, dialogTitle, dialogText, deleteDialogController);
        return;
      }
    } else if (source == wc) {
      if (event == Event.CANCELLED_EVENT) {
        cmc.deactivate();
        wc.dispose();
      } else if (event == Event.DONE_EVENT) {
        cmc.deactivate();
        wc.dispose();
        detailsToolC = null; // force recreation of tool controller
        updateView(ureq);
        fireEvent(ureq, Event.CHANGED_EVENT);
      }
    } else if (source == bookmarkController) {
      closeableModalController.deactivate();
      if (event.equals(Event.DONE_EVENT)) { // bookmark added... remove tool
        if (detailsToolC != null) {
          detailsToolC.setEnabled(TOOL_BOOKMARK, false);
        }
      }
    } else if (source == copyController) {       
      RepositoryHandlerFactory.getInstance().getRepositoryHandler(repositoryEntry).releaseLock(lockResult);   
      lockResult = null;
      copyCloseableModalController.deactivate();
      if (event == Event.DONE_EVENT) {
        fireEvent(ureq, Event.DONE_EVENT); // go back to overview on success
        fireEvent(ureq, new EntryChangedEvent(copyController.getNewEntry(), EntryChangedEvent.ADDED)); // go
        // back to overview on success
      } else if (event == Event.FAILED_EVENT) { // copy failed, go back to
        // overview
        fireEvent(ureq, Event.DONE_EVENT); // go back to overview on failure
      } else if (event instanceof EntryChangedEvent) {
        fireEvent(ureq, event);
      }
      removeAsListenerAndDispose(copyController);
      copyController = null;
    } else if (source == repositoryEditDescriptionController) {
      if (event == Event.CHANGED_EVENT) {
        // RepositoryEntry changed
        // setEntry(repositoryEditDescriptionController.getRepositoryEntry(), ureq);
        this.repositoryEntry = repositoryEditDescriptionController.getRepositoryEntry();
        // do not close upon save/upload image closeableModalController.deactivate();
        updateView(ureq);
      } else if (event == Event.CANCELLED_EVENT) {
        settingsCloseableModalController.deactivate();
        removeAsListenerAndDispose(repositoryEditDescriptionController);
      }
    } else if (source == repositoryEditPropertiesController) {
      if (event == Event.CHANGED_EVENT || event.getCommand().equals("courseChanged")) {
        // RepositoryEntry changed
        this.repositoryEntry = repositoryEditPropertiesController.getRepositoryEntry();
        updateView(ureq);
        RepositoryHandler handler = RepositoryHandlerFactory.getInstance().getRepositoryHandler(repositoryEntry);
        boolean canDownload = repositoryEntry.getCanDownload() && handler.supportsDownload();
        detailsToolC.setEnabled(TOOL_DOWNLOAD, canDownload);
        if (checkIsRepositoryEntryTypeLaunchable()) {
          detailsToolC.setEnabled(TOOL_LAUNCH, checkIsRepositoryEntryLaunchable(ureq));
        }       
        if(event.getCommand().equals("courseChanged")) {
          removeAsListenerAndDispose(repositoryEditPropertiesController);
        }
      } else if (event == Event.CANCELLED_EVENT) {
        settingsCloseableModalController.deactivate();
        removeAsListenerAndDispose(repositoryEditPropertiesController);
      } else if(event == Event.DONE_EVENT) {
        removeAsListenerAndDispose(repositoryEditPropertiesController);
        repositoryEditPropertiesController = null;
      }
    } else if (source == deleteDialogController){
      if (DialogBoxUIFactory.isYesEvent(event)){
        deleteRepositoryEntry(ureq, getWindowControl(), this.repositoryEntry);
     
    } else if (source == settingsCloseableModalController) {
      if (event == CloseableModalController.CLOSE_MODAL_EVENT) {       
        updateView(ureq);       
        //check if commit or not the course conf changes       
        if(repositoryEditPropertiesController!=null) {
          boolean configsChanged = repositoryEditPropertiesController.checkIfCourseConfigChanged(ureq);
          if(!configsChanged) {
            removeAsListenerAndDispose(repositoryEditPropertiesController);
            repositoryEditPropertiesController = null;
          }
        }
      }
    } else if (source == copyCloseableModalController) {
      if (event == CloseableModalController.CLOSE_MODAL_EVENT) {       
        updateView(ureq);           
        if(copyController!=null) {
          //copyController's modal dialog was closed, that is cancel copy
          RepositoryHandlerFactory.getInstance().getRepositoryHandler(repositoryEntry).releaseLock(lockResult);   
          lockResult = null;
          removeAsListenerAndDispose(copyController);
          copyController = null;
        }
      }
    }  else if (source == catalogAdddController) {
      // finish modal dialog and reload categories list controller
      closeableModalController.deactivate();
      updateCategoriesTableC(ureq);
    }
  }

  /**
   * @param ureq
   */
  private void doCloseResource(UserRequest ureq) {
    removeAsListenerAndDispose(wc);
    RepositoryHandler repoHandler = RepositoryHandlerFactory.getInstance().getRepositoryHandler(repositoryEntry);
    wc = repoHandler.getCloseResourceController(ureq, getWindowControl(), repositoryEntry);
    wc.startWorkflow();
    wc.addControllerListener(this);
    cmc = new CloseableModalController(getWindowControl(), translate("close"), wc.getInitialComponent());
    cmc.activate();
  }

  /**
   * @see org.olat.core.gui.control.DefaultController#doDispose(boolean)
   */
  protected void doDispose() {
    if(lockResult!=null) {
      //the lock it is assumed to be released after export/copy operation, but release it anyway in case it failed to release
      if (repositoryEntry != null) {
        RepositoryHandlerFactory.getInstance().getRepositoryHandler(repositoryEntry).releaseLock(lockResult);
     
      lockResult = null;
    }
    if (repositoryEntry != null) {
      CoordinatorManager.getCoordinator().getEventBus().deregisterFor(this, repositoryEntry);
    }
    if (groupEditController != null) {
      groupEditController.dispose();
      groupEditController = null;
    }
    if (groupController != null) {
      groupController.dispose();
      groupController = null;
    }
    if (bookmarkController != null) {
      bookmarkController.dispose();
      bookmarkController = null;
    }
    if (detailsToolC != null) {
      detailsToolC.dispose();
      detailsToolC = null;
    }
    if (copyController != null) {
      copyController.dispose();
      copyController = null;
    }
    if (repositoryEditDescriptionController != null) {
      repositoryEditDescriptionController.dispose();
      repositoryEditDescriptionController = null;
    }
    if (repositoryEditPropertiesController != null) {
      repositoryEditPropertiesController.dispose();
      repositoryEditPropertiesController = null;
    }
    if(copyCloseableModalController!=null) {
      copyCloseableModalController.dispose();
      copyCloseableModalController = null;
    }
    if(settingsCloseableModalController!=null) {
      settingsCloseableModalController.dispose();
      settingsCloseableModalController = null;
    }   
  }

  public void event(Event event) {
    if (event instanceof EntryChangedEvent) {
      repositoryEntry = RepositoryManager.getInstance().lookupRepositoryEntry(repositoryEntry.getKey());
    }
  }

  /**
   *
   * @return
   */
  public ToolController getDetailsToolController() {
    return this.detailsToolC;
  }

}
TOP

Related Classes of org.olat.repository.controllers.RepositoryDetailsController

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.