CCM NG: finished shortcuts

git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@3712 8810af33-2d31-482b-a856-94f89814c4df
pull/2/head
konermann 2015-10-28 08:56:41 +00:00
parent b7fdccf1a1
commit 3343a0024a
4 changed files with 514 additions and 0 deletions

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2013 Jens Pelzetter
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package org.libreccm.shortcuts;
import org.libreccm.shortcuts.ui.AdminPanel;
import com.arsdigita.ui.admin.applications.AbstractSingletonApplicationManager;
import com.arsdigita.ui.admin.applications.ApplicationInstanceAwareContainer;
/**
*
* @author Jens Pelzetter <jens@jp-digital.de>
* @version $Id$
*/
public class ShortcutsAppManager extends AbstractSingletonApplicationManager<Shortcuts>{
public Class<Shortcuts> getApplication() {
return Shortcuts.class;
}
public ApplicationInstanceAwareContainer getApplicationAdminForm() {
final ApplicationInstanceAwareContainer container = new ApplicationInstanceAwareContainer();
container.add(new AdminPanel());
return container;
}
}

View File

@ -0,0 +1,50 @@
/*
* 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,257 @@
/*
* 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.CdiLookupException;
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 CdiUtil cdiUtil = new CdiUtil();
final ShortcutRepository shortcutsRepo;
try {
shortcutsRepo = cdiUtil.findBean(ShortcutRepository.class);
} catch (CdiLookupException ex) {
throw new UncheckedWrapperException(ex);
}
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 CdiUtil cdiUtil = new CdiUtil();
final ShortcutRepository shortcutsRepo;
try {
shortcutsRepo = cdiUtil.findBean(ShortcutRepository.class);
} catch (CdiLookupException ex) {
throw new UncheckedWrapperException(ex);
}
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,162 @@
/*
* 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.CdiLookupException;
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 CdiUtil cdiUtil = new CdiUtil();
final ShortcutRepository shortcutsRepo;
try {
shortcutsRepo = cdiUtil.findBean(ShortcutRepository.class);
} catch (CdiLookupException ex) {
throw new UncheckedWrapperException(ex);
}
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");
}
}
}
}