/** * <a href="http://www.openolat.org"> * OpenOLAT - Online Learning and Training</a><br> * <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 the * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> * <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> * Initial code contributed and copyrighted by<br> * frentix GmbH, http://www.frentix.com * <p> */ package org.olat.admin.site.ui; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; import org.olat.core.CoreSpringFactory; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItemContainer; import org.olat.core.gui.components.form.flexible.elements.FlexiTableElement; import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement; import org.olat.core.gui.components.form.flexible.elements.SingleSelection; import org.olat.core.gui.components.form.flexible.impl.FormBasicController; import org.olat.core.gui.components.form.flexible.impl.FormEvent; import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiColumnModel; import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiTableDataModel; import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel; import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableDataModelFactory; import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableRendererType; import org.olat.core.gui.components.form.flexible.impl.elements.table.SelectionEvent; import org.olat.core.gui.components.form.flexible.impl.elements.table.StaticFlexiCellRenderer; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.navigation.SiteAlternativeControllerCreator; import org.olat.core.gui.control.navigation.SiteConfiguration; import org.olat.core.gui.control.navigation.SiteDefinition; import org.olat.core.gui.control.navigation.SiteDefinitions; import org.olat.core.gui.control.navigation.SiteSecurityCallback; import org.olat.core.gui.control.navigation.SiteViewSecurityCallback; import org.olat.core.util.StringHelper; /** * Configuration of the list of sites: order, security callback, alternative controllers... * * * Initial date: 18.09.2013<br> * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ public class SitesConfigurationController extends FormBasicController { private final SiteDefinitions sitesModule; private final Map<String,SiteDefinition> siteDefs; private final String[] secKeys; private final String[] secValues; private final String[] altKeys; private final String[] altValues; private SiteDefModel model; private FlexiTableElement tableEl; private FormItemContainer formLayout; private boolean needAlternative = false; private final Map<String,SiteSecurityCallback> securityCallbacks; public SitesConfigurationController(UserRequest ureq, WindowControl wControl) { super(ureq, wControl, "sites_order"); sitesModule = CoreSpringFactory.getImpl(SiteDefinitions.class); siteDefs = sitesModule.getAllSiteDefinitionsList(); securityCallbacks = CoreSpringFactory.getBeansOfType(SiteSecurityCallback.class); //security callbacks secKeys = new String[securityCallbacks.size()]; secValues = new String[securityCallbacks.size()]; int count = 0; for(Map.Entry<String, SiteSecurityCallback> secEntry:securityCallbacks.entrySet()) { secKeys[count] = secEntry.getKey(); String translation = translate(secEntry.getKey()); if(translation.length() < 125) { secValues[count++] = translation; } else { secValues[count++] = secEntry.getKey(); } if(secEntry.getValue() instanceof SiteViewSecurityCallback) { needAlternative = true; } } //alternative controller Map<String,SiteAlternativeControllerCreator> alternativeControllers = CoreSpringFactory.getBeansOfType(SiteAlternativeControllerCreator.class); altKeys = new String[alternativeControllers.size() + 1]; altValues = new String[alternativeControllers.size() + 1]; int countAlt = 0; altKeys[countAlt] = "none"; altValues[countAlt++] = translate("site.alternative.none"); for(Map.Entry<String, SiteAlternativeControllerCreator> altEntry:alternativeControllers.entrySet()) { altKeys[countAlt] = altEntry.getKey(); String translation = translate(altEntry.getKey()); if(translation.length() < 125) { altValues[countAlt++] = translation; } else { altValues[countAlt++] = altEntry.getKey(); } } initForm(ureq); } @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { this.formLayout = formLayout; FlexiTableColumnModel columnsModel = FlexiTableDataModelFactory.createFlexiTableColumnModel(); columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(SiteCols.enabled.i18nKey(), SiteCols.enabled.ordinal())); columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(SiteCols.title.i18nKey(), SiteCols.title.ordinal())); columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(false, SiteCols.type.i18nKey(), SiteCols.type.ordinal(), false, null)); columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(SiteCols.secCallback.i18nKey(), SiteCols.secCallback.ordinal())); if(needAlternative) { columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(SiteCols.altController.i18nKey(), SiteCols.altController.ordinal())); } columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(false, SiteCols.defaultOrder.i18nKey(), SiteCols.defaultOrder.ordinal(), false, null)); columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("up", SiteCols.up.ordinal(), "up", new StaticFlexiCellRenderer("", "up", "o_icon o_icon-lg o_icon_move_up", translate("up")))); columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("down", SiteCols.down.ordinal(), "down", new StaticFlexiCellRenderer("", "down", "o_icon o_icon-lg o_icon_move_down", translate("down")))); model = new SiteDefModel(columnsModel); tableEl = uifactory.addTableElement(getWindowControl(), "sitesTable", model, getTranslator(), formLayout); tableEl.setRendererType(FlexiTableRendererType.classic); tableEl.setCustomizeColumns(true); tableEl.setAndLoadPersistedPreferences(ureq, "sites-admin"); reload(); } @Override protected void doDispose() { // } @Override protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { if(source == tableEl) { if(event instanceof SelectionEvent) { SelectionEvent se = (SelectionEvent)event; if("up".equals(se.getCommand())) { SiteDefRow row = model.getObject(se.getIndex()); moveUp(row); doUpdateOrders(); tableEl.getComponent().setDirty(true); } else if("down".equals(se.getCommand())) { SiteDefRow row = model.getObject(se.getIndex()); moveDown(row); doUpdateOrders(); tableEl.getComponent().setDirty(true); } } } else if(source instanceof SingleSelection) { if(source.getName().startsWith("site.security.") && source.getUserObject() instanceof SiteDefRow) { SiteDefRow row = (SiteDefRow)source.getUserObject(); String selectCallbackId = row.getSecurityCallbackEl().getSelectedKey(); boolean needAlt = (securityCallbacks.containsKey(selectCallbackId) && securityCallbacks.get(selectCallbackId) instanceof SiteViewSecurityCallback); if(row.getAlternativeControllerEl().isVisible() != needAlt) { row.getAlternativeControllerEl().setVisible(needAlt); tableEl.reset(); } } doSaveSettings(); } else if(source instanceof MultipleSelectionElement || source instanceof SingleSelection) { doSaveSettings(); } super.formInnerEvent(ureq, source, event); } @Override protected void formOK(UserRequest ureq) { // } protected void reload() { List<SiteDefRow> configs = new ArrayList<SiteDefRow>(); for(Map.Entry<String, SiteDefinition> entryDef:siteDefs.entrySet()) { String id = entryDef.getKey(); SiteDefinition siteDef = entryDef.getValue(); String title = translate(siteDef.getClass().getSimpleName()); SiteConfiguration config = sitesModule.getConfigurationSite(id); SiteDefRow row = new SiteDefRow(siteDef, config, title, formLayout); configs.add(row); } Collections.sort(configs, new RowOrderComparator()); model.setObjects(configs); } private void moveUp(SiteDefRow row) { List<SiteDefRow> rows = model.getObjects(); int currentIndex = rows.indexOf(row); if(currentIndex > 0) { rows.remove(currentIndex); rows.add(currentIndex - 1, row); } model.setObjects(rows); } private void moveDown(SiteDefRow row) { List<SiteDefRow> rows = model.getObjects(); int currentIndex = rows.indexOf(row); if(currentIndex >= 0 && currentIndex + 1 < rows.size()) { rows.remove(currentIndex); rows.add(currentIndex + 1, row); } model.setObjects(rows); } private void doUpdateOrders() { int count = 0; List<SiteConfiguration> configs = new ArrayList<SiteConfiguration>(); for(SiteDefRow row:model.getObjects()) { SiteConfiguration config = row.getRawConfiguration(false); config.setOrder(count++); configs.add(config); } sitesModule.setSitesConfiguration(configs); } private void doSaveSettings() { int count = 0; List<SiteConfiguration> configs = new ArrayList<SiteConfiguration>(); for(SiteDefRow row:model.getObjects()) { SiteConfiguration config = row.getRawConfiguration(true); config.setOrder(count++); configs.add(config); } sitesModule.setSitesConfiguration(configs); } private enum SiteCols { enabled("site.enabled"), title("site.title"), secCallback("site.security"), altController("site.alternative"), type("site.type"), defaultOrder("site.defaultOrder"), up("up"), down("down"); private final String i18n; private SiteCols(String i18n) { this.i18n = i18n; } public String i18nKey() { return i18n; } } private class SiteDefRow { private final String title; private final SiteDefinition siteDef; private final SingleSelection secCallbackEl, altControllerEl; private final MultipleSelectionElement enableSiteEl; private final SiteConfiguration config; public SiteDefRow(SiteDefinition siteDef, SiteConfiguration config, String title, FormItemContainer formLayout) { this.title = title; this.siteDef = siteDef; this.config = config; String id = config.getId(); secCallbackEl = uifactory.addDropdownSingleselect("site.security." + id, "site.security", formLayout, secKeys, secValues, null); if(siteDef.isFeatureEnabled()) { secCallbackEl.addActionListener(FormEvent.ONCHANGE); } else { secCallbackEl.setEnabled(false); } secCallbackEl.setUserObject(this); boolean needAlt = false; if(StringHelper.containsNonWhitespace(config.getSecurityCallbackBeanId())) { for(String secKey:secKeys) { if(secKey.equals(config.getSecurityCallbackBeanId())) { secCallbackEl.select(secKey, true); needAlt = (securityCallbacks.containsKey(secKey) && securityCallbacks.get(secKey) instanceof SiteViewSecurityCallback); } } } enableSiteEl = uifactory.addCheckboxesHorizontal("site.enable." + id, null, formLayout, new String[]{ "x" }, new String[]{ "" }); if(siteDef.isFeatureEnabled()) { enableSiteEl.addActionListener(FormEvent.ONCHANGE); } else { enableSiteEl.setEnabled(false); } altControllerEl = uifactory.addDropdownSingleselect("site.alternative." + id, "site.alternative", formLayout, altKeys, altValues, null); altControllerEl.addActionListener(FormEvent.ONCHANGE); altControllerEl.setVisible(needAlt); if(StringHelper.containsNonWhitespace(config.getAlternativeControllerBeanId())) { for(String altKey:altKeys) { if(altKey.equals(config.getAlternativeControllerBeanId())) { altControllerEl.select(altKey, true); } } } if("olatsites_admin".equals(id)) { enableSiteEl.setEnabled(false); altControllerEl.setEnabled(false); secCallbackEl.setEnabled(false); } } public boolean isEnabled() { return config.isEnabled(); } public SiteDefinition getSiteDef() { return siteDef; } public SingleSelection getSecurityCallbackEl() { return secCallbackEl; } public SingleSelection getAlternativeControllerEl() { return altControllerEl; } public MultipleSelectionElement getEnabledEl() { return enableSiteEl; } public String getTitle() { return title; } public int getOrder() { return config.getOrder(); } public SiteConfiguration getRawConfiguration(boolean update) { if(update) { config.setEnabled(enableSiteEl.isAtLeastSelected(1)); if(secCallbackEl.isOneSelected()) { config.setSecurityCallbackBeanId(secCallbackEl.getSelectedKey()); } else { config.setSecurityCallbackBeanId(null); } if(altControllerEl.isOneSelected() && !"none".equals(altControllerEl.getSelectedKey())) { config.setAlternativeControllerBeanId(altControllerEl.getSelectedKey()); } else { config.setAlternativeControllerBeanId(null); } } return config; } } private static class RowOrderComparator implements Comparator<SiteDefRow> { @Override public int compare(SiteDefRow s1, SiteDefRow s2) { int o1 = s1.getOrder(); int o2 = s2.getOrder(); return o1 - o2; } } private static class SiteDefModel extends DefaultFlexiTableDataModel<SiteDefRow> { public SiteDefModel(FlexiTableColumnModel columnModel) { super(columnModel); } @Override public SiteDefModel createCopyWithEmptyList() { return new SiteDefModel(getTableColumnModel()); } @Override public Object getValueAt(int row, int col) { SiteDefRow def = getObject(row); switch(SiteCols.values()[col]) { case enabled: { MultipleSelectionElement enableSiteEl = def.getEnabledEl(); if(def.isEnabled()) { enableSiteEl.select("x", true); } return enableSiteEl; } case title: return def.getTitle(); case secCallback: { return def.getSecurityCallbackEl(); } case altController: return def.getAlternativeControllerEl(); case type: { String type = def.getSiteDef().getClass().getSimpleName(); return type; } case defaultOrder: return def.getOrder(); default: return ""; } } } }