/** * 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. * <hr> * <a href="http://www.openolat.org"> * OpenOLAT - Online Learning and Training</a><br> * This file has been modified by the OpenOLAT community. Changes are licensed * under the Apache 2.0 license as the original file. */ package org.olat.core.commons.services.mark.ui; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import org.olat.NewControllerFactory; import org.olat.core.CoreSpringFactory; import org.olat.core.commons.services.mark.Mark; import org.olat.core.commons.services.mark.MarkManager; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.link.Link; import org.olat.core.gui.components.link.LinkFactory; import org.olat.core.gui.components.table.ColumnDescriptor; import org.olat.core.gui.components.table.DefaultColumnDescriptor; import org.olat.core.gui.components.table.Table; import org.olat.core.gui.components.table.TableController; import org.olat.core.gui.components.table.TableEvent; import org.olat.core.gui.components.table.TableGuiConfiguration; 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.generic.portal.AbstractPortletRunController; import org.olat.core.gui.control.generic.portal.PortletDefaultTableDataModel; import org.olat.core.gui.control.generic.portal.PortletEntry; import org.olat.core.gui.control.generic.portal.PortletToolSortingControllerImpl; import org.olat.core.gui.control.generic.portal.SortingCriteria; import org.olat.core.gui.translator.Translator; import org.olat.core.id.context.BusinessControl; import org.olat.core.id.context.BusinessControlFactory; import org.olat.core.util.Util; import org.olat.core.util.filter.FilterFactory; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryEntryStatus; import org.olat.repository.RepositoryManager; /** * Description:<br> * Run view controller for the groups list portlet * <P> * Initial Date: 11.07.2005 <br> * @author gnaegi */ public class BookmarksPortletRunController extends AbstractPortletRunController<Bookmark> { private static final String CMD_LAUNCH = "cmd.launch"; private TableController tableCtr; private BookmarkPortletTableDataModel bookmarkListModel; private VelocityContainer bookmarksVC; private Link showAllLink; private final MarkManager markManager; private final RepositoryManager repositoryManager; private final List<String> types = Collections.singletonList("RepositoryEntry"); /** * Constructor * @param ureq * @param component */ public BookmarksPortletRunController(WindowControl wControl, UserRequest ureq, Translator trans, String portletName, int defaultMaxEntries) { super(wControl, ureq, trans, portletName, defaultMaxEntries); sortingTermsList.add(SortingCriteria.TYPE_SORTING); sortingTermsList.add(SortingCriteria.ALPHABETICAL_SORTING); sortingTermsList.add(SortingCriteria.DATE_SORTING); repositoryManager = RepositoryManager.getInstance(); markManager = CoreSpringFactory.getImpl(MarkManager.class); bookmarksVC = createVelocityContainer("bookmarksPortlet"); showAllLink = LinkFactory.createLink("bookmarksPortlet.showAll", bookmarksVC, this); showAllLink.setIconRightCSS("o_icon o_icon_start"); TableGuiConfiguration tableConfig = new TableGuiConfiguration(); tableConfig.setTableEmptyMessage(trans.translate("bookmarksPortlet.nobookmarks")); tableConfig.setDisplayTableHeader(false); tableConfig.setCustomCssClass("o_portlet_table"); tableConfig.setDisplayRowCount(false); tableConfig.setPageingEnabled(false); tableConfig.setDownloadOffered(false); //disable the default sorting for this table tableConfig.setSortingEnabled(false); tableCtr = new TableController(tableConfig, ureq, getWindowControl(), trans); listenTo(tableCtr); // dummy header key, won't be used since setDisplayTableHeader is set to false tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("bookmarksPortlet.bgname", 0, CMD_LAUNCH, trans.getLocale())); tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("bookmarksPortlet.type", 1, null, trans.getLocale(), ColumnDescriptor.ALIGNMENT_RIGHT)); sortingCriteria = getPersistentSortingConfiguration(ureq); reloadModel(sortingCriteria); bookmarksVC.put("table", tableCtr.getInitialComponent()); putInitialPanel(bookmarksVC); } /** * Gets all bookmarks for this identity and converts the list into an PortletEntry list. * @param ureq * @return */ private List<PortletEntry<Bookmark>> getAllPortletEntries() { List<Mark> markList = markManager.getMarks(getIdentity(), types); List<Bookmark> bookmarkList = convertMarkToBookmark(markList); return convertBookmarkToPortletEntryList(bookmarkList); } /** * Converts list. * @param items * @return */ private List<PortletEntry<Bookmark>> convertBookmarkToPortletEntryList(List<Bookmark> items) { List<PortletEntry<Bookmark>> convertedList = new ArrayList<PortletEntry<Bookmark>>(); for(Bookmark mark:items) { convertedList.add(new BookmarkPortletEntry(mark)); } return convertedList; } private List<Bookmark> convertMarkToBookmark(List<Mark> items) { List<Bookmark> convertedList = new ArrayList<Bookmark>(); List<Long> reKeys = new ArrayList<Long>(); for(Mark mark:items) { reKeys.add(mark.getOLATResourceable().getResourceableId()); } List<RepositoryEntry> repositoryEntries = repositoryManager.lookupRepositoryEntries(reKeys); Map<Long,RepositoryEntry> keyToRepositoryEntryMap = new HashMap<Long,RepositoryEntry>(); for(RepositoryEntry repositoryEntry:repositoryEntries) { keyToRepositoryEntryMap.put(repositoryEntry.getKey(), repositoryEntry); } for(Mark mark:items) { RepositoryEntry repositoryEntry = keyToRepositoryEntryMap.get(mark.getOLATResourceable().getResourceableId()); if(repositoryEntry != null) { convertedList.add(new Bookmark(mark, repositoryEntry)); } } return convertedList; } /** * Reloads the bookmarks table model according with the input SortingCriteria. * It first evaluate the sortingCriteria type; if auto get bookmarks from BookmarkManager * and sort the item list according with the sortingCriteria. * Else get the manually sorted list. * @param identity * @param sortingCriteria */ protected void reloadModel(SortingCriteria sortingCriteria) { if (sortingCriteria.getSortingType() == SortingCriteria.AUTO_SORTING) { List<Mark> markList = markManager.getMarks(getIdentity(), types); List<Bookmark> bookmarkList = convertMarkToBookmark(markList); bookmarkList = getSortedList(bookmarkList, sortingCriteria ); List<PortletEntry<Bookmark>> entries = convertBookmarkToPortletEntryList(bookmarkList); bookmarkListModel = new BookmarkPortletTableDataModel(entries, getLocale()); tableCtr.setTableDataModel(bookmarkListModel); } else { reloadModel(this.getPersistentManuallySortedItems()); } } /** * Sets the table model if the sorted items list is already available. * @param ureq * @param sortedItems */ protected void reloadModel(List<PortletEntry<Bookmark>> sortedItems) { bookmarkListModel = new BookmarkPortletTableDataModel(sortedItems, getLocale()); tableCtr.setTableDataModel(bookmarkListModel); } /** * @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 == showAllLink){ // activate homes tab in top navigation and active bookmarks menu item String resourceUrl = "[MyCoursesSite:0][Favorits:0]"; BusinessControl bc = BusinessControlFactory.getInstance().createFromString(resourceUrl); WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(bc, getWindowControl()); NewControllerFactory.getInstance().launch(ureq, bwControl); } } /** * @see org.olat.core.gui.control.ControllerEventListener#dispatchEvent(org.olat.core.gui.UserRequest, org.olat.core.gui.control.Controller, org.olat.core.gui.control.Event) */ @Override public void event(UserRequest ureq, Controller source, Event event) { super.event(ureq, source, event); if (source == tableCtr) { if (event.getCommand().equals(Table.COMMANDLINK_ROWACTION_CLICKED)) { TableEvent te = (TableEvent) event; String actionid = te.getActionId(); if (actionid.equals(CMD_LAUNCH)) { int rowid = te.getRowId(); PortletEntry<Bookmark> bookmark = bookmarkListModel.getObject(rowid); String businessPath = bookmark.getValue().getBusinessPath(); NewControllerFactory.getInstance().launch(businessPath, ureq, getWindowControl()); } } } } /** * Retrieve the persistent manually sorted items for the current portlet. * @param ureq * @return */ private List<PortletEntry<Bookmark>> getPersistentManuallySortedItems() { List<PortletEntry<Bookmark>> entries = getAllPortletEntries(); return getPersistentManuallySortedItems(entries); } /** * Retrieves the persistent sortingCriteria and the persistent manually sorted, if any, * creates the table model for the manual sorting, and instantiates the PortletToolSortingControllerImpl. * @param ureq * @param wControl * @return a PortletToolSortingControllerImpl istance. */ protected PortletToolSortingControllerImpl<Bookmark> createSortingTool(UserRequest ureq, WindowControl wControl) { if(portletToolsController==null) { List<PortletEntry<Bookmark>> entries = getAllPortletEntries(); PortletDefaultTableDataModel<Bookmark> tableDataModel = new BookmarkManualSortingTableDataModel(entries, ureq.getLocale()); List<PortletEntry<Bookmark>> sortedItems = getPersistentManuallySortedItems(); portletToolsController = new PortletToolSortingControllerImpl<Bookmark>(ureq, wControl, getTranslator(), sortingCriteria, tableDataModel, sortedItems); listenTo(portletToolsController); portletToolsController.setConfigManualSorting(true); portletToolsController.setConfigAutoSorting(true); } return portletToolsController; } /** * Comparator implementation used for sorting bookmarks entries according with the * input sortingCriteria. * <p> * @param sortingCriteria * @return a Comparator for the input sortingCriteria */ protected Comparator<Bookmark> getComparator(final SortingCriteria sortingCriteria) { return new Comparator<Bookmark>(){ public int compare(final Bookmark bookmark1, final Bookmark bookmark2) { int comparisonResult = 0; if(sortingCriteria.getSortingTerm()==SortingCriteria.ALPHABETICAL_SORTING) { comparisonResult = collator.compare(bookmark1.getTitle(), bookmark2.getTitle()); } else if(sortingCriteria.getSortingTerm()==SortingCriteria.DATE_SORTING) { comparisonResult = bookmark1.getCreationDate().compareTo(bookmark2.getCreationDate()); } else if(sortingCriteria.getSortingTerm()==SortingCriteria.TYPE_SORTING) { comparisonResult = bookmark1.getDisplayrestype().compareTo(bookmark2.getDisplayrestype()); } if(!sortingCriteria.isAscending()) { //if not isAscending return (-comparisonResult) return -comparisonResult; } return comparisonResult; }}; } /** * * PortletDefaultTableDataModel implementation for the current portlet. * * <P> * Initial Date: 10.12.2007 <br> * @author Lavinia Dumitrescu */ private static class BookmarkPortletTableDataModel extends PortletDefaultTableDataModel<Bookmark> { private final Locale locale; public BookmarkPortletTableDataModel(List<PortletEntry<Bookmark>> objects, Locale locale) { super(objects, 2); this.locale = locale; } public Object getValueAt(int row, int col) { PortletEntry<Bookmark> entry = getObject(row); Bookmark bookmark = entry.getValue(); switch (col) { case 0: String name = getBookmarkTitle(bookmark); return name; case 1: String resType = bookmark.getDisplayrestype(); return NewControllerFactory.translateResourceableTypeName(resType, locale); default: return "ERROR"; } } /** * Get displayname of a bookmark entry. If bookmark entry a RepositoryEntry * and is this RepositoryEntry closed then add a prefix to the title. */ private String getBookmarkTitle(Bookmark bookmark) { String title = bookmark.getTitle(); if (RepositoryManager.getInstance().createRepositoryEntryStatus(bookmark.getStatusCode()).isClosed()) { Translator pT = Util.createPackageTranslator(RepositoryEntryStatus.class, locale); title = "[" + pT.translate("title.prefix.closed") + "] ".concat(title); } return title; } } /** * * Description:<br> * TableDataModel implementation for the bookmark manual sorting. * * <P> * Initial Date: 23.11.2007 <br> * @author Lavinia Dumitrescu */ private static class BookmarkManualSortingTableDataModel extends PortletDefaultTableDataModel<Bookmark> { private final Locale locale; /** * @param objects * @param locale */ public BookmarkManualSortingTableDataModel(List<PortletEntry<Bookmark>> objects, Locale locale) { super(objects, 4); this.locale = locale; } /** * @see org.olat.core.gui.components.table.TableDataModel#getValueAt(int, int) */ public final Object getValueAt(int row, int col) { PortletEntry<Bookmark> entry = getObject(row); Bookmark bm = entry.getValue(); switch (col) { case 0: return bm.getTitle(); case 1: String desc = bm.getDescription(); return (desc == null ? "n/a" : FilterFactory.getHtmlTagsFilter().filter(desc)); case 2: String resType = bm.getDisplayrestype(); return (resType == null ? "n/a" : NewControllerFactory.translateResourceableTypeName(resType, locale)); case 3: Date date = bm.getCreationDate(); //return DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, getTranslator().getLocale()).format(date); //return date else the sorting doesn't work properly return date; default: return "error"; } } } /** * * PortletEntry impl for Bookmark values. * * <P> * Initial Date: 10.12.2007 <br> * @author Lavinia Dumitrescu */ private static class BookmarkPortletEntry implements PortletEntry<Bookmark> { private final Bookmark mark; public BookmarkPortletEntry(Bookmark mark) { this.mark = mark; } public Long getKey() { return mark.getKey(); } public Bookmark getValue() { return mark; } } }