/**
* 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.course.assessment;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import org.olat.NewControllerFactory;
import org.olat.core.commons.fullWebApp.LayoutMain3ColsController;
import org.olat.core.commons.fullWebApp.popup.BaseFullWebappPopupLayoutFactory;
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.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.util.ComponentUtil;
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.creator.ControllerCreator;
import org.olat.core.gui.control.generic.popup.PopupBrowserWindow;
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.Identity;
import org.olat.core.id.context.BusinessControl;
import org.olat.core.id.context.BusinessControlFactory;
import org.olat.core.util.StringHelper;
import org.olat.core.util.event.GenericEventListener;
import org.olat.course.CourseModule;
import org.olat.course.assessment.manager.EfficiencyStatementManager;
import org.olat.course.assessment.model.UserEfficiencyStatementLight;
import org.olat.course.certificate.ui.CertificateAndEfficiencyStatementController;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Description:<br>
* Run view controller for the efficiency statement list portlet
* <P>
* Initial Date: 11.07.2005 <br>
* @author gnaegi
*/
public class EfficiencyStatementsPortletRunController extends AbstractPortletRunController<UserEfficiencyStatementLight> implements GenericEventListener {
private static final String CMD_LAUNCH = "cmd.launch";
private TableController tableCtr;
private EfficiencyStatementsTableDataModel efficiencyStatementsListModel;
private VelocityContainer efficiencyStatementsVC;
private boolean needReloadModel;
private Identity cOwner;
private Link showAllLink;
@Autowired
private EfficiencyStatementManager esm;
/**
* Constructor
* @param ureq
* @param component
*/
public EfficiencyStatementsPortletRunController(WindowControl wControl, UserRequest ureq, Translator trans,
String portletName, int defaultMaxEntries) {
super(wControl, ureq, trans, portletName, defaultMaxEntries);
this.cOwner = ureq.getIdentity();
sortingTermsList.add(SortingCriteria.ALPHABETICAL_SORTING);
sortingTermsList.add(SortingCriteria.DATE_SORTING);
this.efficiencyStatementsVC = this.createVelocityContainer("efficiencyStatementsPortlet");
showAllLink = LinkFactory.createLink("efficiencyStatementsPortlet.showAll", efficiencyStatementsVC, this);
showAllLink.setIconRightCSS("o_icon o_icon_start");
TableGuiConfiguration tableConfig = new TableGuiConfiguration();
tableConfig.setTableEmptyMessage(trans.translate("efficiencyStatementsPortlet.nostatements"));
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);
DefaultColumnDescriptor cd0 = new DefaultColumnDescriptor("table.header.course", 0, CMD_LAUNCH, trans.getLocale());
cd0.setIsPopUpWindowAction(true, "height=600, width=800, location=no, menubar=no, resizable=yes, status=no, scrollbars=yes, toolbar=no");
tableCtr.addColumnDescriptor(cd0);
this.sortingCriteria = getPersistentSortingConfiguration(ureq);
reloadModel(sortingCriteria);
this.efficiencyStatementsVC.put("table", tableCtr.getInitialComponent());
ComponentUtil.registerForValidateEvents(efficiencyStatementsVC, this);
putInitialPanel(efficiencyStatementsVC);
CourseModule.registerForCourseType(this, ureq.getIdentity());
}
/**
* Gets all EfficiencyStatements for this portlet and wraps them into PortletEntry impl.
* @param ureq
* @return the PortletEntry list.
*/
private List<PortletEntry<UserEfficiencyStatementLight>> getAllPortletEntries() {
List<UserEfficiencyStatementLight> efficiencyStatementsList = esm.findEfficiencyStatementsLight(getIdentity());
List<PortletEntry<UserEfficiencyStatementLight>> portletEntryList = convertEfficiencyStatementToPortletEntryList(efficiencyStatementsList);
return portletEntryList;
}
/**
* Converts a EfficiencyStatement list into a PortletEntry list.
* @param items
* @return
*/
private List<PortletEntry<UserEfficiencyStatementLight>> convertEfficiencyStatementToPortletEntryList(List<UserEfficiencyStatementLight> items) {
List<PortletEntry<UserEfficiencyStatementLight>> convertedList = new ArrayList<PortletEntry<UserEfficiencyStatementLight>>();
for(UserEfficiencyStatementLight item:items) {
if(StringHelper.containsNonWhitespace(item.getShortTitle())) {
convertedList.add(new EfficiencyStatementPortletEntry(item));
}
}
return convertedList;
}
/**
*
* @see org.olat.core.gui.control.generic.portal.AbstractPortletRunController#reloadModel(org.olat.core.gui.UserRequest, org.olat.core.gui.control.generic.portal.SortingCriteria)
*/
protected void reloadModel(SortingCriteria sortingCriteria) {
if (sortingCriteria.getSortingType() == SortingCriteria.AUTO_SORTING) {
List<UserEfficiencyStatementLight> efficiencyStatementsList = esm.findEfficiencyStatementsLight(getIdentity());
efficiencyStatementsList = getSortedList(efficiencyStatementsList, sortingCriteria);
List<PortletEntry<UserEfficiencyStatementLight>> entries = convertEfficiencyStatementToPortletEntryList(efficiencyStatementsList);
efficiencyStatementsListModel = new EfficiencyStatementsTableDataModel(entries,2);
tableCtr.setTableDataModel(efficiencyStatementsListModel);
} else {
reloadModel(getPersistentManuallySortedItems());
}
}
/**
*
* @see org.olat.core.gui.control.generic.portal.AbstractPortletRunController#reloadModel(org.olat.core.gui.UserRequest, java.util.List)
*/
protected void reloadModel(List<PortletEntry<UserEfficiencyStatementLight>> sortedItems) {
efficiencyStatementsListModel = new EfficiencyStatementsTableDataModel(sortedItems,2);
tableCtr.setTableDataModel(efficiencyStatementsListModel);
}
/**
* @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 calendar menu item
String resourceUrl = "[HomeSite:" + ureq.getIdentity().getKey() + "][effstatements:0]";
BusinessControl bc = BusinessControlFactory.getInstance().createFromString(resourceUrl);
WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(bc, getWindowControl());
NewControllerFactory.getInstance().launch(ureq, bwControl);
} else if (event == ComponentUtil.VALIDATE_EVENT && needReloadModel) {
reloadModel(sortingCriteria);
}
}
/**
* @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)
*/
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();
final UserEfficiencyStatementLight statement = efficiencyStatementsListModel.getEfficiencyStatementAt(rowid);
// will not be disposed on course run dispose, popus up as new browserwindow
ControllerCreator ctrlCreator = new ControllerCreator() {
public Controller createController(UserRequest lureq, WindowControl lwControl) {
CertificateAndEfficiencyStatementController efficiencyCtrl = new CertificateAndEfficiencyStatementController(lwControl, lureq, statement.getArchivedResourceKey());
return new LayoutMain3ColsController(lureq, getWindowControl(), efficiencyCtrl);
}
};
//wrap the content controller into a full header layout
ControllerCreator layoutCtrlr = BaseFullWebappPopupLayoutFactory.createAuthMinimalPopupLayout(ureq, ctrlCreator);
//open in new browser window
PopupBrowserWindow pbw = getWindowControl().getWindowBackOffice().getWindowManager().createNewPopupBrowserWindowFor(ureq, layoutCtrlr);
pbw.open(ureq);
//
}
}
}
}
/**
* @see org.olat.core.gui.control.DefaultController#doDispose(boolean)
*/
protected void doDispose() {
CourseModule.deregisterForCourseType(this);
super.doDispose();
}
/**
*
* @see org.olat.core.util.event.GenericEventListener#event(org.olat.core.gui.control.Event)
*/
public void event(Event event) {
if (event instanceof AssessmentChangedEvent) {
AssessmentChangedEvent ace = (AssessmentChangedEvent)event;
if (cOwner.getKey().equals(ace.getIdentityKey()) &&
ace.getCommand().equals(AssessmentChangedEvent.TYPE_EFFICIENCY_STATEMENT_CHANGED)) {
needReloadModel = true;
}
}
}
/**
* 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<UserEfficiencyStatementLight> createSortingTool(UserRequest ureq, WindowControl wControl) {
if(portletToolsController==null) {
List<PortletEntry<UserEfficiencyStatementLight>> portletEntryList = getAllPortletEntries();
PortletDefaultTableDataModel<UserEfficiencyStatementLight> tableDataModel = new EfficiencyStatementsManualSortingTableDataModel(portletEntryList, 2);
List<PortletEntry<UserEfficiencyStatementLight>> sortedItems = getPersistentManuallySortedItems();
portletToolsController = new PortletToolSortingControllerImpl<UserEfficiencyStatementLight>(ureq, wControl, getTranslator(), sortingCriteria, tableDataModel, sortedItems);
portletToolsController.setConfigManualSorting(true);
portletToolsController.setConfigAutoSorting(true);
portletToolsController.addControllerListener(this);
}
return portletToolsController;
}
/**
* Retrieves the persistent manually sorted items for the current portlet.
* @param ureq
* @return
*/
private List<PortletEntry<UserEfficiencyStatementLight>> getPersistentManuallySortedItems() {
List<PortletEntry<UserEfficiencyStatementLight>> portletEntryList = getAllPortletEntries();
return this.getPersistentManuallySortedItems(portletEntryList);
}
/**
* Comparator implementation.
* Compares EfficiencyStatements according with the input sortingCriteria.
* <p>
* @param sortingCriteria
* @return a Comparator for the input sortingCriteria
*/
protected Comparator<UserEfficiencyStatementLight> getComparator(final SortingCriteria sortingCriteria) {
return new Comparator<UserEfficiencyStatementLight>(){
public int compare(final UserEfficiencyStatementLight s1, final UserEfficiencyStatementLight s2) {
int comparisonResult = 0;
if(sortingCriteria.getSortingTerm()==SortingCriteria.ALPHABETICAL_SORTING) {
String st1 = s1.getShortTitle();
String st2 = s2.getShortTitle();
if(st2 == null) return -1;
if(st1 == null) return 1;
comparisonResult = collator.compare(st1, st2);
} else if(sortingCriteria.getSortingTerm()==SortingCriteria.DATE_SORTING) {
comparisonResult = s1.getLastModified().compareTo(s2.getLastModified());
}
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 class EfficiencyStatementsTableDataModel extends PortletDefaultTableDataModel<UserEfficiencyStatementLight> {
public EfficiencyStatementsTableDataModel(List<PortletEntry<UserEfficiencyStatementLight>> objects, int numCols) {
super(objects, numCols);
}
public Object getValueAt(int row, int col) {
UserEfficiencyStatementLight efficiencyStatement = getEfficiencyStatementAt(row);
switch (col) {
case 0:
return efficiencyStatement.getShortTitle();
case 1:
Float score = efficiencyStatement.getScore();
return AssessmentHelper.getRoundedScore(score);
case 2:
return efficiencyStatement.getPassed();
default:
return "ERROR";
}
}
public UserEfficiencyStatementLight getEfficiencyStatementAt(int row) {
return getObject(row).getValue();
}
}
/**
*
* PortletDefaultTableDataModel implementation for the manual sorting component.
*
* <P>
* Initial Date: 05.12.2007 <br>
* @author Lavinia Dumitrescu
*/
private class EfficiencyStatementsManualSortingTableDataModel extends PortletDefaultTableDataModel<UserEfficiencyStatementLight> {
/**
* @param objects
* @param locale
*/
public EfficiencyStatementsManualSortingTableDataModel(List<PortletEntry<UserEfficiencyStatementLight>> objects, int numCols) {
super(objects, numCols);
}
/**
* @see org.olat.core.gui.components.table.TableDataModel#getValueAt(int, int)
*/
public final Object getValueAt(int row, int col) {
PortletEntry<UserEfficiencyStatementLight> entry = getObject(row);
UserEfficiencyStatementLight statement = entry.getValue();
switch (col) {
case 0:
return statement.getShortTitle();
case 1:
return statement.getLastModified();
default:
return "error";
}
}
}
/**
*
* PortletEntry implementation for EfficiencyStatement objects.
*
* <P>
* Initial Date: 07.12.2007 <br>
* @author Lavinia Dumitrescu
*/
private class EfficiencyStatementPortletEntry implements PortletEntry<UserEfficiencyStatementLight> {
private UserEfficiencyStatementLight value;
private Long key;
public EfficiencyStatementPortletEntry(UserEfficiencyStatementLight efficiencyStatement) {
value = efficiencyStatement;
key = efficiencyStatement.getCourseRepoKey();
}
public Long getKey() {
return key;
}
public UserEfficiencyStatementLight getValue() {
return value;
}
}
}