Package org.olat.catalog.ui

Source Code of org.olat.catalog.ui.CatalogController

/**
* 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.catalog.ui;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

import org.apache.commons.lang.StringEscapeUtils;
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.Manager;
import org.olat.basesecurity.ManagerFactory;
import org.olat.basesecurity.SecurityGroup;
import org.olat.bookmark.AddAndEditBookmarkController;
import org.olat.bookmark.BookmarkManager;
import org.olat.catalog.CatalogEntry;
import org.olat.catalog.CatalogJumpInHandlerFactory;
import org.olat.catalog.CatalogManager;
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.form.Form;
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.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.Activateable;
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.helpers.Settings;
import org.olat.core.id.Identity;
import org.olat.core.id.OLATResourceable;
import org.olat.core.logging.AssertException;
import org.olat.core.util.Util;
import org.olat.core.util.coordinate.CoordinatorManager;
import org.olat.core.util.coordinate.LockResult;
import org.olat.core.util.mail.ContactList;
import org.olat.core.util.mail.ContactMessage;
import org.olat.core.util.resource.OresHelper;
import org.olat.modules.co.ContactFormController;
import org.olat.repository.RepositoryEntry;
import org.olat.repository.RepositoryEntryIconRenderer;
import org.olat.repository.RepositoryManager;
import org.olat.repository.RepositoryTableModel;
import org.olat.repository.controllers.EntryChangedEvent;
import org.olat.repository.controllers.RepositoryEditDescriptionController;
import org.olat.repository.controllers.RepositoryEntryImageController;
import org.olat.repository.controllers.RepositorySearchController;
import org.olat.repository.handlers.RepositoryHandler;
import org.olat.repository.handlers.RepositoryHandlerFactory;
import org.olat.resource.OLATResource;

/**
* <pre>
* Description:
* <P>
* The CatalogController is responsible for:
* <ul>
* <li>displaying the catalog with its categories and linked resources,
* starting from the supplied root node</li>
* <li>handling the access to the actual category:
* <ul>
* <li>OLATAdmin is/should be the owner of catalog root</li>
* <li>LocalTreeAdmin is administrator of a subtree within the catalog</li>
* <li>Author is responsible for adding his resources to the catalog</li>
* <li>ordinary user browses the catalog for quickly finding his desired
* resources</li>
* </ul>
* The CatalogController accomplish this access rights by modifying the
* corresponding toolbox entries in the GUI, which grant access to the mentioned
* actions.</li>
* <li>handles the controllers and forms allowing to edit, create the catalog
* structure
* <ol>
* <li>change category data (name, description)</li>
* <li>modify category's localTreeAdmin group</li>
* <li>contact category's localTreeAdmin group</li>
* <li>add a new subcategory</li>
* <li>add a resource link</li>
* <li>remove a resource link</li>
* <li>paste structure</li>
* </ol>
* The OLATAdmin as superuser can invoke all of the above listed actions. <br>
* Whereas the LocalTreeAdmin is restricted to the follwing set: on the
* LocalTreeAdmin's subtree-root-node only 4,6 are possible. But from the
* children on he/she can invoke any of 1-6 except 5.<br>
* The author is solely able to invoke 5.
* </ul>
* </li>
* </ul>
* The catalog is based upon the idea of having a lot of resources which must
* somehow be ordered to find them quickly. Frankly speaking the catalog only
* makes sense if no access restrictions to the linked resources apply. This in
* mind, it is solely possible to link resources which are accessible for the
* users of the installation.
* </pre>
* Date: 2005/10/14 12:35:40 <br>
* @author Felix Jost
*/
public class CatalogController extends BasicController implements Activateable {
 
  // velocity form flags
 
  private static final String ENABLE_GROUPMNGMNT = "enableGroupMngmnt";
  private static final String ENABLE_EDIT_CATEGORY = "enableEditCategory";
  private static final String ENABLE_REPOSITORYSELECTION = "enableRepositorySelection";
  private static final String ENABLE_ADD_SUBCATEGORY = "enableAddSubcategory";
  private static final String ENABLE_EDIT_LINK = "enableLinkEdit";
  private static final String ENABLE_EDIT_CATALOG_LINK = "enableEditCatalogLink";
  private static final String ENABLE_REQUESTFORM = "enableRequestForm";

  // catalog actions
 
  private static final String ACTION_ADD_CTLGLINK = "addCtlglink";
  private static final String ACTION_ADD_CTLGCATEGORY = "addCtlgCategory";
  private static final String ACTION_EDIT_CTLGCATEGORY = "editCtlgCategory";
  private static final String ACTION_EDIT_CTLGCATOWNER = "editCtlgCategoryOwnerGroup";
  private static final String ACTION_DELETE_CTLGCATEGORY = "actionDeleteCtlgCategory";
  private static final String ACTION_NEW_CTGREQUEST = "actionCategoryRequest";
  private static final String ACTION_ADD_STRUCTURE = "addStructure";
 
  private static final String ACTION_ADD_BOOKMARK = "addBookmark";
  private static final String ACTION_MOVE_ENTRY = "moveEntry";
 
  // commands in table and history
 
  private static final String CATCMD_HISTORY = "history";
  private static final String CATCMD_REMOVE = "remove.";
  private static final String CATCMD_EDIT = "edit.";
  private static final String CATCMD_DETAIL = "detail.";
  private static final String CATCMD_MOVE = "move.";
 
  // URL command 
 
  private static final String CATENTRY_CHILD = "child";
  private static final String CATENTRY_LEAF = "leaf";
  private static final String CATENTRY_NODE = "node";
 
  // NLS support
 
  private static final String NLS_DIALOG_MODAL_LEAF_DELETE_TEXT = "dialog.modal.leaf.delete.text";
  private static final String NLS_CHOOSE = "choose";
  private static final String NLS_DIALOG_MODAL_SUBTREE_DELETE_TEXT = "dialog.modal.subtree.delete.text";
  private static final String NLS_CONTACT_TO_GROUPNAME_CARETAKER = "contact.to.groupname.caretaker";
  private static final String NLS_TOOLS_EDIT_CATALOG_CATEGORY = "tools.edit.catalog.category";
  private static final String NLS_TOOLS_EDIT_CATALOG_CATEGORY_OWNERGROUP = "tools.edit.catalog.category.ownergroup";
  private static final String NLS_TOOLS_NEW_CATALOG_CATEGORYREQUEST = "tools.new.catalog.categoryrequest";
  private static final String NLS_TOOLS_DELETE_CATALOG_ENTRY = "tools.delete.catalog.entry";
  private static final String NLS_TOOLS_ADD_HEADER = "tools.add.header";
  private static final String NLS_TOOLS_ADD_CATALOG_CATEGORY = "tools.add.catalog.category";
  private static final String NLS_TOOLS_ADD_CATALOG_LINK = "tools.add.catalog.link";
  private static final String NLS_TOOLS_PASTESTRUCTURE = "tools.pastestructure";
  private static final String NLS_TOOLS_ADD_BOOKMARK = "tools.add.catalog.bookmark";
  private static final String NLS_TOOLS_MOVE_CATALOG_ENTRY = "tools.move.catalog.entry";
 
  // private stuff

  private VelocityContainer myContent;

  private CatalogManager cm;
  private CatalogEntry currentCatalogEntry;
  private CatalogEntry newLinkNotPersistedYet;
  private int currentCatalogEntryLevel = -1;
  private List<CatalogEntry> historyStack = new ArrayList<CatalogEntry>(5);
  private List childCe;
  private boolean isOLATAdmin;
  private boolean isAuthor;
  private boolean isLocalTreeAdmin = false;
  private int isLocalTreeAdminLevel = -1;
  private boolean canAddLinks;
  private boolean canAdministrateCategory;
  private boolean canAddSubCategories;
  private boolean canRemoveAllLinks;
  private ToolController catalogToolC;
  private RepositorySearchController rsc;
  private EntryForm addEntryForm;
  private EntryForm editEntryForm;
  private GroupController groupController;
  private DialogBoxController dialogDeleteSubtree;
  private CatalogEntry linkMarkedToBeDeleted;
  private CatalogEntry linkMarkedToBeEdited;
  private DialogBoxController dialogDeleteLink;
  private ContactFormController cfc;
  private EntryForm addStructureForm;
  private boolean isGuest;
  private Link loginLink;
  private CloseableModalController cmc;
  private AddAndEditBookmarkController bookmarkController;
  private boolean canBookmark=true;
  private Controller catEntryMoveController;
  private RepositoryEditDescriptionController repositoryEditDescriptionController;

  // locking stuff for cataloge edit operations
  private LockResult catModificationLock;
  private static final String LOCK_TOKEN = "catalogeditlock";

  // key also needed by BookmarksPortletRunController to identify type of bookmark
  private static final String TOOL_BOOKMARK = "tool_bookmark";
 
  /**
   * Init with catalog root
   *
   * @param ureq
   * @param wControl
   * @param rootce
   */
  public CatalogController(UserRequest ureq, WindowControl wControl, String jumpToNode) {
    // fallback translator to repository package to reduce redundant translations
    super(ureq, wControl, Util.createPackageTranslator(RepositoryManager.class, ureq.getLocale()));
   
    cm = CatalogManager.getInstance();

    List<CatalogEntry> rootNodes = cm.getRootCatalogEntries();
    CatalogEntry rootce;
    if (rootNodes.isEmpty()) throw new AssertException("No RootNodes found for Catalog! failed module init? corrupt DB?");
    rootce = (CatalogEntry) cm.getRootCatalogEntries().get(0);

    // Check AccessRights
    isAuthor = ureq.getUserSession().getRoles().isAuthor();
    isOLATAdmin = ureq.getUserSession().getRoles().isOLATAdmin();
    isGuest = ureq.getUserSession().getRoles().isGuestOnly();
    // and also if user is localTreeAdmin
    updateToolAccessRights(ureq, rootce, 0);
    canAddLinks = isOLATAdmin || isAuthor;
    canAdministrateCategory = isOLATAdmin;
    canAddSubCategories = isOLATAdmin || isLocalTreeAdmin;
    canRemoveAllLinks = isOLATAdmin || isLocalTreeAdmin;

    cm = CatalogManager.getInstance();

    myContent = createVelocityContainer("catalog");
   
    if (isOLATAdmin) {
      myContent.contextPut("RepoAccessVal", new Integer(RepositoryEntry.ACC_OWNERS));
    else if (isAuthor) {
      myContent.contextPut("RepoAccessVal", new Integer(RepositoryEntry.ACC_OWNERS_AUTHORS));
    else if (isGuest) {
      myContent.contextPut("RepoAccessVal", new Integer(RepositoryEntry.ACC_USERS_GUESTS));
    } else {
      // a daily user
      myContent.contextPut("RepoAccessVal", new Integer(RepositoryEntry.ACC_USERS));
    }

    myContent.contextPut(CATENTRY_LEAF, new Integer(CatalogEntry.TYPE_LEAF));
    myContent.contextPut(CATENTRY_NODE, new Integer(CatalogEntry.TYPE_NODE));
    // access rights for use in the Velocity Container
    myContent.contextPut("canAddLinks", new Boolean(canAddLinks));
    myContent.contextPut("canRemoveAllLinks", new Boolean(canRemoveAllLinks));
    myContent.contextPut("isGuest", new Boolean(isGuest));
    // add icon renderer
    myContent.contextPut("iconRenderer", new RepositoryEntryIconRenderer(getLocale()));
    // add this root node as history start
    historyStack.add(rootce);
    updateContent(ureq.getIdentity(), rootce, 0);
   
    // jump to a specific node in the catalog structure, build corresponding
    // historystack and update tool access
    if (jumpToNode != null) {
      activate(ureq, jumpToNode);
    }
    loginLink = LinkFactory.createLink("cat.login", myContent, this);
   
    putInitialPanel(myContent);
  }

  /**
   * @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 == myContent) { // links from vc -> here a link used in a
      // form action
      String command = event.getCommand();
      // FIXME:fj:c in .hbm.xml file: optimize loading (secgroup
      // outer-join=false)
      //     
      // events:
      // - subcategory selection fires a 'child' event
      // - 'navigation path' history
      // - link selectionfires a leaf event
      //
      if (command.startsWith(CATENTRY_CHILD)) { // child clicked
        int pos = Integer.parseInt(command.substring(CATENTRY_CHILD.length()));
        CatalogEntry cur = (CatalogEntry) childCe.get(pos);
        // put new as trail on stack
        historyStack.add(cur);
        updateToolAccessRights(ureq, cur, historyStack.indexOf(cur));
        updateContent(ureq.getIdentity(), cur, historyStack.indexOf(cur));
        fireEvent(ureq, Event.CHANGED_EVENT);
       
      } else if (command.startsWith(CATCMD_HISTORY)) { // history clicked
        int pos = Integer.parseInt(command.substring(CATCMD_HISTORY.length()));
        CatalogEntry cur = historyStack.get(pos);
        historyStack = historyStack.subList(0, pos + 1);
        updateToolAccessRights(ureq, cur, historyStack.indexOf(cur));
        updateContent(ureq.getIdentity(), cur, historyStack.indexOf(cur));
        fireEvent(ureq, Event.CHANGED_EVENT);
       
      } else if (command.startsWith(CATENTRY_LEAF)) { // link clicked
        int pos = Integer.parseInt(command.substring(CATENTRY_LEAF.length()));
        CatalogEntry cur = (CatalogEntry) childCe.get(pos);
        RepositoryEntry repoEntry = cur.getRepositoryEntry();
        if (repoEntry == null) throw new AssertException("a leaf did not have a repositoryentry! catalogEntry = key:" + cur.getKey()
            + ", title " + cur.getName());
        // launch entry if launchable, otherwise offer it as download / launch
        // it as non-html in browser
        String displayName = cur.getName();
        RepositoryHandler handler = RepositoryHandlerFactory.getInstance().getRepositoryHandler(repoEntry);
        OLATResource ores = repoEntry.getOlatResource();
        if (ores == null) throw new AssertException("repoEntry had no olatresource, repoKey = " + repoEntry.getKey());
        if (repoEntry.getCanLaunch()) {
          // we can create a controller and launch
          // it in OLAT, e.g. if it is a
          // content-packacking or a course

          //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;
            Controller launchController = ControllerFactory.createLaunchController(ores, null, ureq, dt.getWindowControl(), true);
            dt.setController(launchController);
            dts.addDTab(dt);
          }
          dts.activate(ureq, dt, null); // null: start with main entry point of controller
        } else if (repoEntry.getCanDownload()) {
          // else not launchable in olat, but downloadable -> send the document
          // directly to browser but "downloadable" (pdf, word, excel)
          MediaResource mr = handler.getAsMediaResource(ores);
          RepositoryManager.getInstance().incrementDownloadCounter(repoEntry);
          ureq.getDispatchResult().setResultingMediaResource(mr);
          return;
        } else { // neither launchable nor downloadable -> show details         
          //REVIEW:pb:replace EntryChangedEvent with a more specific event
          fireEvent(ureq, new EntryChangedEvent(repoEntry, EntryChangedEvent.MODIFIED));
          return;
        }

      } else if (command.startsWith(CATCMD_MOVE)) {
        String s = command.substring(CATCMD_MOVE.length());
        if (s.startsWith(CATENTRY_LEAF)) {
          // move a resource in the catalog - moving of catalog leves is triggered by a toolbox action
          int pos = Integer.parseInt(s.substring(CATENTRY_LEAF.length()));
          linkMarkedToBeEdited = (CatalogEntry) childCe.get(pos);
          removeAsListenerAndDispose(catEntryMoveController);
          boolean ajax = getWindowControl().getWindowBackOffice().getWindowManager().isAjaxEnabled();
          if (ajax) {
            // fancy ajax tree
            catEntryMoveController= new CatalogAjaxMoveController(ureq, getWindowControl(), linkMarkedToBeEdited);
          } else {
            // old-school selection tree
            catEntryMoveController= new CatalogEntryMoveController(getWindowControl(), ureq, linkMarkedToBeEdited, getTranslator());
          }
          listenTo(catEntryMoveController);
          removeAsListenerAndDispose(cmc);
          cmc = new CloseableModalController(getWindowControl(), "close", catEntryMoveController.getInitialComponent());
          listenTo(cmc);
          cmc.activate();
        }
      } else if (command.startsWith(CATCMD_REMOVE)) {
        String s = command.substring(CATCMD_REMOVE.length());
        if (s.startsWith(CATENTRY_LEAF)) {
          int pos = Integer.parseInt(s.substring(CATENTRY_LEAF.length()));
          linkMarkedToBeDeleted = (CatalogEntry) childCe.get(pos);
          // create modal dialog
          String[] trnslP = { linkMarkedToBeDeleted.getName() };
          dialogDeleteLink = activateYesNoDialog(ureq, null, getTranslator().translate(NLS_DIALOG_MODAL_LEAF_DELETE_TEXT, trnslP), dialogDeleteLink);
          return;
        }
      } else if (command.startsWith(CATCMD_EDIT)) {
        String s = command.substring(CATCMD_EDIT.length());
        if (s.startsWith(CATENTRY_LEAF)) {
          int pos = Integer.parseInt(s.substring(CATENTRY_LEAF.length()));
          linkMarkedToBeEdited = (CatalogEntry) childCe.get(pos);
          repositoryEditDescriptionController = new RepositoryEditDescriptionController(ureq, getWindowControl(), linkMarkedToBeEdited.getRepositoryEntry(), false);
          repositoryEditDescriptionController.addControllerListener(this);
          // open form in dialog
          removeAsListenerAndDispose(cmc);
          cmc = new CloseableModalController(getWindowControl(), "close", repositoryEditDescriptionController.getInitialComponent(), true, translate("tools.edit.catalog.category"));
          listenTo(cmc);
          cmc.activate();         
        }
      } else if (command.startsWith(CATCMD_DETAIL)) {
        String s = command.substring(CATCMD_DETAIL.length());
        if (s.startsWith(CATENTRY_LEAF)) {
          int pos = Integer.parseInt(s.substring(CATENTRY_LEAF.length()));
          CatalogEntry showDetailForLink = (CatalogEntry) childCe.get(pos);
          RepositoryEntry repoEnt = showDetailForLink.getRepositoryEntry();         
          fireEvent(ureq, new EntryChangedEvent(repoEnt, EntryChangedEvent.MODIFIED));
          //TODO [ingkr]
          //getWindowControl().getDTabs().activateStatic(ureq, RepositorySite.class.getName(), RepositoryMainController.JUMPFROMEXTERN+RepositoryMainController.JUMPFROMCATALOG+repoEnt.getKey().toString());
          return;
        }
      }
    }
    /*
     * login link clicked
     */   
    else if (source == loginLink){
      DispatcherAction.redirectToDefaultDispatcher(ureq.getHttpResp());
    }
    /*
     * add/edit node
     */
    else if (source == addEntryForm) {
      // remove modal dialog
      cmc.deactivate();
      if (event == Form.EVNT_VALIDATION_OK) {
        CatalogEntry ce = cm.createCatalogEntry();
        addEntryForm.fillEntry(ce);
        ce.setOwnerGroup(ManagerFactory.getManager().createAndPersistSecurityGroup());
        ce.setRepositoryEntry(null);
        ce.setParent(currentCatalogEntry);
        // optimistic save: might fail in case the parent has been deleted in the meantime
        cm.saveCatalogEntry(ce);
      } else if (event == Form.EVNT_FORM_CANCELLED) {
        // nothing to do
      }
      CatalogEntry reloaded = cm.loadCatalogEntry(currentCatalogEntry);
      currentCatalogEntry = reloaded;// FIXME:pb:
      updateContent(ureq.getIdentity(), currentCatalogEntry, currentCatalogEntryLevel);
      updateToolAccessRights(ureq, currentCatalogEntry, currentCatalogEntryLevel);
      // in any case, remove the lock
      if (catModificationLock != null && catModificationLock.isSuccess()) {
        CoordinatorManager.getCoordinator().getLocker().releaseLock(catModificationLock);
        catModificationLock = null;
      }
      fireEvent(ureq, Event.CHANGED_EVENT);
     
    } else if (source == editEntryForm) {
      // remove modal dialog
      cmc.deactivate();
      // optimistic save: might fail in case the current entry has been deleted
      // in the meantime by someone else
      CatalogEntry reloaded = (CatalogEntry) DBFactory.getInstance().loadObject(currentCatalogEntry);
      currentCatalogEntry = reloaded;// FIXME:pb
      if (event == Form.EVNT_VALIDATION_OK) {
        editEntryForm.fillEntry(currentCatalogEntry);
        cm.updateCatalogEntry(currentCatalogEntry);
        // update the changed name in the history path
        historyStack.remove(historyStack.size() - 1);
        historyStack.add(currentCatalogEntry);
      } else if (event == Form.EVNT_FORM_CANCELLED) {
        // nothing to do
      }
      // in any case, remove the lock
      if (catModificationLock != null && catModificationLock.isSuccess()) {
        CoordinatorManager.getCoordinator().getLocker().releaseLock(catModificationLock);
        catModificationLock = null;
      }
      updateContent(ureq.getIdentity(), currentCatalogEntry, currentCatalogEntryLevel);
    }
    /*
     * admin submitted a new structure
     */
    else if (source == addStructureForm) {
      // remove modal dialog first
      cmc.deactivate();
      if (event == Form.EVNT_VALIDATION_OK) {
        importStructure();
      }
      CatalogEntry newRoot = (CatalogEntry) cm.getRootCatalogEntries().get(0);
      historyStack = new ArrayList<CatalogEntry>();
      historyStack.add(newRoot);
      updateContent(ureq.getIdentity(), newRoot, 0);
      updateToolAccessRights(ureq, currentCatalogEntry, currentCatalogEntryLevel);
      fireEvent(ureq, Event.CHANGED_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)
   */
  public void event(UserRequest ureq, Controller source, Event event) {

    /*
     * events from the catalogToolC
     */
    if (source == catalogToolC) {
      /*
       * add new subcategory to the currentCategory
       */
      if (event.getCommand().equals(ACTION_ADD_CTLGCATEGORY)) {
        catModificationLock = CoordinatorManager.getCoordinator().getLocker().acquireLock(OresHelper.createOLATResourceableType(CatalogController.class), ureq.getIdentity(), LOCK_TOKEN);
        if ( ! catModificationLock.isSuccess()) {
          showError("catalog.locked.by", catModificationLock.getOwner().getName());
          return;
        }
        addEntryForm = new EntryForm("entryform", getTranslator(), false);
        addEntryForm.addListener(this);
        // open form in dialog
        removeAsListenerAndDispose(cmc);
        cmc = new CloseableModalController(getWindowControl(), "close", addEntryForm, true, translate("tools.add.catalog.category"));
        listenTo(cmc);
        cmc.activate();         
      }
      /*
       * add a link to the currentCategory
       */
      else if (event.getCommand().equals(ACTION_ADD_CTLGLINK)) {
        removeAsListenerAndDispose(rsc);
        rsc = new RepositorySearchController(translate(NLS_CHOOSE), ureq, getWindowControl(), true, false);
        listenTo(rsc);
        // OLAT-Admin has search form
        if (isOLATAdmin) {
          rsc.displaySearchForm();
        }
        // an Author gets the list of his repository
        else {
          // admin is responsible for not inserting wrong visibility entries!!
          rsc.doSearchByOwnerLimitAccess(ureq.getIdentity(), RepositoryEntry.ACC_USERS);
        }
        // open form in dialog
        removeAsListenerAndDispose(cmc);
        cmc = new CloseableModalController(getWindowControl(), "close", rsc.getInitialComponent(), true, translate("tools.add.catalog.link"));
        listenTo(cmc);
        cmc.activate();         
      }
      /*
       * edit the currentCategory
       */
      else if (event.getCommand().equals(ACTION_EDIT_CTLGCATEGORY)) {
        catModificationLock = CoordinatorManager.getCoordinator().getLocker().acquireLock(OresHelper.createOLATResourceableType(CatalogController.class), ureq.getIdentity(), LOCK_TOKEN);
        if ( ! catModificationLock.isSuccess()) {
          showError("catalog.locked.by", catModificationLock.getOwner().getName());
          return;
        }
        editEntryForm = new EntryForm("entryform", getTranslator(), false);
        editEntryForm.setFormFields(currentCatalogEntry);// fill the
        // form fields
        editEntryForm.addListener(this);
        // open form in dialog
        removeAsListenerAndDispose(cmc);
        cmc = new CloseableModalController(getWindowControl(), "close", editEntryForm, true, translate("tools.edit.catalog.category"));
        listenTo(cmc);
        cmc.activate();       
      }
      /*
       * edit current category's ownergroup
       */
      else if (event.getCommand().equals(ACTION_EDIT_CTLGCATOWNER)) {
        // add ownership management
        SecurityGroup secGroup = currentCatalogEntry.getOwnerGroup();
        if (secGroup == null) {
          CatalogEntry reloaded = cm.loadCatalogEntry(currentCatalogEntry);
          currentCatalogEntry = reloaded;// FIXME:pb:?
          secGroup = ManagerFactory.getManager().createAndPersistSecurityGroup();
          currentCatalogEntry.setOwnerGroup(secGroup);
          cm.saveCatalogEntry(currentCatalogEntry);
        }
        boolean keepAtLeastOne = currentCatalogEntryLevel == 0;
        removeAsListenerAndDispose(groupController);
        groupController = new GroupController(ureq, getWindowControl(), true, keepAtLeastOne, false, secGroup);
        listenTo(groupController);
        // open form in dialog
        removeAsListenerAndDispose(cmc);
        cmc = new CloseableModalController(getWindowControl(), "close", groupController.getInitialComponent(), true, translate("tools.edit.catalog.category.ownergroup"));
        listenTo(cmc);
        cmc.activate();         
      }
      /*
       * delete category (subtree)
       */
      else if (event.getCommand().equals(ACTION_DELETE_CTLGCATEGORY)) {
        catModificationLock = CoordinatorManager.getCoordinator().getLocker().acquireLock(OresHelper.createOLATResourceableType(CatalogController.class), ureq.getIdentity(), LOCK_TOKEN);
        if ( ! catModificationLock.isSuccess()) {
          showError("catalog.locked.by", catModificationLock.getOwner().getName());
          return;
        }
        String[] trnslP = { currentCatalogEntry.getName() };
        dialogDeleteSubtree = activateYesNoDialog(ureq, null, getTranslator().translate(NLS_DIALOG_MODAL_SUBTREE_DELETE_TEXT, trnslP), dialogDeleteSubtree);
        return;
      }
      /*
       * contact caretaker, request subcategory, request deletion of an entry,
       * etc.
       */
      else if (event.getCommand().equals(ACTION_NEW_CTGREQUEST)) {
        /*
         * find the first caretaker, looking from the leaf towards the root,
         * following the selected branch.
         */
        Manager mngr = ManagerFactory.getManager();
        ContactList caretaker = new ContactList(translate(NLS_CONTACT_TO_GROUPNAME_CARETAKER));
        final List emptyList = new ArrayList();
        List tmpIdent = new ArrayList();
        for (int i = historyStack.size() - 1; i >= 0 && tmpIdent.isEmpty(); i--) {
          // start at the selected category, the root category is asserted to
          // have the OLATAdministrator
          // so we end up having always at least one identity as receiver for a
          // request ;-)
          CatalogEntry tmp = historyStack.get(i);
          SecurityGroup tmpOwn = tmp.getOwnerGroup();
          if (tmpOwn != null) tmpIdent = mngr.getIdentitiesOfSecurityGroup(tmpOwn);
          else tmpIdent = emptyList;
        }
        for (int i = tmpIdent.size() - 1; i >= 0; i--) {
          caretaker.add((Identity) tmpIdent.get(i));
        }
       
        //create e-mail Message
        ContactMessage cmsg = new ContactMessage(ureq.getIdentity());
        cmsg.addEmailTo(caretaker);
        removeAsListenerAndDispose(cfc);
        cfc = new ContactFormController(ureq, getWindowControl(), false, true, false, false, cmsg);
        listenTo(cfc);
        // open form in dialog
        removeAsListenerAndDispose(cmc);
        cmc = new CloseableModalController(getWindowControl(), "close", cfc.getInitialComponent(), true, translate("contact.caretaker"));
        listenTo(cmc);
        cmc.activate();         
      }
      /*
       * add a structure
       */
      else if (event.getCommand().equals(ACTION_ADD_STRUCTURE)) {
        addStructureForm = new EntryForm("ADDSTRUCTURE", getTranslator(), false);
        addStructureForm.addListener(this);
        cmc = new CloseableModalController(getWindowControl(), "close", addStructureForm, true, translate("contact.caretaker"));
        listenTo(cmc);
        cmc.activate();         
      }
     
      /*
       * add bookmark
       */
     
      else if (event.getCommand().equals(ACTION_ADD_BOOKMARK)){
        removeAsListenerAndDispose(bookmarkController);
        CatalogManager cm = CatalogManager.getInstance();
        OLATResourceable ores = cm.createOLATResouceableFor(currentCatalogEntry);
        bookmarkController = new AddAndEditBookmarkController(ureq, getWindowControl(), currentCatalogEntry.getName(), "", ores, CatalogManager.CATALOGENTRY);           
        listenTo(bookmarkController);
        removeAsListenerAndDispose(cmc);
        cmc = new CloseableModalController(getWindowControl(), "close", bookmarkController.getInitialComponent());
        listenTo(cmc);
        cmc.activate();
      }
      /*
       * move catalogentry
       */
      else if(event.getCommand().equals(ACTION_MOVE_ENTRY)){       
        // Move catalog level - moving of resources in the catalog (leafs) is triggered by a velocity command
        // so, reset stale link to the current resource first (OLAT-4253), the linkMarkedToBeEdited will be reset
        // when an edit or move operation on the resource is done
        linkMarkedToBeEdited = null;
        //
        catModificationLock = CoordinatorManager.getCoordinator().getLocker().acquireLock(OresHelper.createOLATResourceableType(CatalogController.class), ureq.getIdentity(), LOCK_TOKEN);
        if ( ! catModificationLock.isSuccess()) {
          showError("catalog.locked.by", catModificationLock.getOwner().getName());
          return;
        }
        // check if user surfs in ajax mode
        removeAsListenerAndDispose(catEntryMoveController);
        boolean ajax = getWindowControl().getWindowBackOffice().getWindowManager().isAjaxEnabled();
        if (ajax) {
          // fancy ajax tree
          catEntryMoveController= new CatalogAjaxMoveController(ureq, getWindowControl(), currentCatalogEntry);
        } else {
          // old-school selection tree
          catEntryMoveController= new CatalogEntryMoveController(getWindowControl(), ureq, currentCatalogEntry, getTranslator());         
        }
        listenTo(catEntryMoveController);
        removeAsListenerAndDispose(cmc);
        cmc = new CloseableModalController(getWindowControl(), "close", catEntryMoveController.getInitialComponent());
        listenTo(cmc);
        cmc.activate();
      }
    }
    /*
     * from the repository search, a entry was selected to add
     */
    else if (source == rsc) {
      // remove modal dialog
      cmc.deactivate();
      if (event.getCommand().equals(RepositoryTableModel.TABLE_ACTION_SELECT_LINK)) {
        /*
         * succesfully selected a repository entry which will be a link within
         * the current Category
         */
        RepositoryEntry re = rsc.getSelectedEntry();
        /*
         * create, but do not persist a new catalog entry
         */
        newLinkNotPersistedYet = cm.createCatalogEntry();
        newLinkNotPersistedYet.setName(re.getDisplayname());
        newLinkNotPersistedYet.setDescription(re.getDescription());
        newLinkNotPersistedYet.setRepositoryEntry(re);
        newLinkNotPersistedYet.setType(CatalogEntry.TYPE_LEAF);
        /*
         * open the confirm form, which allows to change the link-title,
         * link-description.
         */
        newLinkNotPersistedYet.setOwnerGroup(ManagerFactory.getManager().createAndPersistSecurityGroup());
        cm.addCatalogEntry(currentCatalogEntry, newLinkNotPersistedYet);
        newLinkNotPersistedYet = null;
        updateContent(ureq.getIdentity(), currentCatalogEntry, currentCatalogEntryLevel);
        updateToolAccessRights(ureq, currentCatalogEntry, currentCatalogEntryLevel);
        fireEvent(ureq, Event.CHANGED_EVENT);
      } else if (event == Event.CANCELLED_EVENT) {
        updateContent(ureq.getIdentity(), currentCatalogEntry, currentCatalogEntryLevel);
        updateToolAccessRights(ureq, currentCatalogEntry, currentCatalogEntryLevel);
        fireEvent(ureq, Event.CHANGED_EVENT);

      }
    }
    /*
     * from remove subtree dialog -> yes or no
     */
    else if (source == dialogDeleteSubtree) {
      if (DialogBoxUIFactory.isYesEvent(event)) {
        // remember the parent of the subtree being deleted
        CatalogEntry parent = currentCatalogEntry.getParent();
        // delete the subtree!!!
        cm.deleteCatalogEntry(currentCatalogEntry);
        // display the parent
        historyStack.remove(historyStack.size() - 1);
        updateContent(ureq.getIdentity(), parent, historyStack.indexOf(parent));
        updateToolAccessRights(ureq, parent, historyStack.indexOf(parent));
        fireEvent(ureq, Event.CHANGED_EVENT);
      }
      // in any case, remove the lock
      if (catModificationLock != null && catModificationLock.isSuccess()) {
        CoordinatorManager.getCoordinator().getLocker().releaseLock(catModificationLock);
        catModificationLock = null;
      }

    }
    /*
     * from remove link dialog -> yes or no
     */
    else if (source == dialogDeleteLink) {
      if (DialogBoxUIFactory.isYesEvent(event)) {
        cm.deleteCatalogEntry(linkMarkedToBeDeleted);
        updateContent(ureq.getIdentity(), currentCatalogEntry, currentCatalogEntryLevel);
      }
      // in any case, remove the lock
      if (catModificationLock != null && catModificationLock.isSuccess()) {
        CoordinatorManager.getCoordinator().getLocker().releaseLock(catModificationLock);
        catModificationLock = null;
      }
    }
    /*
     * from contactform controller, aka sending e-mail to caretaker
     */
    else if (source == cfc) {
      // remove modal dialog
      cmc.deactivate();
      if (event.equals(Event.DONE_EVENT) || event.equals(Event.CANCELLED_EVENT)) {
        updateContent(ureq.getIdentity(), currentCatalogEntry, currentCatalogEntryLevel);
      }
    } else if (source == groupController) {
      // remove modal dialog
      cmc.deactivate();
      if(event instanceof IdentitiesAddEvent ) { //FIXME:chg: Move into seperate RepositoryOwnerGroupController like BusinessGroupEditController ?
        IdentitiesAddEvent identitiesAddedEvent = (IdentitiesAddEvent) event;
        List<Identity> list = identitiesAddedEvent.getAddIdentities();
        for (Identity identity : list) {
          ManagerFactory.getManager().addIdentityToSecurityGroup(identity, currentCatalogEntry.getOwnerGroup());
          identitiesAddedEvent.getAddedIdentities().add(identity);
        }
      } else if (event instanceof IdentitiesRemoveEvent) {
        IdentitiesRemoveEvent identitiesRemoveEvent = (IdentitiesRemoveEvent) event;
        List<Identity> list = identitiesRemoveEvent.getRemovedIdentities();
        for (Identity identity : list) {
          ManagerFactory.getManager().removeIdentityFromSecurityGroup(identity, currentCatalogEntry.getOwnerGroup());
        }   
      }
    }
   
    else if(source == bookmarkController ){
      // remove modal dialog
      cmc.deactivate();
      if(event.equals(Event.DONE_EVENT)){
        // Add bookmark workflow did successfully save the bookmark, nothing to
        // do here
        // User did set a bookmark - bookmarking no longer enabled and disable
        // it in toolbox
        canBookmark = false;
        catalogToolC.setEnabled(TOOL_BOOKMARK, canBookmark);
      }
    }

    else if(source == catEntryMoveController){
      cmc.deactivate();
      if(event.equals(Event.DONE_EVENT)){
        //linkMarkedToBeEdited is the catalog entry - "leaf" - which is moved
        showInfo("tools.move.catalog.entry.success", (linkMarkedToBeEdited == null ? currentCatalogEntry.getName() : linkMarkedToBeEdited.getName()));
        //currentCatalogEntry is the current active "Folder" - reload model to reflect change.
        reloadHistoryStack(ureq, currentCatalogEntry.getKey());
      } else if(event.equals(Event.FAILED_EVENT)){
        showError("tools.move.catalog.entry.failed");
        updateContent(ureq.getIdentity(), currentCatalogEntry, currentCatalogEntryLevel);
      }
      // in any case, remove the lock
      if (catModificationLock != null && catModificationLock.isSuccess()) {
        CoordinatorManager.getCoordinator().getLocker().releaseLock(catModificationLock);
        catModificationLock = null;
      }
    }
   
    else if (source == cmc) {
      // in any case, remove the lock
      if (catModificationLock != null && catModificationLock.isSuccess()) {
        CoordinatorManager.getCoordinator().getLocker().releaseLock(catModificationLock);
        catModificationLock = null;
      }
    }
    else if (source == repositoryEditDescriptionController) {
      if (event == Event.CHANGED_EVENT) {
        linkMarkedToBeEdited.setRepositoryEntry(repositoryEditDescriptionController.getRepositoryEntry());
        updateContent(ureq.getIdentity(), currentCatalogEntry, currentCatalogEntryLevel);
      } else if (event == Event.CANCELLED_EVENT) {
        cmc.deactivate();
      }
    }
  }

  /**
   * before calling this method make sure the person has the right to add
   * categories. The method checks further if the person also can add links as
   * author.
   *
   * @return configured tool controller
   */
  public ToolController createCatalogToolController() {
    removeAsListenerAndDispose(catalogToolC);
    catalogToolC = ToolFactory.createToolController(getWindowControl());
    listenTo(catalogToolC);
    //if (isOLATAdmin || isLocalTreeAdmin || isAuthor ) {
    // at least a person being able to do something...
    if (!isGuest) {
      // included normal user now for bookmark functionality
      /*
       * edit tools
       */
      catalogToolC.addHeader(getTranslator().translate("tools.edit.header"));     
     
      catalogToolC.addLink(ACTION_ADD_BOOKMARK, translate(NLS_TOOLS_ADD_BOOKMARK),TOOL_BOOKMARK,null);      // new bookmark link
      catalogToolC.setEnabled(TOOL_BOOKMARK, canBookmark);
     
      if (canAdministrateCategory || canAddLinks) {
        if (canAdministrateCategory) catalogToolC.addLink(ACTION_EDIT_CTLGCATEGORY, translate(NLS_TOOLS_EDIT_CATALOG_CATEGORY));
        if (canAdministrateCategory) catalogToolC.addLink(ACTION_EDIT_CTLGCATOWNER,
            translate(NLS_TOOLS_EDIT_CATALOG_CATEGORY_OWNERGROUP));
        if (canAddLinks) catalogToolC.addLink(ACTION_NEW_CTGREQUEST, translate(NLS_TOOLS_NEW_CATALOG_CATEGORYREQUEST));

        if (canAdministrateCategory && currentCatalogEntryLevel > 0)
        // delete root? very dangerous, disabled!
        catalogToolC.addLink(ACTION_DELETE_CTLGCATEGORY, translate(NLS_TOOLS_DELETE_CATALOG_ENTRY));
        if (canAdministrateCategory && currentCatalogEntryLevel > 0)
          catalogToolC.addLink(ACTION_MOVE_ENTRY, translate(NLS_TOOLS_MOVE_CATALOG_ENTRY));
      }

      /*
       * add tools
       */
      if(isOLATAdmin || isLocalTreeAdmin || isAuthor){
          catalogToolC.addHeader(translate(NLS_TOOLS_ADD_HEADER));
          if (canAddSubCategories) catalogToolC.addLink(ACTION_ADD_CTLGCATEGORY, translate(NLS_TOOLS_ADD_CATALOG_CATEGORY));
          if (canAddLinks) catalogToolC.addLink(ACTION_ADD_CTLGLINK, translate(NLS_TOOLS_ADD_CATALOG_LINK));
          if (currentCatalogEntryLevel == 0 && isOLATAdmin && cm.getChildrenOf(currentCatalogEntry).isEmpty())
            catalogToolC.addLink(ACTION_ADD_STRUCTURE, translate(NLS_TOOLS_PASTESTRUCTURE));
     
    }
    return catalogToolC;
  }

  /**
   * @see org.olat.core.gui.control.DefaultController#doDispose(boolean)
   */
  protected void doDispose() {
    // remove any locks
    if (catModificationLock != null && catModificationLock.isSuccess()) {
      CoordinatorManager.getCoordinator().getLocker().releaseLock(catModificationLock);
      catModificationLock = null;
    }
    // controllers autodisposed by basic controller
  }

  /**
   * refresh content of current category for displaying
   *
   * @param ce
   * @param ceLevel
   */
  private void updateContent(Identity identity, CatalogEntry ce, int ceLevel) {
    /*
     * FIXME:pb:c include lookahead feature, displaying the 1st 3 children if
     * any, to give a google directory feeling
     */
    currentCatalogEntry = ce;
    currentCatalogEntryLevel = ceLevel;
    myContent.contextPut("canAddLinks", new Boolean(canAddLinks));
    myContent.contextPut("canRemoveAllLinks", new Boolean(canRemoveAllLinks));
    myContent.contextPut("currentCatalogEntry", currentCatalogEntry);
    childCe = cm.getChildrenOf(ce);
    myContent.contextPut("children", childCe);
    for ( Object leaf : childCe ) {
      CatalogEntry entry = (CatalogEntry)leaf;
      if(entry.getType() == CatalogEntry.TYPE_NODE) continue;
      String name = "image" + childCe.indexOf(leaf);
      ImageComponent ic = RepositoryEntryImageController.getImageComponentForRepositoryEntry(name, entry.getRepositoryEntry());
      if(ic == null) {
        myContent.remove(myContent.getComponent(name));
        continue;
      }
      ic.setMaxWithAndHeightToFitWithin(200, 100);
      myContent.put(name, ic);
    }
    myContent.contextPut(CATCMD_HISTORY, historyStack);

    String url = Settings.getServerContextPathURI() + "/url/CatalogEntry/" + ce.getKey();
    myContent.contextPut("guestExtLink", url + "?guest=true&amp;lang=" + getLocale().getLanguage());
    if ( ! isGuest) {
      myContent.contextPut("extLink", url);
    }
    // check which of the entries are owned entries. users who can add links
    // can also remove links. users who can remove all links do not need to be
    // checked
    if (canAddLinks && !canRemoveAllLinks) {
      List ownedLinks = cm.filterOwnedLeafs(identity, childCe);
      if (ownedLinks.size() > 0) {
        myContent.contextPut("hasOwnedLinks", Boolean.TRUE);
        myContent.contextPut("ownedLinks", ownedLinks);
      } else myContent.contextPut("hasOwnedLinks", Boolean.FALSE);

    } else myContent.contextPut("hasOwnedLinks", Boolean.FALSE);
  }

  /**
   * Helper to imports simple tree structure, for simplicity
   */
  private void importStructure() {
    CatalogEntry oldRoot = (CatalogEntry) cm.getRootCatalogEntries().get(0);
    SecurityGroup rootOwners = oldRoot.getOwnerGroup();
    Manager secMgr = ManagerFactory.getManager();
    List olatAdminIdents = secMgr.getIdentitiesOfSecurityGroup(rootOwners);
    SecurityGroup catalogAdmins = secMgr.createAndPersistSecurityGroup();
    for (int i = 0; i < olatAdminIdents.size(); i++) {
      secMgr.addIdentityToSecurityGroup((Identity) olatAdminIdents.get(i), catalogAdmins);
    }
    cm.deleteCatalogEntry(oldRoot);

    CatalogEntry dummy = cm.createCatalogEntry();
    addStructureForm.fillEntry(dummy);
    String structure = dummy.getDescription();
    String[] lines = structure.split("\n");
    Stack<CatalogEntry> treeStack = new Stack<CatalogEntry>();
    //
    CatalogEntry newRoot = cm.createCatalogEntry();
    newRoot.setParent(null);
    newRoot.setType(CatalogEntry.TYPE_NODE);
    newRoot.setDescription("fill it");
    newRoot.setName(lines[0]);
    newRoot.setOwnerGroup(catalogAdmins);
    cm.saveCatalogEntry(newRoot);
    treeStack.push(newRoot);
    for (int i = 1; i < lines.length; i++) {
      int level = 0;
      int pos = 0;
      while ("".equals(lines[i].substring(pos, pos + 2).trim())) {
        level++;
        pos += 3;
      }
      CatalogEntry tmp = cm.createCatalogEntry();
      tmp.setType(CatalogEntry.TYPE_NODE);
      tmp.setDescription("fill it");
      tmp.setName(lines[i].trim());
      if (treeStack.size() == level) {
        tmp.setParent(treeStack.lastElement());
        treeStack.push(tmp);
      } else if (treeStack.size() > level) {
        // moving towards root
        for (int ii = treeStack.size() - 1; ii >= level; ii--) {
          treeStack.pop();
        }
        tmp.setParent(treeStack.lastElement());
        treeStack.push(tmp);
      }
      cm.saveCatalogEntry(tmp);
    }
  }

  /**
   * Internal helper to calculate the users rights within the controller. The
   * method will fire change events if necessary to signal the parent controller
   * that he need to rebuild the tool controller
   *
   * @param ureq
   * @param ce The current catalog category element from the given level
   * @param pos The current level in the catalog
   */
  private void updateToolAccessRights(UserRequest ureq, CatalogEntry ce, int pos) {
    // 1) check if user has already a bookmark for this level
    final CatalogEntry tmp=ce;
    OLATResourceable catEntryOres = CatalogManager.getInstance().createOLATResouceableFor(ce);
    if (tmp != null && BookmarkManager.getInstance().isResourceableBookmarked(ureq.getIdentity(), catEntryOres)){
      canBookmark = false;
      if(catalogToolC != null){
        catalogToolC.setEnabled(TOOL_BOOKMARK, canBookmark);
        fireEvent(ureq, Event.CHANGED_EVENT);
      }
    } else{
      canBookmark=true;
    }
    // 2) check if insert structure must be removed or showed
    if (isOLATAdmin && currentCatalogEntryLevel == 0) {
      fireEvent(ureq, Event.CHANGED_EVENT);
    }
    if (isOLATAdmin) return;

    // 3) check other cases that might change default values from constructor
    if (isLocalTreeAdminLevel > pos) {
      // 3a) below branch that user has admin rights - revoke all rights
      isLocalTreeAdminLevel = -1;
      isLocalTreeAdmin = false;
      canAddLinks = isOLATAdmin || isAuthor;
      canAdministrateCategory = isOLATAdmin;
      canAddSubCategories = isOLATAdmin;
      canRemoveAllLinks = isOLATAdmin;
      fireEvent(ureq, Event.CHANGED_EVENT);
     
    } else if (isLocalTreeAdminLevel == -1) {
      // 3b) check if user is admin for this level
      SecurityGroup owners = ce.getOwnerGroup();
      boolean isInGroup = false;
      if (owners != null) {
        isInGroup = ManagerFactory.getManager().isIdentityInSecurityGroup(ureq.getIdentity(), owners);
      }
      if (isInGroup) {
        isLocalTreeAdminLevel = pos;
        isLocalTreeAdmin = true;
        canAddLinks = isOLATAdmin || isAuthor;
        canAdministrateCategory = true;
        canAddSubCategories = true;
        canRemoveAllLinks = true;
        fireEvent(ureq, Event.CHANGED_EVENT);       
      }
    }
  }

  /**
   * @see org.olat.core.gui.control.generic.dtabs.Activateable#activate(org.olat.core.gui.UserRequest, java.lang.String)
   */
  public void activate(UserRequest ureq, String viewIdentifier){
     // transforms the parameter jumpToNode into a long value and calls jumpToNode(UserRequest, long)
    try{
      long parsed=Long.parseLong(viewIdentifier);
      reloadHistoryStack(ureq, parsed);
    } catch(Exception e){
      logWarn("Could not activate catalog entry with ID::" + viewIdentifier, null);
    }
  }
 
  /**
   * Internal helper: Get's the requested catalog node and set it as active
   * content, builds also the history stack from the root-node to this node.
   *
   * @return true if successful otherwise false (e.c. jumpToNode referenced a
   *         catalog leaf or no catalog entry at all)
   */
  private boolean jumpToNode(UserRequest ureq, long jumpToNode){
    CatalogEntry cE=CatalogManager.getInstance().loadCatalogEntry(Long.valueOf(jumpToNode));
      if(cE!=null){
          Stack<CatalogEntry> stack=new Stack<CatalogEntry>();
          // get elements, and add to filo stack
          while(cE !=null){
            stack.push(cE);
            cE=cE.getParent();
          }
          // read filo stack
          while ( !stack.isEmpty())
          {
            cE = stack.pop();
            historyStack.add(cE);
            updateContent(ureq.getIdentity(), cE, historyStack.size()-1);         
            updateToolAccessRights(ureq, cE, historyStack.size()-1);
          }
          return true;
      }
      return false;
  }

  /**
   * Internal helper: clear history and jumpt to the given node
   * @param ureq
   * @param jumpToNode
   */
  private void reloadHistoryStack(UserRequest ureq, long jumpToNode){
    historyStack.clear();
    jumpToNode(ureq, jumpToNode);
  }

}
TOP

Related Classes of org.olat.catalog.ui.CatalogController

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.