diff --git a/ccm-core/src/main/java/com/arsdigita/toolbox/ui/AbstractDataQueryBuilder.java.todo b/ccm-core/src/main/java/com/arsdigita/toolbox/ui/AbstractDataQueryBuilder.java.todo
deleted file mode 100644
index c2279b2aa..000000000
--- a/ccm-core/src/main/java/com/arsdigita/toolbox/ui/AbstractDataQueryBuilder.java.todo
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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 com.arsdigita.toolbox.ui;
-
-import org.libreccm.cdi.utils.CdiUtil;
-
-import javax.persistence.criteria.CriteriaQuery;
-
-/**
- *
- * @author Jens Pelzetter
- * @param Type of entity retrieved by the query.
- */
-public abstract class AbstractDataQueryBuilder implements DataQueryBuilder {
-
- /**
- * Retrieves the {@link DataTableController} can creates a new
- * {@code CriteriaQuery} using
- * {@link DataTableController#createQuery(java.lang.Class)}.
- *
- * @param entityClass
- *
- * @return A new {@link CriteriaQuery} which can be further customised.
- */
- protected CriteriaQuery createBaseQuery(final Class entityClass) {
- final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
- final DataTableController controller = cdiUtil.findBean(
- DataTableController.class);
-
- return controller.createQuery(entityClass);
- }
-
-}
diff --git a/ccm-core/src/main/java/com/arsdigita/toolbox/ui/ActionGroup.java b/ccm-core/src/main/java/com/arsdigita/toolbox/ui/ActionGroup.java
deleted file mode 100755
index 6db08359e..000000000
--- a/ccm-core/src/main/java/com/arsdigita/toolbox/ui/ActionGroup.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
- *
- * 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 com.arsdigita.toolbox.ui;
-
-import com.arsdigita.bebop.Component;
-import com.arsdigita.bebop.PageState;
-import com.arsdigita.util.Assert;
-import com.arsdigita.xml.Element;
-import java.util.Iterator;
-import java.util.ArrayList;
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.LogManager;
-
-/**
- * A simple layout panel with top, bottom, left, right, and body sections.
- *
- * @author Justin Ross <jross@redhat.com>
- */
-public class ActionGroup extends ComponentSet {
-
- private static final Logger LOGGER = LogManager.getLogger(ActionGroup.class);
-
- private Component m_subject;
- private final ArrayList m_actions = new ArrayList();
-
- public static final String ADD = "add";
- public static final String EDIT = "edit";
- public static final String DELETE = "delete";
- public static final String RETURN = "return";
-
- public final void setSubject(final Component subject) {
- Assert.exists(subject, "Component subject");
- Assert.isUnlocked(this);
-
- m_subject = subject;
- add(m_subject);
- }
-
- public final void addAction(final Component action, final String clacc) {
- Assert.exists(action, "Component action");
- Assert.isUnlocked(this);
-
- m_actions.add(new Object[]{action, clacc});
- add(action);
- }
-
- public final void addAction(final Component action) {
- addAction(action, null);
- }
-
- public final void generateXML(final PageState state, final Element parent) {
- if (isVisible(state)) {
- final Element layout = parent.newChildElement("bebop:actionGroup",
- BEBOP_XML_NS);
-
- final Element subject = layout.newChildElement("bebop:subject",
- BEBOP_XML_NS);
-
- if (m_subject != null) {
- m_subject.generateXML(state, subject);
- }
-
- for (Iterator iter = m_actions.iterator(); iter.hasNext();) {
- final Object[] spec = (Object[]) iter.next();
- final Component component = (Component) spec[0];
- final String clacc = (String) spec[1];
-
- if (component.isVisible(state)) {
- final Element action = layout
- .newChildElement("bebop:action", BEBOP_XML_NS);
-
- if (clacc != null) {
- action.addAttribute("class", clacc);
- }
-
- component.generateXML(state, action);
- }
- }
- }
- }
-
-}
diff --git a/ccm-core/src/main/java/com/arsdigita/toolbox/ui/Cancellable.java b/ccm-core/src/main/java/com/arsdigita/toolbox/ui/Cancellable.java
deleted file mode 100755
index c0084988e..000000000
--- a/ccm-core/src/main/java/com/arsdigita/toolbox/ui/Cancellable.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
- *
- * 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 com.arsdigita.toolbox.ui;
-
-import com.arsdigita.bebop.PageState;
-
-public interface Cancellable {
-
- public boolean isCancelled(final PageState state);
-}
diff --git a/ccm-core/src/main/java/com/arsdigita/toolbox/ui/ComponentAccess.java b/ccm-core/src/main/java/com/arsdigita/toolbox/ui/ComponentAccess.java
deleted file mode 100755
index 8f3cd76c2..000000000
--- a/ccm-core/src/main/java/com/arsdigita/toolbox/ui/ComponentAccess.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
- *
- * 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 com.arsdigita.toolbox.ui;
-
-import com.arsdigita.bebop.Component;
-import com.arsdigita.bebop.PageState;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-
-import org.libreccm.cdi.utils.CdiUtil;
-
-import org.libreccm.security.PermissionChecker;
-
-import java.util.Collections;
-
-/**
- *
- * Wrapper class that registers access checks (actions) to a Bebop
- * component.
- *
- * @author Michael Pih
- * @author Jens Pelzetter
- */
-public class ComponentAccess {
-
- private Component component;
- private List accessCheckList;
-
- /**
- * @param component The component
- */
- public ComponentAccess(final Component component) {
- accessCheckList = new ArrayList<>();
- this.component = component;
- }
-
- /**
- * @param component The component
- * @param check An access check
- */
- public ComponentAccess(final Component component, final String check) {
- this(component);
- accessCheckList.add(check);
- }
-
- /**
- * Add an access check to this component.
- *
- * @param check The access check
- */
- public void addAccessCheck(final String check) {
- accessCheckList.add(check);
- }
-
- /**
- * Get the access checks.
- *
- * @return The list of access checks
- */
- public List getAccessCheckList() {
- return Collections.unmodifiableList(accessCheckList);
- }
-
- /**
- * Get the component.
- *
- * @return The component
- */
- public Component getComponent() {
- return component;
- }
-
- /**
- * Do all the access checks registered to the component pass?
- *
- * @return true if all the access checks pass, false otherwise
- */
- public boolean canAccess() {
- final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
- final PermissionChecker permissionChecker = cdiUtil.findBean(
- PermissionChecker.class);
-
- if (accessCheckList.isEmpty()) {
- return true;
- }
-
- final Optional canAccess = accessCheckList.stream()
- .map(accessCheck -> permissionChecker.isPermitted(accessCheck))
- .reduce((result1, result2) -> result1 && result2);
-
- return canAccess.orElse(false);
- }
-
- public boolean canAccess(final PageState state) {
- return canAccess();
- }
-
-}
diff --git a/ccm-core/src/main/java/com/arsdigita/toolbox/ui/ComponentMap.java b/ccm-core/src/main/java/com/arsdigita/toolbox/ui/ComponentMap.java
deleted file mode 100644
index e3a9f5f07..000000000
--- a/ccm-core/src/main/java/com/arsdigita/toolbox/ui/ComponentMap.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
- *
- * 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 com.arsdigita.toolbox.ui;
-
-import com.arsdigita.bebop.Component;
-import com.arsdigita.bebop.PageState;
-import com.arsdigita.bebop.Resettable;
-import com.arsdigita.bebop.SimpleComponent;
-import com.arsdigita.util.Assert;
-import com.arsdigita.util.SequentialMap;
-import com.arsdigita.xml.Element;
-
-import org.apache.logging.log4j.LogManager;
-
-import java.util.Iterator;
-
-import org.apache.logging.log4j.Logger;
-
-public abstract class ComponentMap extends SimpleComponent
- implements Resettable {
-
- private static final Logger LOGGER = LogManager
- .getLogger(ComponentMap.class);
-
- private final SequentialMap m_components;
-
- public ComponentMap() {
- m_components = new SequentialMap();
- }
-
- public final Iterator children() {
- return m_components.values().iterator();
- }
-
- public void reset(final PageState state) {
- LOGGER.debug("Resetting my children");
-
- final Iterator iter = children();
-
- while (iter.hasNext()) {
- final Object component = iter.next();
-
- if (component instanceof Resettable) {
- ((Resettable) component).reset(state);
- }
- }
- }
-
- public final void put(final Object key, final Component component) {
- Assert.isUnlocked(this);
- Assert.exists(key, Object.class);
-
- m_components.put(key, component);
- }
-
- public final Component get(final Object key) {
- return (Component) m_components.get(key);
- }
-
- public final boolean containsKey(final Object key) {
- return m_components.containsKey(key);
- }
-
- public final boolean containsValue(final Component component) {
- return m_components.containsValue(component);
- }
-
- public abstract void generateXML(final PageState state,
- final Element parent);
-
-}
diff --git a/ccm-core/src/main/java/com/arsdigita/toolbox/ui/ComponentSet.java b/ccm-core/src/main/java/com/arsdigita/toolbox/ui/ComponentSet.java
deleted file mode 100755
index 368cf8447..000000000
--- a/ccm-core/src/main/java/com/arsdigita/toolbox/ui/ComponentSet.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
- *
- * 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 com.arsdigita.toolbox.ui;
-
-import com.arsdigita.bebop.Component;
-import com.arsdigita.bebop.PageState;
-import com.arsdigita.bebop.Resettable;
-import com.arsdigita.bebop.SimpleComponent;
-import com.arsdigita.util.Assert;
-import com.arsdigita.xml.Element;
-import java.util.ArrayList;
-import java.util.Iterator;
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.LogManager;
-
-/**
- *
- * @version $Id$
- */
-public class ComponentSet extends SimpleComponent
- implements Resettable {
-
- private static final Logger LOGGER = LogManager.getLogger(ComponentSet.class);
-
- private final ArrayList m_components;
-
- public ComponentSet() {
- m_components = new ArrayList();
- }
-
- public void reset(final PageState state) {
- LOGGER.debug("Resetting children");
-
- final Iterator iter = children();
-
- while (iter.hasNext()) {
- final Object component = iter.next();
-
- if (component instanceof Resettable) {
- ((Resettable) component).reset(state);
- }
- }
- }
-
- public final Iterator children() {
- return m_components.iterator();
- }
-
- public final void add(final Component component) {
- Assert.exists(component, "Component component");
-
- synchronized (m_components) {
- final int index = m_components.indexOf(component);
-
- if (index == -1) {
- m_components.add(component);
- } else {
- m_components.set(index, component);
- }
- }
- }
-
- public final Component get(final int index) {
- return (Component) m_components.get(index);
- }
-
- public final int indexOf(final Component component) {
- return m_components.indexOf(component);
- }
-
- public final boolean contains(final Component component) {
- return m_components.contains(component);
- }
-
- public void generateXML(final PageState state, final Element parent) {
- if (isVisible(state)) {
- final Iterator iter = children();
-
- while (iter.hasNext()) {
- ((Component) iter.next()).generateXML(state, parent);
- }
- }
- }
-}
diff --git a/ccm-core/src/main/java/com/arsdigita/toolbox/ui/ContextBar.java b/ccm-core/src/main/java/com/arsdigita/toolbox/ui/ContextBar.java
deleted file mode 100755
index c0f039d77..000000000
--- a/ccm-core/src/main/java/com/arsdigita/toolbox/ui/ContextBar.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
- *
- * 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 com.arsdigita.toolbox.ui;
-
-import com.arsdigita.bebop.SimpleComponent;
-import com.arsdigita.bebop.PageState;
-import com.arsdigita.bebop.RequestLocal;
-import com.arsdigita.web.URL;
-import com.arsdigita.util.Assert;
-import com.arsdigita.xml.Element;
-
-import java.util.Iterator;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- *
A context bar.
- *
- * @author Justin Ross
- * @author Jens Pelzetter
- */
-public abstract class ContextBar extends SimpleComponent {
-
- private static final RequestLocal ENTRIES = new RequestLocal() {
- @Override
- protected final Object initialValue(final PageState state) {
- return new ArrayList<>();
- }
- };
-
- public ContextBar() {
- super();
- }
-
- @SuppressWarnings("unchecked")
- protected List entries(final PageState state) {
- return (List) ENTRIES.get(state);
- }
-
- @Override
- public final void generateXML(final PageState state, final Element parent) {
- if (isVisible(state)) {
- final Element nav = parent.newChildElement
- ("bebop:contextBar", BEBOP_XML_NS);
-
- for (Iterator iter = entries(state).iterator(); iter.hasNext(); ) {
- iter.next().generateXML(state, nav);
- }
- }
- }
-
- public static final class Entry {
- private final String m_title;
- private final String m_href;
-
- public Entry(final String title, final String href) {
- super();
-
- Assert.exists(title, "String title");
-
- m_title = title;
- m_href = href;
- }
-
- public Entry(final String title, final URL url) {
- this(title, url.toString());
- }
-
- public void generateXML(final PageState state,
- final Element parent) {
- final Element elem = parent.newChildElement
- ("bebop:entry", BEBOP_XML_NS);
-
- elem.addAttribute("title", m_title);
- elem.addAttribute("href", m_href);
- }
- }
-}
diff --git a/ccm-core/src/main/java/com/arsdigita/toolbox/ui/DataQueryBuilder.java.todo b/ccm-core/src/main/java/com/arsdigita/toolbox/ui/DataQueryBuilder.java.todo
deleted file mode 100755
index 98862fb13..000000000
--- a/ccm-core/src/main/java/com/arsdigita/toolbox/ui/DataQueryBuilder.java.todo
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
- *
- * 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 com.arsdigita.toolbox.ui;
-
-import com.arsdigita.util.Lockable;
-import com.arsdigita.bebop.PageState;
-
-import java.util.List;
-
-import javax.persistence.criteria.CriteriaQuery;
-
-/**
- * This class is used by the {@link DataTable} class in order to construct a
- * query during each request.
- *
- * In its original implementation this class used a {@code DataQuery}. Because
- * this class is not longer available in JPA we had to change this class to use
- * the JPA CriteriaQuery which is a rough equivalent in JPA. Also this class now
- * uses generics.
- *
- * To create a {@link CriteriaQuery} the method
- * {@link DataTableController#createQuery(java.lang.Class)} can be used. After
- * the query is build
- * {@link DataTableController#executeQuery(javax.persistence.criteria.CriteriaQuery)}
- * can be used to execute the query. An instance of {@link DataTableController}
- * can be obtained using the {@link org.libreccm.cdi.utils.CdiUtil} class.
- *
- * The abstract {@link AbstractDataQueryBuilder} can be used to avoid this
- * boilerplate code. It provides the method
- * {@link AbstractDataQueryBuilder#createBaseQuery(java.lang.Class)} which
- * retrieves the {@link DataTableController} can creates a new
- * {@link CriteriaQuery}.
- *
- * @param the type of the entities the query should return.
- */
-public interface DataQueryBuilder extends Lockable {
-
- /**
- * Perform all necessary database operations and return a {@link List} for
- * the {@link DataTable} to use.
- *
- * @param table the parent DataTable
- * @param state the page state
- *
- * @return
- */
- CriteriaQuery makeDataQuery(DataTable table, PageState state);
-
- /**
- * @return the name of the column in the query that serves as the primary
- * key for the items
- */
- String getKeyColumn();
-
-}
diff --git a/ccm-core/src/main/java/com/arsdigita/toolbox/ui/DataTable.java.todo b/ccm-core/src/main/java/com/arsdigita/toolbox/ui/DataTable.java.todo
deleted file mode 100755
index b36500029..000000000
--- a/ccm-core/src/main/java/com/arsdigita/toolbox/ui/DataTable.java.todo
+++ /dev/null
@@ -1,978 +0,0 @@
-/*
- * Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
- *
- * 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 com.arsdigita.toolbox.ui;
-
-import com.arsdigita.bebop.Page;
-import com.arsdigita.bebop.PageState;
-import com.arsdigita.bebop.PaginationModelBuilder;
-import com.arsdigita.bebop.Paginator;
-import com.arsdigita.bebop.ParameterSingleSelectionModel;
-import com.arsdigita.bebop.SingleSelectionModel;
-import com.arsdigita.bebop.Table;
-import com.arsdigita.bebop.Label;
-import com.arsdigita.bebop.ControlLink;
-import com.arsdigita.bebop.Component;
-import com.arsdigita.bebop.RequestLocal;
-import com.arsdigita.bebop.event.EventListenerList;
-import com.arsdigita.bebop.event.TableActionEvent;
-import com.arsdigita.bebop.event.TableActionListener;
-import com.arsdigita.bebop.table.DefaultTableCellRenderer;
-import com.arsdigita.bebop.table.DefaultTableColumnModel;
-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.bebop.parameters.StringParameter;
-import com.arsdigita.util.LockableImpl;
-import com.arsdigita.util.Assert;
-
-import com.arsdigita.globalization.GlobalizedMessage;
-
-import com.arsdigita.xml.Element;
-
-import java.util.Iterator;
-import java.util.Map;
-import java.util.HashMap;
-
-import java.math.BigDecimal;
-
-import org.apache.log4j.Logger;
-import org.libreccm.cdi.utils.CdiUtil;
-
-import java.util.ResourceBundle;
-
-import javax.persistence.criteria.CriteriaBuilder;
-import javax.persistence.criteria.CriteriaQuery;
-import javax.persistence.criteria.Expression;
-import javax.persistence.criteria.Root;
-
-/**
- *
General
- *
- * Wraps any {@link List} in a sortable Bebop {@link Table}.
- *
- * The {@link List} is supplied by the {@link DataQueryBuilder} class, which the
- * user must implement. The DataQueryBuilder may dynamically
- * construct the query during each request, or return the same named query for
- * each request; the DataTable does not care where the query comes
- * from.
- *
- * This class may contain multiple {@link QueryListener}s. These listeners will
- * be fired whenever the query is about to be performed, thus giving the user a
- * chance to set additional filters on the query.
- *
- * Columns may be added to the DataTable by calling the
- * {@link #addColumn} method. The user may choose to make the column sortable or
- * non-sortable; sortable columns will appear as links on the Web page which,
- * when clicked, will sort the table by the specified column. See the
- * documentation on the various addColumn methods for more
- * information.
- *
- *
- * This class sets the XSL "class" attribute to "dataTable"
- *
- *
Pagination
- *
- * DataTable also implements {@link PaginationModelBuilder}. This
- * means that it could serve as the model builder for any {@link Paginator}
- * component. Pagination of the query occurs after all the sorting and query
- * events have finished. Consider a query which returns the rows "A B C D E F".
- * If the paginator displays 3 rows per page, page 1 will contain "A B C" and
- * page 2 will contain "D E F". If the user then clicks on the header in the
- * DataTable, causing the query to be sorted in reverse order, page
- * 1 will contain "F E D" and page 2 will contain "C B A". In order for
- * pagination to work properly, the following pattern must be used:
- *
- *
- * DataTable table = new DataTable(...);
- * Paginator paginator = new Paginator(table, ...);
- * table.setPaginator(paginator);
- *
- *
- * The setPaginator call is required due to a design flaw in the
- * Paginator component.
- *
- *
- *
Globalization
- *
- * The DataTable will ordinarily interpret the labels of its column
- * headers as plain text, and spit them out on the screen verbatim. However, if
- * setResouceBundle is called, DataTable will instead
- * interpret the column header labels as keys into the specified resource
- * bundle, thus attempting to globalize the column headers at runtime.
- *
- *
- * @author Stanislav Freidin
- * @author Jens Pelzetter
- * @param Type of the entities in the table.
- */
-public class DataTable extends Table implements PaginationModelBuilder {
-
- private DataQueryBuilder dataQueryBuilder;
- private SingleSelectionModel orderModel;
- private StringParameter dirParam;
- private String resourceBundle;
- private RequestLocal querySize;
- private Paginator paginator;
-
- public static final String ORDER = "o";
- public static final String DIRECTION = "d";
- public static final String ASCENDING = "asc";
- public static final String DESCENDING = "desc";
-
- private EventListenerList queryListeners;
-
- /**
- * Construct a new DataTable.
- *
- * @param dataQueryBuilder the {@link DataQueryBuilder} that will be used
- * for this browser
- * @param orderModel the {@link SingleSelectionModel} that will be
- * used to determine the column to order by
- * @param resourceBundle the name of the resource bundle that will be used
- * to globalise the column labels. If null, column
- * labels will be printed verbatim to the screen.
- */
- public DataTable(final DataQueryBuilder dataQueryBuilder,
- final SingleSelectionModel orderModel,
- final String resourceBundle) {
-
- super(new DataBuilderAdapter(), new DataTableColumnModel());
- this.dataQueryBuilder = dataQueryBuilder;
- this.resourceBundle = resourceBundle;
-
- setOrderSelectionModel(orderModel);
- addTableActionListener(new DataTableActionListener());
- queryListeners = new EventListenerList();
-
- dirParam = new StringParameter(DIRECTION);
- dirParam.setDefaultValue(ASCENDING);
-
- getHeader().setDefaultRenderer(new GlobalizedHeaderCellRenderer());
-
- querySize = new RequestLocal();
- paginator = null;
-
- setClassAttr("dataTable");
- }
-
- /**
- * Construct a new DataTable.
- *
- * @param dataQueryBuilder the {@link DataQueryBuilder} that will be used
- * for this browser
- * @param orderModel the {@link SingleSelectionModel} that will be
- * used to determine the column to order by
- */
- public DataTable(final DataQueryBuilder dataQueryBuilder,
- final SingleSelectionModel orderModel) {
- this(dataQueryBuilder, orderModel, null);
- }
-
- /**
- * Construct a new DataTable
- *
- * @param dataQueryBuilder the {@link DataQueryBuilder} that will be used
- * for this browser
- *
- */
- public DataTable(final DataQueryBuilder dataQueryBuilder) {
- this(dataQueryBuilder,
- new ParameterSingleSelectionModel(new StringParameter(ORDER)));
- }
-
- /**
- * Register the ordering parameter
- */
- @Override
- public void register(final Page parent) {
- super.register(parent);
- parent.addComponentStateParam(this,
- getOrderSelectionModel()
- .getStateParameter());
- parent.addComponentStateParam(this, dirParam);
- }
-
- /**
- * Set the key of the default column which will be used to sort the entries
- *
- * @param attribute the default attribute to sort by
- */
- public void setDefaultOrder(final String attribute) {
- Assert.isUnlocked(this);
- getOrderSelectionModel().getStateParameter()
- .setDefaultValue(attribute);
- }
-
- /**
- * Get the key of the default column which will be used to sort the entries
- *
- * @return the default attribute to sort by, or null if no default has been
- * set
- */
- public String getDefaultOrder() {
- return (String) getOrderSelectionModel().getStateParameter()
- .getDefaultValue();
- }
-
- /**
- * Add a column to this table.
- *
- * @param label The user-readable label for the column NOTE: depending
- * on setResourceBundle() it is treated as plain text for
- * output or key into bundle resulting in globalized
- * Labels!
- * @param attribute The name of the attribute in the DataQuery
- * which will be used as the value for this column.
- * @param isSortable true if it is possible to sort using this column, false
- * otherwise
- * @param renderer a {@link TableCellRenderer} that will be used to format
- * the attribute as a string.
- *
- * @return the newly added column
- */
- public TableColumn addColumn(final String label,
- final String attribute,
- final boolean isSortable,
- final TableCellRenderer renderer) {
- return addColumn(label, attribute, isSortable, renderer, null);
- }
-
- /**
- * Add a column to this table.
- *
- * @param label The user-readable label for the column NOTE:
- * depending on setResourceBundle() it is treated as
- * plain text for output or key into bundle resulting
- * in globalised Labels!
- * @param attribute The name of the attribute in the
- * DataQuery which will be used as the
- * value for this column.
- * @param isSortable true if it is possible to sort using this column,
- * false otherwise
- * @param renderer a {@link TableCellRenderer} that will be used to
- * format the attribute as a string.
- * @param orderAttribute The name of the attribute which will be used as the
- * column to order by. This key may be different from
- * the attribute parameter.
- *
- * @return the newly added column
- */
- public TableColumn addColumn(final String label,
- final String attribute,
- final boolean isSortable,
- final TableCellRenderer renderer,
- final String orderAttribute) {
- DataTableColumnModel model = (DataTableColumnModel) getColumnModel();
- TableColumn column = new SortableTableColumn(model.size(),
- label,
- attribute,
- isSortable,
- renderer
- );
-
- model.add(column, orderAttribute);
-
- // Update the default sort order
- if (isSortable && getDefaultOrder() == null) {
- setDefaultOrder((orderAttribute == null) ? attribute
- : orderAttribute);
- }
-
- return column;
- }
-
- /**
- * Add a column to this table.
- *
- * @param label The user-readable label for the column NOTE: depending
- * on setResourceBundle() it is treated as plain text for
- * output or key into bundle resulting in globalized
- * Labels!
- * @param attribute The name of the attribute in the DataQuery
- * which will be used as the value for this column.
- * @param isSortable true if it is possible to sort using this column, false
- * otherwise
- *
- * @return the newly added column
- */
- public TableColumn addColumn(final String label,
- final String attribute,
- final boolean isSortable) {
- return addColumn(label,
- attribute,
- isSortable,
- new DefaultTableCellRenderer(false));
- }
-
- /**
- * Add a column to this table.
- *
- * @param label The user-readable label for the column NOTE: depending
- * on setResourceBundle() it is treated as plain text for
- * output or key into bundle resulting in globalized
- * Labels!
- * @param attribute The name of the attribute in the DataQuery
- * which will be used as the value for this column.
- *
- * @return the newly added column
- */
- public TableColumn addColumn(final String label, final String attribute) {
- return addColumn(label, attribute, false);
- }
-
- /**
- * Add a column to this table. The value for the column will not be supplied
- * by the query; instead, it is the user's responsibility to supply the
- * value through a custom {@link TableModel} or render it directly in the
- * {@link TableCellRenderer}. Typically, this method will be used to add
- * {@link ControlLink}s to the table.
- *
- * @param label The user-readable label for the column NOTE: depending on
- * setResourceBundle() it is treated as plain text for
- * output or key into bundle resulting in globalized Labels!
- * @param renderer The cell renderer for the given column
- *
- * @return the newly added column
- */
- public TableColumn addColumn(final String label,
- final TableCellRenderer renderer) {
- final TableColumnModel columnModel = getColumnModel();
- final TableColumn column = new TableColumn(columnModel.size(), label);
- column.setCellRenderer(renderer);
- column.setHeaderRenderer(new GlobalizedHeaderCellRenderer(false));
- columnModel.add(column);
- return column;
- }
-
- /**
- *
- * @return the {@link DataQueryBuilder} that creates a {@link DataQuery} for
- * this table during each request
- */
- public DataQueryBuilder getDataQueryBuilder() {
- return dataQueryBuilder;
- }
-
- /**
- * @param builder the new {@link DataQueryBuilder} for this table
- */
- public void setDataQueryBuilder(final DataQueryBuilder builder) {
- Assert.isUnlocked(this);
- dataQueryBuilder = builder;
- }
-
- /**
- * @return the {@link SingleSelectionModel} that will determine the order
- */
- public SingleSelectionModel getOrderSelectionModel() {
- return orderModel;
- }
-
- /**
- * Set the {@link SingleSelectionModel} that will determine the order for
- * the items in the table.
- *
- * @param orderModel The new model
- */
- public void setOrderSelectionModel(
- final SingleSelectionModel orderModel) {
-
- Assert.isUnlocked(this);
- this.orderModel = orderModel;
- }
-
- /**
- * Add a {@link QueryListener} to this table. The listener will be fired
- * whenever the query is about to be performed.
- *
- * @param listener the new query listener
- */
- public void addQueryListener(final QueryListener listener) {
- Assert.isUnlocked(this);
- queryListeners.add(QueryListener.class, listener);
- }
-
- /**
- * Remove a {@link QueryListener} from this table.
- *
- * @param listener the new query listener
- */
- public void removeQueryListener(final QueryListener listener) {
- Assert.isUnlocked(this);
- queryListeners.remove(QueryListener.class, listener);
- }
-
- /**
- * Fire the query event listeners to indicate that a query is about to be
- * performed
- *
- * @param state The page state
- * @param query The {@link DataQuery}
- */
- protected void fireQueryPending(final PageState state,
- final CriteriaQuery query) {
- final Iterator iterator = queryListeners
- .getListenerIterator(QueryListener.class);
- QueryEvent event = null;
-
- while (iterator.hasNext()) {
- if (event == null) {
- event = new QueryEvent<>(this, state, query);
- }
- iterator.next().queryPending(event);
- }
- }
-
- /**
- * Set the column by which the table will be ordered
- *
- * @param state the page state
- * @param attr the attribute by which the table will be sorted
- */
- public void setOrder(final PageState state, final String attr) {
- getOrderSelectionModel().setSelectedKey(state, attr);
- }
-
- /**
- * @param state the page state
- *
- * @return the column by which the table will be ordered
- */
- public String getOrder(final PageState state) {
- return getOrderSelectionModel().getSelectedKey(state);
- }
-
- /**
- * @param state the page state
- *
- * @return the order by which the currently selected column will be sorted;
- * will be either ASCENDING or DESCENDING
- */
- public String getOrderDirection(final PageState state) {
- return (String) state.getValue(dirParam);
- }
-
- /**
- * Set the sort direction
- *
- * @param state the page state
- * @param dir the direction in which the current column should be sorted;
- * either ASCENDING or DESCENDING
- */
- public void setOrderDirection(final PageState state, final String dir) {
- Assert.isTrue(ASCENDING.equals(dir) || DESCENDING.equals(dir));
- state.setValue(dirParam, dir);
- }
-
- /**
- * Toggle the sort direction between ascending and descending
- *
- * @param state the page state
- *
- * @return the new order direction; will be either ASCENDING or DESCENDING
- */
- public String toggleOrderDirection(final PageState state) {
- String dir = getOrderDirection(state);
- dir = (ASCENDING.equals(dir)) ? DESCENDING : ASCENDING;
- setOrderDirection(state, dir);
- return dir;
- }
-
- /**
- * Return the {@link DataQuery} that will be used during the current request
- *
- * @param state the page state for the current request
- *
- * @return the current DataQuery
- */
- public CriteriaQuery getDataQuery(final PageState state) {
- return ((DataQueryTableModel) getTableModel(state)).getDataQuery();
- }
-
- /**
- * Paginate the query according to the paginator component. This method will
- * be automatically called by the {@link Paginator} component to which this
- * DataTable has been added as the model builder.
- *
- * @param paginator the parent Paginator
- * @param state the current page state
- *
- * @return the total number of rows in the query
- */
- @Override
- public int getTotalSize(final Paginator paginator, final PageState state) {
- final CriteriaQuery query = getDataQuery(state);
-
- final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
- final DataTableController controller = cdiUtil.findBean(
- DataTableController.class);
-
- return controller.executeQuery(query).size();
- }
-
- /**
- * Return the paginator component used by this table, or null if the table
- * is not paginated.
- *
- * @return The paginator.
- */
- public final Paginator getPaginator() {
- return paginator;
- }
-
- /**
- * Set the paginator component used by this table, or null if the table
- * should not be paginated.
- *
- * @param paginator The paginator to use.
- */
- public final void setPaginator(final Paginator paginator) {
- Assert.isUnlocked(this);
- this.paginator = paginator;
- }
-
- /**
- * Return the RequestLocal used for storing the query size during the
- * request
- *
- * @return The query size.
- */
- protected final RequestLocal getQuerySizeLocal() {
- return querySize;
- }
-
- /**
- * Lock this table
- */
- @Override
- public void lock() {
- dataQueryBuilder.lock();
- super.lock();
- }
-
- // Export the current order
- @Override
- public void generateExtraXMLAttributes(final PageState state,
- final Element element) {
- String key = getOrder(state);
- if (key != null) {
- element.addAttribute("order",
- Integer
- .toString(getColumnModel().getIndex(key)));
- }
- String dir = getOrderDirection(state);
- if (dir != null) {
- element.addAttribute("direction", dir);
- }
- }
-
- /**
- * Globalises the specified key.
- *
- * @param key The key of the message.
- *
- * @return The globalised message for the provided key.
- */
- public GlobalizedMessage globalize(String key) {
- return new GlobalizedMessage(key, resourceBundle);
- }
-
- /**
- * Return the resource bundle for globalisation, or null if no bundle was
- * specified
- *
- * @return The fully qualified name of the {@link ResourceBundle} used by
- * this {@code DataTable}.
- */
- public String getResourceBundle() {
- return resourceBundle;
- }
-
- /**
- * Set the resource bundle for globalisation, or null if no globalisation is
- * needed.
- *
- * @param bundle The fully qualified name of the {@link ResourceBundle} to
- * use.
- */
- public void setResourceBundle(final String bundle) {
- Assert.isUnlocked(this);
- resourceBundle = bundle;
- }
-
- /**
- * A {@link TableColumn} that could potentially be sorted
- */
- private static class SortableTableColumn extends TableColumn {
-
- private boolean sortable;
- private SingleSelectionModel orderModel;
-
- /**
- * Construct a new SortableTableColumn
- *
- * @param modelIndex the index of the column in the table model from
- * which to retrieve values.
- * @param value the value for the column header.
- * @param key the key for the column header.
- * @param isSortable whether the column is sortable or not
- * @param renderer the renderer which will be used to render this
- * column
- */
- public SortableTableColumn(final int modelIndex,
- final Object value,
- final Object key,
- final boolean isSortable,
- final TableCellRenderer renderer
- ) {
-
- super(modelIndex, value, key);
- setSortable(isSortable);
- setCellRenderer(renderer);
- }
-
- /**
- * Determine whether this column is sortable
- *
- * @param isSortable if true, the column will be sortable
- */
- public void setSortable(final boolean isSortable) {
- Assert.isUnlocked(this);
- sortable = isSortable;
- setHeaderRenderer(new GlobalizedHeaderCellRenderer(isSortable));
- }
-
- /**
- * @return the {@link SingleSelectionModel} which is responsible for
- * maintaining the sort order
- */
- public SingleSelectionModel getOrderSelectionModel() {
- return orderModel;
- }
-
- /**
- * @return true if this column is sortable, false otherwise
- */
- public boolean isSortable() {
- return sortable;
- }
-
- }
-
- /**
- * The action listener that will sort the {@link DataQuery} for this table
- */
- private static class DataTableActionListener implements TableActionListener {
-
- @Override
- public void cellSelected(final TableActionEvent event) {
- }
-
- @Override
- public void headSelected(final TableActionEvent event) {
- final PageState state = event.getPageState();
- final DataTable> table = (DataTable>) event.getSource();
-
- final int index = event.getColumn();
- final SortableTableColumn column = (SortableTableColumn) table
- .getColumnModel().get(index);
-
- if (column != null) {
- if (column.isSortable()) {
- final DataTableColumnModel model
- = (DataTableColumnModel) table
- .getColumnModel();
- final String oldOrder = table.getOrder(state);
- String newOrder = model.getColumnKey(column);
- if (newOrder == null) {
- newOrder = (String) column.getHeaderKey();
- }
- if (oldOrder != null && oldOrder.equals(newOrder)) {
- // Reverse direction
- table.toggleOrderDirection(state);
- } else {
- table.setOrder(state, newOrder);
- table.setOrderDirection(state, DataTable.ASCENDING);
- }
- }
- }
- }
-
- }
-
- /**
- * Adapts a {@link DataQueryBuilder} into a {@link TableModelBuilder}. Wraps
- * the query returned by the builder in a DataQueryTableModel.
- *
- * @see com.arsdigita.toolbox.ui.DataTable.DataQueryTableModel
- */
- protected static class DataBuilderAdapter extends LockableImpl
- implements TableModelBuilder {
-
- /**
- * Create a new DataBuilderAdapter
- */
- public DataBuilderAdapter() {
- super();
- }
-
- /**
- * Obtain a {@link DataQuery} and apply query events to it. The query
- * events may add additional filters to the query, among other things.
- * Finally, retrieve the current sort column from the parent
- * {@link DataTable} and apply it to the query
- *
- * @see com.arsdigita.toolbox.ui.DataTable.DataQueryTableModel
- * @param table the parent {@link DataTable}
- * @param state the current page state
- *
- * @return the final {@link DataQuery}, which is now ready to be wrapped
- * in a DataQueryTableModel
- */
- protected CriteriaQuery createQuery(final DataTable table,
- final PageState state) {
- final CriteriaQuery query = table.getDataQueryBuilder()
- .makeDataQuery(table, state);
-
- final Root root = query.getR
-
- final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
- final DataTableController controller = cdiUtil.findBean(
- DataTableController.class);
- final CriteriaBuilder criteriaBuilder = controller
- .getCriteriaBuilder();
-
- String order = table.getOrder(state);
- if (order != null) {
- String dir = table.getOrderDirection(state);
- if (dir != null) {
- order += " " + dir;
- }
- query.orderBy(criteriaBuilder.asc())
- query.addOrder(order);
- }
- table.fireQueryPending(state, query);
-
- // Paginate the query if neccessary
- if (table.getPaginator() != null) {
- // Force the size to calculate before the range is set
- if (table.getQuerySizeLocal().get(state) == null) {
- table.getQuerySizeLocal().set(state, new BigDecimal(query
- .size()));
- }
-
- // Paginate the query
- query
- .setRange(new Integer(table.getPaginator().getFirst(state)),
- new Integer(table.getPaginator().getLast(state)
- + 1));
- }
-
- return query;
- }
-
- /**
- * Construct a DataQueryTableModel by wrapping the query.
- *
- * @param table the parent {@link DataTable}
- * @param s the current page state
- *
- * @see com.arsdigita.toolbox.ui.DataTable.DataQueryTableModel
- * @return a DataQueryTableModel that will iterate through the query
- */
- public TableModel makeModel(Table table, PageState s) {
- DataTable t = (DataTable) table;
- DataQuery d = createQuery(t, s);
-
- if (d == null) {
- return Table.EMPTY_MODEL;
- }
-
- return new DataQueryTableModel(t, d,
- t.getDataQueryBuilder()
- .getKeyColumn());
- }
-
- }
-
- /**
- * A TableModel which gets its data from a DataQuery. This TableModel is
- * used in the {@link DataTable.DataBuilderAdapter} to iterate through the
- * query returned by the {@link DataQueryBuilder} and generate rows for it
- * on the screen.
- */
- protected static class DataQueryTableModel implements TableModel {
-
- private DataQuery m_data;
- private DataTableColumnModel m_cols;
- private String m_keyColumn;
-
- /**
- * Create a new DataQueryTableModel
- *
- * @param t the {@link DataTable} which needs this model
- * @param data the {@link DataQuery to be wrapped}
- * @param keyColumn the name of the column in the query which represents
- * the primary key
- *
- * @pre data != null
- * @pre keyColumn != null
- * @pre t != null
- * @pre t.getColumnModel() != null
- */
- public DataQueryTableModel(DataTable t, DataQuery data, String keyColumn) {
- m_data = data;
- m_cols = (DataTableColumnModel) t.getColumnModel();
- m_keyColumn = keyColumn;
- }
-
- public int getColumnCount() {
- return m_cols.size();
- }
-
- public boolean nextRow() {
- return m_data.next();
- }
-
- public Object getElementAt(int columnIndex) {
- String key = (String) m_cols.get(columnIndex).getHeaderKey();
- if (key != null) {
- return m_data.get(key);
- } else {
- return null;
- }
- }
-
- public Object getKeyAt(int columnIndex) {
- String key = m_cols.getKeyAt(columnIndex);
- if (key != null) {
- return m_data.get(key);
- } else {
- return m_data.get(m_keyColumn);
- }
- }
-
- /**
- * Return the original DataQuery. The query's cursor will be "pointing"
- * at the current row
- */
- public DataQuery getDataQuery() {
- return m_data;
- }
-
- }
-
- /**
- * Always renders the table header as a link. Thus, it becomes possible to
- * sort up and down by clicking the table column over and over.
- * Also, globalizes the column labels if possible.
- */
- protected static class GlobalizedHeaderCellRenderer
- implements TableCellRenderer {
-
- private boolean m_active;
-
- public GlobalizedHeaderCellRenderer(boolean isActive) {
- m_active = isActive;
- }
-
- public GlobalizedHeaderCellRenderer() {
- this(true);
- }
-
- public Component getComponent(Table table, PageState state, Object value,
- boolean isSelected, Object key,
- int row, int column) {
- DataTable t = (DataTable) table;
- Label label;
-
- if (value == null) {
- label = new Label(" ", false);
- } else {
- String str = value.toString();
- if (t.getResourceBundle() != null) {
- label = new Label(t.globalize(str));
- } else {
- label = new Label(str);
- }
- }
-
- if (m_active) {
- return new ControlLink(label);
- } else {
- return label;
- }
- }
-
- }
-
- /**
- * A special column model that maintains an alternate key for each column.
- * The alternate key will be passed to the query in the
- * addOrder method, thus sorting the query by the given column
- * - making it possible to make the sort key differ from the attribute key
- * for any given column.
- *
- * Note that each column ALREADY has a unique key, which can be retrieved by
- * calling TableColumn.getHeaderKey(). This key will be used to
- * provide the value for the column.
- */
- protected static class DataTableColumnModel extends DefaultTableColumnModel {
-
- // The column keys are a property of the table and column
- // combination so we store the values in the HashMap
- private Map m_columnKeys = new HashMap();
-
- public void add(TableColumn column, String columnKey) {
- super.add(column);
- setColumnKey(column, columnKey);
- }
-
- public void add(int columnIndex, TableColumn column, String columnKey) {
- super.add(columnIndex, column);
- setColumnKey(column, columnKey);
- }
-
- public String getColumnKey(TableColumn column) {
- return (String) m_columnKeys.get(column);
- }
-
- public String getKeyAt(int columnIndex) {
- return getColumnKey(get(columnIndex));
- }
-
- public void setColumnKey(TableColumn column, String columnKey) {
- m_columnKeys.put(column, columnKey);
- }
-
- public void setColumnKey(int columnIndex, String columnKey) {
- setColumnKey(get(columnIndex), columnKey);
- }
-
- @Override
- public void remove(TableColumn column) {
- super.remove(column);
- m_columnKeys.remove(column);
- }
-
- }
-
-}
diff --git a/ccm-core/src/main/java/com/arsdigita/toolbox/ui/DomainObjectPropertySheet.java b/ccm-core/src/main/java/com/arsdigita/toolbox/ui/DomainObjectPropertySheet.java
deleted file mode 100755
index eec67ae65..000000000
--- a/ccm-core/src/main/java/com/arsdigita/toolbox/ui/DomainObjectPropertySheet.java
+++ /dev/null
@@ -1,640 +0,0 @@
-/*
- * Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
- *
- * 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 com.arsdigita.toolbox.ui;
-
-import com.arsdigita.bebop.PageState;
-import com.arsdigita.bebop.PropertySheet;
-import com.arsdigita.bebop.PropertySheetModel;
-import com.arsdigita.bebop.PropertySheetModelBuilder;
-import com.arsdigita.bebop.parameters.StringParameter;
-import com.arsdigita.globalization.GlobalizedMessage;
-import com.arsdigita.kernel.KernelConfig;
-import com.arsdigita.toolbox.ToolboxConstants;
-import com.arsdigita.ui.CcmObjectSelectionModel;
-import com.arsdigita.util.LockableImpl;
-
-import org.libreccm.core.CcmObject;
-import org.libreccm.core.UnexpectedErrorException;
-import org.libreccm.l10n.LocalizedString;
-
-import java.beans.BeanInfo;
-import java.beans.IntrospectionException;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Optional;
-import java.util.StringTokenizer;
-
-/**
- * Displays a list of label-value pairs, which represent the attributes of a
- * domain object.
- *
- * Typical usage is
- *
- *
- * The first argument is the visible label for the property, and the second
- * argument is the name of the property as it appears in the PDL file.
- *
- * Instead of specifying the property directly, you may specify the "path" to
- * the property. For example,
- *
- * mySheet.add("Address Line 1:", "user.address.street");
- *
- *
- * The code above tells the DomainObjectPropertySheet to look for
- * the child of the current object named "user"; then look for the child of the
- * user named "address", and finally to return the property of the address named
- * "street".
- *
- * Note that, by default, DomainObjectPropertySheet retrieves the
- * values for its properties directly from the underlying {@link DataObject} of
- * the {@link DomainObject}. This means that the Java getXXX
- * methods of the DomainObject will never be called. Of course, it
- * is always possible to create a custom {@link AttributeFormatter} that will
- * call the appropriate methods.
- *
- * @author Stanislav Freidin
- * @author Peter Boy (localization)
- * @author Jens Pelzetter
- */
-public class DomainObjectPropertySheet extends PropertySheet {
-
- private List properties;
- private CcmObjectSelectionModel> objectSelectionModel;
- private AttributeFormatter toStringFormatter;
- private AttributeFormatter recursiveFormatter;
-
- private StringParameter selectedLanguageParam;
-
- /**
- * Construct a new DomainObjectPropertySheet
- *
- * @param objectSelectionModel The selection model which feeds domain
- * objects to this property sheet.
- */
- public DomainObjectPropertySheet(
- final CcmObjectSelectionModel> objectSelectionModel) {
-
- this(objectSelectionModel, false);
- }
-
- /**
- * Construct a new DomainObjectPropertySheet
- *
- * @param objectSelectionModel The selection model which feeds domain
- * objects to this property sheet
- * @param valueOutputEscape The value of the label-value pair(i.e.,
- * column[1])'s output-escaping
- */
- public DomainObjectPropertySheet(
- final CcmObjectSelectionModel> objectSelectionModel,
- final boolean valueOutputEscape) {
-
- this(objectSelectionModel, valueOutputEscape, null);
- }
-
- public DomainObjectPropertySheet(
- final CcmObjectSelectionModel> objectSelectionModel,
- final boolean valueOutputEscape,
- final StringParameter selectedLanguageParam) {
-
- super(new DomainObjectModelBuilder(), valueOutputEscape);
-
- this.objectSelectionModel = objectSelectionModel;
- properties = new LinkedList<>();
- if (selectedLanguageParam == null) {
- this.selectedLanguageParam
- = new StringParameter("selected_language");
- } else {
- this.selectedLanguageParam = selectedLanguageParam;
- }
-
- toStringFormatter = new SimpleAttributeFormatter();
- recursiveFormatter = new RecursiveAttributeFormatter();
-
- getColumn(0).setVAlign("top");
- getColumn(0).setAlign("left");
- getColumn(1).setVAlign("top");
- getColumn(1).setAlign("left");
- }
-
- /**
- * Add a new property to the sheet. The sheet will automatically retrieve an
- * attribute of the object and call toString() on it
- *
- * @param label The label for the attribute
- * @param attribute The name for the attribute. Could be a simple name or a
- * compound path, such as "foo.bar.baz" (usually a PDL
- * property)
- *
- * @deprecated use add(GlobalizedMessage label, String attribute) instead
- */
- public void add(final String label, String attribute) {
- add(new GlobalizedMessage(label,
- ToolboxConstants.TOOLBOX_BUNDLE),
- attribute);
- }
-
- /**
- * Add a new property to the sheet. The sheet will automatically retrieve an
- * attribute of the object and call toString() on it
- *
- * @param label The label for the attribute
- * @param attribute The name for the attribute. Could be a simple name or a
- * compound path, such as "foo.bar.baz" (usually a PDL
- * property)
- */
- public void add(final GlobalizedMessage label,
- final String attribute) {
- // Determine if we are dealing with a simple string or a complex
- // path
- if (attribute.indexOf('.') == -1) {
- add(label, attribute, toStringFormatter);
- } else {
- add(label, attribute, recursiveFormatter);
- }
- }
-
- /**
- * Add a new property to the sheet. The sheet will use an AttributeFormatter
- * to convert the value of the attribute to a String.
- *
- * @param label The label for the attribute
- * @param attribute The name for the attribute. Could be a simple name or a
- * compound path, such as "foo.bar.baz" (usually a PDL
- * property)
- * @param formatter An instance of AttributeFormatter
- *
- * @deprecated Use add(GlobalizedMessage label, String attribute,
- * AttributeFormatter f) instead
- */
- public void add(final String label,
- final String attribute,
- final AttributeFormatter formatter) {
- add(new GlobalizedMessage(label, ToolboxConstants.TOOLBOX_BUNDLE),
- attribute,
- formatter);
- }
-
- /**
- * Add a new property to the sheet. The sheet will use an AttributeFormatter
- * to convert the value of the attribute to a String.
- *
- * @param label The label for the attribute
- * @param attribute The name for the attribute. Could be a simple name or a
- * compound path, such as "foo.bar.baz" (usually a PDL
- * property)
- * @param formatter An instance of AttributeFormatter
- */
- public void add(final GlobalizedMessage label,
- final String attribute,
- final AttributeFormatter formatter) {
- properties.add(new Property(label, attribute, formatter));
- }
-
- /**
- * @return The object selection model
- */
- public CcmObjectSelectionModel> getObjectSelectionModel() {
- return objectSelectionModel;
- }
-
- /**
- * @return The iterator over all properties
- */
- protected Iterator properties() {
- return properties.iterator();
- }
-
- /**
- * An interface which can transform the value of a (domain) property to a
- * string.
- *
- * Most of the time, classes which implement this interface will just return
- * object.get(attribute).toString()
- *
- * In case of associations, however, more complicated processing will be
- * required.
- */
- public interface AttributeFormatter {
-
- /**
- * Formatter for the value of an attribute. It has to retrieve the value
- * for the specified attribute of the object and format it as an string
- * if it is one already.
- *
- * Note: the format method has to be executed at each page request. Take
- * care to properly adjust globalization and localization inside thes
- * method and not earlier in one of the classes using it!
- *
- * @param obj Object containing the attribute to format.
- * @param attribute Name of the attribute to retrieve and format
- * @param state PageState of the request
- *
- * @return A String representation of the retrieved attribute of the
- * domain object.
- */
- String format(Object obj, String attribute, PageState state);
-
- }
-
- /**
- * Associates a label with the attribute and the formatter.
- */
- protected static class Property {
-
- private GlobalizedMessage label;
- private String attribute;
- private AttributeFormatter formatter;
-
- /**
- * Constructor, takes the set of parameter to create a new Property.
- *
- * @param label the labal for the attribute
- * @param attribute the attribute (as String, i.e name of the property)
- * @param formatter the formatter to convert the attribute a into a
- * String
- */
- public Property(final GlobalizedMessage label,
- final String attribute,
- final AttributeFormatter formatter) {
- this.label = label;
- this.attribute = attribute;
- this.formatter = formatter;
- }
-
- /**
- * @deprecated use getGlobalizedLabel instead
- */
- public String getLabel() {
- return label.getKey();
- }
-
- /**
- * Fetch the (globalises) label of the property.
- *
- * @return
- */
- public GlobalizedMessage getGlobalizedLabel() {
- return label;
- }
-
- /**
- * Fetch the attribute.
- *
- * @return name of the attribute (a String)
- */
- public String getAttribute() {
- return attribute;
- }
-
- /**
- * Fetch the formatter for the attribute
- *
- * @return
- */
- public AttributeFormatter getFormatter() {
- return formatter;
- }
-
- }
-
- /**
- * Build up the object properties model from the iterator over all
- * properties.
- */
- private static class DomainObjectPropertiesModel
- implements PropertySheetModel {
-
- private CcmObject object;
- private PageState pageState;
- private Iterator properties;
- private Property currentProperty;
- private static String ERROR = "No current property. "
- + "Make sure that nextRow() was "
- + "called at least once.";
-
- /**
- *
- * @param object
- * @param properties
- * @param pageState
- */
- public DomainObjectPropertiesModel(final CcmObject object,
- Iterator properties,
- final PageState pageState) {
- this.object = object;
- this.properties = properties;
- this.pageState = pageState;
- this.currentProperty = null;
- }
-
- @Override
- public boolean nextRow() {
- if (!properties.hasNext()) {
- return false;
- }
-
- currentProperty = properties.next();
- return true;
- }
-
- /**
- * @deprecated use getGlobalizedLabel() instead
- */
- @Override
- public String getLabel() {
- return getGlobalizedLabel().getKey();
- }
-
- /**
- *
- * @return
- */
- @Override
- public GlobalizedMessage getGlobalizedLabel() {
- if (currentProperty == null) {
- throw new IllegalStateException(ERROR);
- }
- return currentProperty.getGlobalizedLabel();
- }
-
- @Override
- public String getValue() {
- if (currentProperty == null) {
- throw new IllegalStateException(ERROR);
- }
- return currentProperty
- .getFormatter()
- .format(object, currentProperty.getAttribute(), pageState);
- }
-
- }
-
- /**
- * Builds an DomainObjectPropertiesModel.
- */
- private static class DomainObjectModelBuilder
- extends LockableImpl
- implements PropertySheetModelBuilder {
-
- @Override
- public PropertySheetModel makeModel(
- final PropertySheet sheet,
- final PageState state) {
-
- final DomainObjectPropertySheet objSheet
- = (DomainObjectPropertySheet) sheet;
- return new DomainObjectPropertiesModel(
- objSheet.getObjectSelectionModel().getSelectedObject(state),
- objSheet.properties(),
- state);
- }
-
- }
-
- /**
- * Abstract AttributeFormatter class which maintains a "default" value for
- * the attribute. The default value is a GlobalizedMessage, which will be
- * formatted to a String by the default format method.
- */
- private static abstract class DefaultAttributeFormatter
- implements AttributeFormatter {
-
- private GlobalizedMessage m_default;
-
- /**
- * Default Constructor which creates a default GlobalizedMessage to be
- * used as default value for an attribute.
- */
- public DefaultAttributeFormatter() {
- m_default = new GlobalizedMessage(
- "toolbox.ui.na", ToolboxConstants.TOOLBOX_BUNDLE);
- }
-
- /**
- * Constructor which takes a custom GlobalizedMessage to be used as a
- * default value.
- *
- * @param def GlobalizedMessage used as default value
- */
- public DefaultAttributeFormatter(final GlobalizedMessage def) {
- m_default = def;
- }
-
- public GlobalizedMessage getDefaultValue() {
- return m_default;
- }
-
- }
-
- /**
- * A simple attribute formatter that calls get on the object with the
- * specified attribute.
- */
- private class SimpleAttributeFormatter
- extends DefaultAttributeFormatter {
-
- /**
- * Constructor, simply calls the super class. Uses a default value for
- * empty attributes.
- */
- public SimpleAttributeFormatter() {
- super();
- }
-
- /**
- * Constructor which takes a custom GlobalizedMessage to be used as a
- * default value.
- *
- * @param def GlobalizedMessage used as default value
- */
- public SimpleAttributeFormatter(GlobalizedMessage def) {
- super(def);
- }
-
- /**
- * Formatter method, invoked at every page request!
- *
- * @param obj
- * @param attribute
- * @param state
- *
- * @return
- */
- @Override
- public String format(final Object obj,
- final String attribute,
- final PageState state) {
-
- /* Determine the default value */
- GlobalizedMessage defaultMsg = getDefaultValue();
-
- if (obj == null) {
- return (String) defaultMsg.localize();
- }
-
- final Optional