CCM NG: Shortcuts settings pane in /ccm/admin/ is now available and works

git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4168 8810af33-2d31-482b-a856-94f89814c4df
pull/2/head
jensp 2016-06-22 12:00:04 +00:00
parent 25166623cf
commit 9b181dc6ab
20 changed files with 630 additions and 489 deletions

View File

@ -22,6 +22,7 @@
<jta-data-source>java:/comp/env/jdbc/libreccm/db</jta-data-source>
<jar-file>lib/ccm-core-7.0.0-SNAPSHOT.jar</jar-file>
<jar-file>lib/ccm-shortcuts-7.0.0-SNAPSHOT.jar</jar-file>
<properties>
<!-- Properties for Hibernate -->

View File

@ -20,7 +20,6 @@ package com.arsdigita.ui.admin.applications;
import com.arsdigita.bebop.ActionLink;
import com.arsdigita.bebop.BoxPanel;
import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.PageState;
@ -40,8 +39,6 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import static com.arsdigita.ui.admin.AdminUiConstants.*;
@ -102,7 +99,14 @@ public class ApplicationsTab extends LayoutPanel {
final ApplicationType appType = appManager.getApplicationTypes()
.get(appTypeKey);
if (appType.singleton()) {
if (appType == null) {
hideAllInstanceForms(state);
hideAllSettingsPanes(state);
hideAppInfo(state);
hideInstances(state);
hideManagementLinks(state);
hideSingletonAppSettings(state);
} else if (appType.singleton()) {
showSingletonAppSettings(state);
} else {
showInstances(state);
@ -219,6 +223,14 @@ public class ApplicationsTab extends LayoutPanel {
page.setVisibleDefault(placeholderSingletonSettings, false);
page.setVisibleDefault(appInfo, false);
settingsPanes.forEach((k, v) -> {
page.setVisibleDefault(v, false);
});
instanceForms.forEach((k, v) -> {
page.setVisibleDefault(v, false);
});
}
protected void showManagementLinks(final PageState state) {
@ -251,7 +263,13 @@ public class ApplicationsTab extends LayoutPanel {
hideAllInstanceForms(state);
hideAllSettingsPanes(state);
placeholderInstances.setVisible(state, false);
placeholderSingletonSettings.setVisible(state, true);
//placeholderSingletonSettings.setVisible(state, true);
final String appType = selectedAppType.getSelectedKey(state);
if (settingsPanes.containsKey(appType)) {
settingsPanes.get(appType).setVisible(state, true);
}
appInfo.setVisible(state, false);
}

View File

@ -18,8 +18,14 @@
*/
package com.arsdigita.ui.admin.applications;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.ParameterSingleSelectionModel;
import com.arsdigita.bebop.Text;
import com.arsdigita.globalization.GlobalizedMessage;
import org.libreccm.web.ApplicationType;
import static com.arsdigita.ui.admin.AdminUiConstants.*;
/**
*
@ -33,13 +39,59 @@ public class DefaultApplicationSettingsPane
final ParameterSingleSelectionModel<String> selectedAppInstance) {
super(selectedAppType, selectedAppInstance);
final Label label = new Label();
label.addPrintListener(e -> {
final PageState state = e.getPageState();
final ApplicationType appType = getSelectedAppType(state);
final GlobalizedMessage message;
if (appType.singleton()) {
message = new GlobalizedMessage(
"ui.admin.applications.settings.singleton.no_setting_for",
ADMIN_BUNDLE,
new String[]{appType.name()});
} else {
message = new GlobalizedMessage(
"ui.admin.applications.settings.instance.no_setting_for",
ADMIN_BUNDLE,
new String[]{appType.name()});
}
final Label target = (Label) e.getTarget();
target.setLabel(message);
});
add(label);
}
@Override
protected void createWidgets() {
add(new Text(""));
// final Label label = new Label();
// label.addPrintListener(e -> {
// final PageState state = e.getPageState();
// final ApplicationType appType = getSelectedAppType(state);
//
// final GlobalizedMessage message;
// if (appType.singleton()) {
// message = new GlobalizedMessage(
// "ui.admin.applications.settings.singleton.no_setting_for",
// ADMIN_BUNDLE,
// new String[]{appType.name()});
// } else {
// message = new GlobalizedMessage(
// "ui.admin.applications.settings.instance.no_setting_for",
// ADMIN_BUNDLE,
// new String[]{appType.name()});
// }
//
// final Label target = (Label) e.getTarget();
// target.setLabel(message);
// });
//
// add(label);
}
}

View File

@ -538,3 +538,5 @@ ui.admin.applications.type.property_sheet.singleton=Singleton?
ui.admin.applications.type.property_sheet.servlet_class=Servlet
ui.admin.applications.type.property_sheet.servlet_path=Servlet path
ui.admin.applications.info.heading=About the application type
ui.admin.applications.settings.singleton.no_setting_for=No settings for application {0} available.
ui.admin.applications.settings.instance.no_setting_for=No settings for instance of application type {0} available.

View File

@ -541,3 +541,5 @@ ui.admin.applications.type.property_sheet.singleton=Singleton?
ui.admin.applications.type.property_sheet.servlet_class=Servlet
ui.admin.applications.type.property_sheet.servlet_path=Servlet-Pfad
ui.admin.applications.info.heading=\u00dcber den Applikationstyp
ui.admin.applications.settings.singleton.no_setting_for=Keine Einstellungen f\u00fcr Applikation {0} verf\u00fcbar.
ui.admin.applications.settings.instance.no_setting_for=Keine Einstellungen f\u00fcr Instanzen des Typs {0} verf\u00fcgbar.

View File

@ -534,3 +534,5 @@ ui.admin.applications.type.property_sheet.singleton=Singleton?
ui.admin.applications.type.property_sheet.servlet_class=Servlet
ui.admin.applications.type.property_sheet.servlet_path=Servlet path
ui.admin.applications.info.heading=About the application type
ui.admin.applications.settings.singleton.no_setting_for=No settings for application {0} available.
ui.admin.applications.settings.instance.no_setting_for=No settings for instance of application type {0} available.

View File

@ -525,3 +525,5 @@ ui.admin.applications.type.property_sheet.singleton=Singleton?
ui.admin.applications.type.property_sheet.servlet_class=Servlet
ui.admin.applications.type.property_sheet.servlet_path=Servlet path
ui.admin.applications.info.heading=About the application type
ui.admin.applications.settings.singleton.no_setting_for=No settings for application {0} available.
ui.admin.applications.settings.instance.no_setting_for=No settings for instance of application type {0} available.

View File

@ -23,6 +23,7 @@ import org.libreccm.security.RequiresPrivilege;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.transaction.Transactional;
/**
* This class provides complex operations on {@link Shortcut} objects like
@ -50,6 +51,7 @@ public class ShortcutManager {
*/
@AuthorizationRequired
@RequiresPrivilege(ShortcutsConstants.SHORTSCUT_MANAGE_PRIVILEGE)
@Transactional(Transactional.TxType.REQUIRED)
public Shortcut createShortcut(final String url, final String redirect) {
if (url == null || url.trim().isEmpty()) {
throw new IllegalArgumentException(

View File

@ -30,6 +30,7 @@ import java.util.Optional;
import javax.enterprise.context.RequestScoped;
import javax.persistence.NoResultException;
import javax.persistence.TypedQuery;
import javax.transaction.Transactional;
/**
*
@ -91,6 +92,7 @@ public class ShortcutRepository extends AbstractEntityRepository<Long, Shortcut>
@Override
@AuthorizationRequired
@RequiresPrivilege(ShortcutsConstants.SHORTSCUT_MANAGE_PRIVILEGE)
@Transactional(Transactional.TxType.REQUIRED)
public void save(final Shortcut shortcut) {
//Cleanup the URL key
shortcut.setUrlKey(cleanUrlKey(shortcut.getUrlKey()));
@ -101,6 +103,7 @@ public class ShortcutRepository extends AbstractEntityRepository<Long, Shortcut>
@Override
@AuthorizationRequired
@RequiresPrivilege(ShortcutsConstants.SHORTSCUT_MANAGE_PRIVILEGE)
@Transactional(Transactional.TxType.REQUIRED)
public void delete(final Shortcut shortcut) {
super.delete(shortcut);
}

View File

@ -26,6 +26,7 @@ import org.libreccm.modules.Module;
import org.libreccm.modules.RequiredModule;
import org.libreccm.modules.ShutdownEvent;
import org.libreccm.modules.UnInstallEvent;
import org.libreccm.shortcuts.ui.ShortcutsSettingsPane;
import org.libreccm.web.ApplicationType;
/**
@ -38,8 +39,9 @@ import org.libreccm.web.ApplicationType;
},
applicationTypes = {
@ApplicationType(name = ShortcutsConstants.SHORTCUTS_APP_TYPE,
descBundle = "org.libreccm.shortcuts.ShortcutsResources",
descBundle = ShortcutsConstants.SHORTCUTS_BUNDLE,
singleton = true,
settingsPane = ShortcutsSettingsPane.class,
creator = ShortcutsApplicationCreator.class)})
public class Shortcuts implements CcmModule {

View File

@ -28,7 +28,10 @@ public final class ShortcutsConstants {
* Name of the shortcuts application type
*/
public static final String SHORTCUTS_APP_TYPE
= "org.libreccm.shortcuts.Shortcuts";
= "org.libreccm.shortcuts.Shortcuts";
public static final String SHORTCUTS_BUNDLE
= "org.libreccm.shortcuts.ShortcutsResources";
/**
* Primary URL of the singleton Shortcuts application instance.
@ -37,4 +40,8 @@ public final class ShortcutsConstants {
public static final String SHORTSCUT_MANAGE_PRIVILEGE = "manage_shortcuts";
private ShortcutsConstants() {
//Nothing
}
}

View File

@ -1,50 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.shortcuts.ui;
import org.apache.log4j.Category;
import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.ParameterSingleSelectionModel;
import com.arsdigita.bebop.SimpleContainer;
import com.arsdigita.bebop.parameters.LongParameter;
public class AdminPanel extends SimpleContainer {
final private ParameterSingleSelectionModel m_shortcut = new ParameterSingleSelectionModel(new LongParameter("ShortcutID"));
private static final Category log = Category.getInstance(AdminPanel.class
.getName());
public AdminPanel() {
add(new ShortcutForm(m_shortcut));
add(new ShortcutsTable(m_shortcut));
}
@Override
public void register(Page p) {
super.register(p);
p.addGlobalStateParam(m_shortcut.getStateParameter());
}
}

View File

@ -0,0 +1,159 @@
/*
* Copyright (C) 2016 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.shortcuts.ui;
import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.FormData;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.ParameterSingleSelectionModel;
import com.arsdigita.bebop.SaveCancelSection;
import com.arsdigita.bebop.form.TextField;
import com.arsdigita.globalization.GlobalizedMessage;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.shortcuts.Shortcut;
import org.libreccm.shortcuts.ShortcutManager;
import org.libreccm.shortcuts.ShortcutRepository;
import org.libreccm.shortcuts.ShortcutsConstants;
import java.util.Locale;
import java.util.regex.Pattern;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class ShortcutForm extends Form {
private static final String URL_KEY = "urlKey";
private static final String REDIRECT = "redirect";
private final TextField urlKeyField;
private final TextField redirectField;
private final SaveCancelSection saveCancelSection;
public ShortcutForm(
final ShortcutsSettingsPane shortcutsPane,
final ParameterSingleSelectionModel<String> selectedShortcut) {
super("shortcutForm");
urlKeyField = new TextField(URL_KEY);
urlKeyField.setLabel(new GlobalizedMessage(
"shortcuts.ui.admin.url_key.label",
ShortcutsConstants.SHORTCUTS_BUNDLE));
add(urlKeyField);
redirectField = new TextField(REDIRECT);
redirectField.setLabel(new GlobalizedMessage(
"shortcuts.ui.admin.redirect.label",
ShortcutsConstants.SHORTCUTS_BUNDLE));
add(redirectField);
saveCancelSection = new SaveCancelSection();
add(saveCancelSection);
addValidationListener(e -> {
final PageState state = e.getPageState();
final FormData data = e.getFormData();
final String urlKey = data.getString(URL_KEY);
if (urlKey == null || urlKey.trim().isEmpty()) {
data.addError(URL_KEY, new GlobalizedMessage(
"shortcuts.ui.admin.url_key.error.not_empty",
ShortcutsConstants.SHORTCUTS_BUNDLE));
return;
}
// The URL to redirect must start with a '/' and end with a '/'.
// Between the starting and the ending '/' only the characters
// 'a' to 'z', 'A' to 'Z', '0' to '9', '_', '-' and '.' may appear.
if (!Pattern.matches("^/[-a-zA-Z0-9_./]+/$", urlKey)) {
data.addError(URL_KEY, new GlobalizedMessage(
"shortcuts.ui.admin.url_key.error.invalid",
ShortcutsConstants.SHORTCUTS_BUNDLE));
return;
}
if (data.getString(REDIRECT) == null
|| data.getString(REDIRECT).trim().isEmpty()) {
data.addError(URL_KEY, new GlobalizedMessage(
"shortcuts.ui.admin.redirect.not_empty",
ShortcutsConstants.SHORTCUTS_BUNDLE));
return;
}
final String redirect = data.getString(REDIRECT).toLowerCase(
Locale.ROOT);
if (!redirect.startsWith("http://")
&& !redirect.startsWith("https://")
&& !redirect.startsWith("/")) {
data.addError(URL_KEY, new GlobalizedMessage(
"shortcuts.ui.admin.redirect.error.invalid",
ShortcutsConstants.SHORTCUTS_BUNDLE));
}
});
addInitListener(e -> {
final PageState state = e.getPageState();
final FormData data = e.getFormData();
if (selectedShortcut.isSelected(state)) {
final ShortcutRepository repo = CdiUtil.createCdiUtil()
.findBean(ShortcutRepository.class);
final Shortcut shortcut = repo.findById(Long.parseLong(
selectedShortcut.getSelectedKey(state)));
urlKeyField.setValue(state, shortcut.getUrlKey());
redirectField.setValue(state, shortcut.getRedirect());
}
});
addProcessListener(e -> {
final PageState state = e.getPageState();
final FormData data = e.getFormData();
if (saveCancelSection.getSaveButton().isSelected(state)) {
final Shortcut shortcut;
if (selectedShortcut.isSelected(state)) {
final ShortcutRepository repo = CdiUtil.createCdiUtil()
.findBean(ShortcutRepository.class);
shortcut = repo.findById(Long.parseLong(selectedShortcut
.getSelectedKey(state)));
shortcut.setUrlKey(data.getString(URL_KEY));
shortcut.setRedirect(data.getString(REDIRECT));
repo.save(shortcut);
} else {
final ShortcutManager shortcutManager = CdiUtil
.createCdiUtil().findBean(ShortcutManager.class);
shortcutManager.createShortcut(data.getString(URL_KEY),
data.getString(REDIRECT));
}
}
selectedShortcut.clearSelection(state);
shortcutsPane.showShortcutsTable(state);
});
}
}

View File

@ -1,256 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.shortcuts.ui;
import java.math.BigDecimal;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.event.FormProcessListener;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.event.FormValidationListener;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.event.FormInitListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.event.ParameterListener;
import com.arsdigita.bebop.event.ParameterEvent;
import com.arsdigita.bebop.form.Submit;
import com.arsdigita.bebop.form.TextField;
import com.arsdigita.bebop.parameters.ParameterData;
import com.arsdigita.bebop.parameters.TrimmedStringParameter;
import com.arsdigita.bebop.parameters.NotEmptyValidationListener;
import com.arsdigita.bebop.util.GlobalizationUtil;
import org.libreccm.shortcuts.ShortcutManager;
import com.arsdigita.bebop.ParameterSingleSelectionModel;
import org.libreccm.shortcuts.Shortcut;
import org.libreccm.shortcuts.ShortcutRepository;
import com.arsdigita.util.UncheckedWrapperException;
import org.apache.log4j.Category;
import org.apache.oro.text.perl.Perl5Util;
import org.apache.oro.text.perl.MalformedPerl5PatternException;
import org.libreccm.cdi.utils.CdiUtil;
public class ShortcutForm extends Form {
private static final Category log = Category.getInstance(ShortcutForm.class
.getName());
private ParameterSingleSelectionModel m_selected_shortcut;
private TextField m_url;
private TextField m_redirect;
private final Submit m_submit;
public ShortcutForm(ParameterSingleSelectionModel selected_shortcut) {
super("ShortcutForm");
m_selected_shortcut = selected_shortcut;
TrimmedStringParameter urlKeyParameter = new TrimmedStringParameter(
"url");
urlKeyParameter.addParameterListener(new NotEmptyValidationListener());
m_url = new TextField(urlKeyParameter);
TrimmedStringParameter redirectParameter = new TrimmedStringParameter(
"redirect");
redirectParameter
.addParameterListener(new NotEmptyValidationListener());
m_redirect = new TextField(redirectParameter);
urlKeyParameter.addParameterListener(new ParameterListener() {
@Override
public void validate(ParameterEvent e) throws FormProcessException {
ParameterData data = e.getParameterData();
String key = (String) data.getValue();
if (key == null) {
return; // Something else will handle this
}
Perl5Util perl = new Perl5Util();
try {
if (!perl.match("/^(\\/[-a-zA-Z0-9_.]+)+\\/?$/", key)) {
data.addError(GlobalizationUtil.globalize(
"shortcuts.ui.invalid_key_descr"));
throw new FormProcessException(
"Invalid key",
GlobalizationUtil.globalize(
"shortcuts.ui.invalid_key")
);
}
} catch (MalformedPerl5PatternException ex) {
throw new UncheckedWrapperException("bad regex", ex);
}
}
});
redirectParameter.addParameterListener(new ParameterListener() {
@Override
public void validate(ParameterEvent e) throws FormProcessException {
ParameterData data = e.getParameterData();
String url = (String) data.getValue();
if (url == null) {
return; // Something else will handle this
}
url = url.toLowerCase();
// Absolute local url is ok
if (url.startsWith("/")) {
return;
}
// Fully qualified url is ok
if (url.startsWith("http://")) {
return;
}
// And secure ones too
if (url.startsWith("https://")) {
return;
}
data
.addError("You must enter an absolute path "
+ "(starting with '/') or a fully "
+ "qualified URL (starting with 'http://' or 'https://')");
throw new FormProcessException(GlobalizationUtil.globalize(
"shortcuts.ui.invalid_key"));
}
});
add(new Label("URL Key:"));
add(m_url);
add(new Label("Redirect:"));
add(m_redirect);
m_submit = new Submit("Save Shortcut");
add(m_submit);
addInitListener(new ShortcutInitListener());
addProcessListener(new ShortcutFormProcessListener());
addValidationListener(new ShortcutFormValidationListener());
}
private class ShortcutInitListener implements FormInitListener {
@Override
public void init(FormSectionEvent ev) throws FormProcessException {
final PageState state = ev.getPageState();
final ShortcutRepository shortcutsRepo = CdiUtil.createCdiUtil()
.findBean(ShortcutRepository.class);
Long shortcutKey = (Long) m_selected_shortcut
.getSelectedKey(state);
if (shortcutKey == null) {
log.debug("init form for empty shortcut");
m_url.setValue(state, null);
m_redirect.setValue(state, null);
} else {
log.debug("init form for shortcut " + shortcutKey);
// Shortcut shortcut = new Shortcut(shortcutKey);
Shortcut shortcut = shortcutsRepo.findById(shortcutKey);
m_url.setValue(state, shortcut.getUrlKey());
m_redirect.setValue(state, shortcut.getRedirect());
}
}
}
private class ShortcutFormValidationListener implements
FormValidationListener {
@Override
public void validate(FormSectionEvent e) throws FormProcessException {
PageState state = e.getPageState();
ShortcutManager shortcutMgr = new ShortcutManager();
// get currently edited shortcut
Long shortcutKey = (Long) m_selected_shortcut
.getSelectedKey(state);
//TODO: maybe adjust url. see com-arsdigita.shortcuts.ShortcutUtil.cleanURLKey()
String key = (String) m_url.getValue(state);
if (shortcutKey == null) {
String target = shortcutMgr.findByUrlKey(key).getUrlKey();
if (target != null) {
m_url.addError(GlobalizationUtil.globalize(
"shortcuts.ui.key_already_exists"));
throw new FormProcessException(
"duplicate key",
GlobalizationUtil
.globalize("shortcuts.ui.duplicate_key")
);
}
}
int index = key.indexOf("/", 2);
String base = key.substring(0, index + 1);
}
}
private class ShortcutFormProcessListener implements FormProcessListener {
@Override
public void process(FormSectionEvent e) throws FormProcessException {
ShortcutManager shortcutMgr = new ShortcutManager();
PageState state = e.getPageState();
final ShortcutRepository shortcutsRepo = CdiUtil.createCdiUtil()
.findBean(ShortcutRepository.class);
Long shortcutKey = (Long) m_selected_shortcut.getSelectedKey(state);
// String url = ShortcutUtil.cleanURLKey((String) m_url.getValue(state));
String url = (String) m_url.getValue(state);
String redirect = (String) m_redirect.getValue(state);
if (shortcutKey == null) {
log.info("save new shortcut " + url);
Shortcut shortcut = shortcutMgr.createShortcut(url, redirect);
shortcutsRepo.save(shortcut);
} else {
log.info("save updated shortcut " + shortcutKey + " " + url);
Shortcut shortcut = shortcutsRepo.findById(shortcutKey);
shortcut.setUrlKey(url);
shortcut.setRedirect(redirect);
shortcutsRepo.save(shortcut);
}
// ShortcutUtil.repopulateShortcuts();
m_redirect.setValue(state, "");
m_url.setValue(state, "");
m_selected_shortcut.clearSelection(state);
}
}
}

View File

@ -0,0 +1,107 @@
/*
* Copyright (C) 2016 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.shortcuts.ui;
import com.arsdigita.bebop.ActionLink;
import com.arsdigita.bebop.BoxPanel;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.ParameterSingleSelectionModel;
import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.ui.admin.applications.AbstractAppSettingsPane;
import org.libreccm.shortcuts.ShortcutsConstants;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class ShortcutsSettingsPane extends AbstractAppSettingsPane {
private final StringParameter selectedShortcutParam;
private final ParameterSingleSelectionModel<String> selectedShortcut;
private final ShortcutsTable shortcutsTable;
private final ActionLink addShortcutLink;
private final ShortcutForm shortcutForm;
public ShortcutsSettingsPane(
final ParameterSingleSelectionModel<String> selectedAppType,
final ParameterSingleSelectionModel<String> selectedAppInstance) {
super(selectedAppType, selectedAppInstance);
selectedShortcutParam = new StringParameter("selectedShortcut");
selectedShortcut = new ParameterSingleSelectionModel<>(
selectedShortcutParam);
final BoxPanel panel = new BoxPanel(BoxPanel.VERTICAL);
final Label heading = new Label(new GlobalizedMessage(
"shortcuts.ui.admin.heading", ShortcutsConstants.SHORTCUTS_BUNDLE));
heading.setClassAttr("heading");
panel.add(heading);
shortcutsTable = new ShortcutsTable(this, selectedShortcut);
panel.add(shortcutsTable);
shortcutForm = new ShortcutForm(this, selectedShortcut);
panel.add(shortcutForm);
addShortcutLink = new ActionLink(new GlobalizedMessage(
"shortcuts.ui.admin.add_shortcut",
ShortcutsConstants.SHORTCUTS_BUNDLE));
addShortcutLink.addActionListener(e -> {
showShortcutForm(e.getPageState());
});
panel.add(addShortcutLink);
add(panel);
}
@Override
protected void createWidgets() {
}
@Override
public void register(final Page page) {
super.register(page);
page.addGlobalStateParam(selectedShortcutParam);
page.setVisibleDefault(shortcutsTable, true);
page.setVisibleDefault(shortcutForm, false);
page.setVisibleDefault(addShortcutLink, true);
}
void showShortcutForm(final PageState state) {
shortcutsTable.setVisible(state, false);
shortcutForm.setVisible(state, true);
addShortcutLink.setVisible(state, false);
}
void showShortcutsTable(final PageState state) {
shortcutsTable.setVisible(state, true);
shortcutForm.setVisible(state, false);
addShortcutLink.setVisible(state, true);
}
}

View File

@ -0,0 +1,224 @@
/*
* Copyright (C) 2016 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.shortcuts.ui;
import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.ControlLink;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.ParameterSingleSelectionModel;
import com.arsdigita.bebop.Table;
import com.arsdigita.bebop.event.TableActionEvent;
import com.arsdigita.bebop.event.TableActionListener;
import com.arsdigita.bebop.table.TableCellRenderer;
import com.arsdigita.bebop.table.TableColumn;
import com.arsdigita.bebop.table.TableColumnModel;
import com.arsdigita.bebop.table.TableModel;
import com.arsdigita.bebop.table.TableModelBuilder;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.util.LockableImpl;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.shortcuts.Shortcut;
import org.libreccm.shortcuts.ShortcutRepository;
import org.libreccm.shortcuts.ShortcutsConstants;
import java.util.List;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class ShortcutsTable extends Table {
private static final int COL_URL_KEY = 0;
private static final int COL_REDIRECT = 1;
private static final int COL_EDIT = 2;
private static final int COL_DELETE = 3;
private final ShortcutsSettingsPane shortcutsPane;
public ShortcutsTable(
final ShortcutsSettingsPane shortcutsPane,
final ParameterSingleSelectionModel<String> selectedShortcut) {
super();
this.shortcutsPane = shortcutsPane;
final TableColumnModel columnModel = getColumnModel();
columnModel.add(new TableColumn(
COL_URL_KEY,
new Label(new GlobalizedMessage(
"shortcuts.ui.admin.shortcuts_table.col_url_key.header",
ShortcutsConstants.SHORTCUTS_BUNDLE))
));
columnModel.add(new TableColumn(
COL_REDIRECT,
new Label(new GlobalizedMessage(
"shortcuts.ui.admin.shortcuts_table.col_redirect.header",
ShortcutsConstants.SHORTCUTS_BUNDLE))
));
columnModel.add(new TableColumn(
COL_EDIT,
new Label(new GlobalizedMessage(
"shortcuts.ui.admin.shortcuts_table.col_edit.header",
ShortcutsConstants.SHORTCUTS_BUNDLE))
));
columnModel.add(new TableColumn(
COL_DELETE,
new Label(new GlobalizedMessage(
"shortcuts.ui.admin.shortcuts_table.col_delete.header",
ShortcutsConstants.SHORTCUTS_BUNDLE))
));
columnModel.get(COL_EDIT).setCellRenderer(new TableCellRenderer() {
@Override
public Component getComponent(final Table table,
final PageState state,
final Object value,
final boolean isSelected,
final Object key,
final int row,
final int column) {
return new ControlLink((Component) value);
}
});
columnModel.get(COL_DELETE).setCellRenderer(new TableCellRenderer() {
@Override
public Component getComponent(final Table table,
final PageState state,
final Object value,
final boolean isSelected,
final Object key,
final int row,
final int column) {
return new ControlLink((Component) value);
}
});
addTableActionListener(new TableActionListener() {
@Override
public void cellSelected(final TableActionEvent event) {
final PageState state = event.getPageState();
switch (event.getColumn()) {
case COL_EDIT:
selectedShortcut.setSelectedKey(state,
event.getRowKey());
shortcutsPane.showShortcutForm(state);
break;
case COL_DELETE: {
final ShortcutRepository repo = CdiUtil.createCdiUtil()
.findBean(ShortcutRepository.class);
final Shortcut shortcut = repo.findById(Long.parseLong(
(String) event.getRowKey()));
repo.delete(shortcut);
break;
}
}
}
@Override
public void headSelected(final TableActionEvent event) {
//nothing
}
});
setModelBuilder(new ShortcutsTableModelBuilder());
setEmptyView(new Label(new GlobalizedMessage(
"shortcuts.ui.admin.table.empty",
ShortcutsConstants.SHORTCUTS_BUNDLE)));
}
private class ShortcutsTableModelBuilder extends LockableImpl implements
TableModelBuilder {
@Override
public TableModel makeModel(final Table table, final PageState state) {
return new ShortcutsTableModel();
}
}
private class ShortcutsTableModel implements TableModel {
private final List<Shortcut> shortcuts;
private int index = -1;
public ShortcutsTableModel() {
final ShortcutRepository repo = CdiUtil.createCdiUtil().findBean(
ShortcutRepository.class);
shortcuts = repo.findAll();
shortcuts.sort((s1, s2) -> {
return s1.getUrlKey().compareTo(s2.getUrlKey());
});
}
@Override
public int getColumnCount() {
return 4;
}
@Override
public boolean nextRow() {
index++;
return index < shortcuts.size();
}
@Override
public Object getElementAt(final int columnIndex) {
final Shortcut shortcut = shortcuts.get(index);
switch (columnIndex) {
case COL_URL_KEY:
return shortcut.getUrlKey();
case COL_REDIRECT:
return shortcut.getRedirect();
case COL_EDIT:
return new Label(new GlobalizedMessage(
"shortcuts.ui.admin.shortcuts_table.edit",
ShortcutsConstants.SHORTCUTS_BUNDLE));
case COL_DELETE:
return new Label(new GlobalizedMessage(
"shortcuts.ui.admin.shortcuts_table.delete",
ShortcutsConstants.SHORTCUTS_BUNDLE));
default:
throw new IllegalArgumentException(
"Not a valid column index");
}
}
@Override
public Object getKeyAt(final int columnIndex) {
return Long.toString(shortcuts.get(index).getShortcutId());
}
}
}

View File

@ -1,166 +0,0 @@
/*
* Copyright (C) 2015 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package org.libreccm.shortcuts.ui;
import com.arsdigita.bebop.Table;
import com.arsdigita.bebop.table.TableModelBuilder;
import com.arsdigita.util.LockableImpl;
import com.arsdigita.bebop.table.TableModel;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.ParameterSingleSelectionModel;
import org.libreccm.shortcuts.Shortcut;
//import com.arsdigita.shortcuts.ShortcutCollection;
import java.math.BigDecimal;
import org.apache.log4j.Category;
import com.arsdigita.bebop.event.TableActionListener;
import com.arsdigita.bebop.table.TableCellRenderer;
import com.arsdigita.bebop.event.TableActionEvent;
import com.arsdigita.bebop.ControlLink;
import com.arsdigita.util.UncheckedWrapperException;
import com.arsdigita.bebop.Component;
import java.util.List;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.shortcuts.ShortcutRepository;
/**
*
*
*/
public class ShortcutsTable extends Table {
private static final Category log
= Category.getInstance(
ShortcutsTable.class.getName());
public static final String headers[] = {"URL Key", "Redirect", "", ""};
public ShortcutsTable(final ParameterSingleSelectionModel selected_shortcut) {
super(new ShortcutsModelBuilder(), headers);
setDefaultCellRenderer(new ShortcutsCellRenderer());
final ShortcutRepository shortcutsRepo = CdiUtil.createCdiUtil()
.findBean(ShortcutRepository.class);
addTableActionListener(new TableActionListener() {
public void cellSelected(TableActionEvent e) {
selected_shortcut.clearSelection(e.getPageState());
String row = (String) e.getRowKey();
if (e.getColumn().intValue() == 2) {
// edit selected
log.debug("selected edit shortcut " + row);
selected_shortcut.setSelectedKey(e.getPageState(),
new BigDecimal(row));
} else if (e.getColumn().intValue() == 3) {
// delete selected
log.fatal("selected delete shortcut " + row);
Shortcut shortcut = shortcutsRepo.findById(
(Long) selected_shortcut
.getSelectedKey(e.getPageState()));
if (shortcut != null) {
log.info("delete shortcut " + shortcut.getUrlKey());
shortcutsRepo.delete(shortcut);
}
}
}
public void headSelected(TableActionEvent e) {
}
});
}
protected static class ShortcutsModelBuilder extends LockableImpl implements
TableModelBuilder {
public TableModel makeModel(Table table, PageState ps) {
return new ShortcutsModel();
}
protected class ShortcutsModel implements TableModel {
private ShortcutRepository shortcutRepo = new ShortcutRepository();
private List<Shortcut> m_shortcuts = null;
private int index = 0;
private Shortcut m_shortcut;
public ShortcutsModel() {
// m_shortcuts = Shortcut.retrieveAll();
m_shortcuts = shortcutRepo.findAll();
}
public int getColumnCount() {
return headers.length;
}
public boolean nextRow() {
if (index < m_shortcuts.size()) {
index++;
m_shortcut = m_shortcuts.get(index);
return true;
} else {
return false;
}
}
public Object getElementAt(int col) {
return m_shortcut;
}
public Long getKeyAt(int col) {
Long id = m_shortcut.getShortcutId();
return id;
}
}
}
protected static class ShortcutsCellRenderer implements TableCellRenderer {
public Component getComponent(Table table, PageState state,
Object value, boolean isSelected,
Object key, int row,
int column) {
Shortcut shortcut = (Shortcut) value;
switch (column) {
// case 0:
// return new ExternalLink(shortcut.getUrlKey(), shortcut
// .getUrlKey());
// case 1:
// return new ExternalLink(shortcut.getRedirect(), shortcut
// .getRedirect());
case 2:
return new ControlLink(" edit ");
case 3:
return new ControlLink(" delete ");
default:
throw new UncheckedWrapperException("Column out of bounds");
}
}
}
}

View File

@ -17,3 +17,18 @@
application_title=Shortcuts
application_desc=Manage short URLs for internal and external redirects.
shortcuts.ui.admin.shortcuts_table.col_url_key.header=URL
shortcuts.ui.admin.shortcuts_table.col_redirect.header=Redirect
shortcuts.ui.admin.shortcuts_table.col_edit.header=Edit
shortcuts.ui.admin.shortcuts_table.col_delete.header=Delete
shortcuts.ui.admin.shortcuts_table.edit=Edit
shortcuts.ui.admin.shortcuts_table.delete=Delete
shortcuts.ui.admin.url_key.label=URL
shortcuts.ui.admin.redirect.label=Redirect
shortcuts.ui.admin.url_key.error.not_empty=The URL to redirect can't be empty.
shortcuts.ui.admin.url_key.error.invalid=The URL to redirect is not a valid URL.
shortcuts.ui.admin.redirect.not_empty=The target of the redirect can't be empty.
shortcuts.ui.admin.redirect.error.invalid=The target of the redirect must be a absolute URL.
shortcuts.ui.admin.heading=Manage shortcuts
shortcuts.ui.admin.table.empty=No shortcuts definied yet
shortcuts.ui.admin.add_shortcut=Add shortcut

View File

@ -17,3 +17,18 @@
application_title=Shortcuts
application_desc=Manage short URLs for internal and external redirects.
shortcuts.ui.admin.shortcuts_table.col_url_key.header=URL
shortcuts.ui.admin.shortcuts_table.col_redirect.header=Weiterleitung
shortcuts.ui.admin.shortcuts_table.col_edit.header=Bearbeiten
shortcuts.ui.admin.shortcuts_table.col_delete.header=L\u00f6schen
shortcuts.ui.admin.shortcuts_table.edit=Bearbeiten
shortcuts.ui.admin.shortcuts_table.delete=L\u00f6schen
shortcuts.ui.admin.url_key.label=URL
shortcuts.ui.admin.redirect.label=Weiterleitung
shortcuts.ui.admin.url_key.error.not_empty=Die weiterzuleitende URL darf nicht leer sein.
shortcuts.ui.admin.url_key.error.invalid=Die weiterzuleitende URL ist keine valide URL.
shortcuts.ui.admin.redirect.not_empty=Das Ziel der Weiterleitung darf nicht leer sein.
shortcuts.ui.admin.redirect.error.invalid=Das Ziel der Weiterleitung muss eine absolute URL sein.
shortcuts.ui.admin.heading=Shortcuts verwalten
shortcuts.ui.admin.table.empty=Es wurden noch keine Shortcuts angelegt.
shortcuts.ui.admin.add_shortcut=Shortcut hinzuf\u00fcgen