Removed depcrecated packages com.arsdigita.toolbox.ui and org.libreccm.pagemodel.ui

pull/28/head
Jens Pelzetter 2022-03-21 19:55:47 +01:00
parent af6bee2cdc
commit 7cd39aa321
29 changed files with 0 additions and 4379 deletions

View File

@ -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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
* @param <T> Type of entity retrieved by the query.
*/
public abstract class AbstractDataQueryBuilder<T> implements DataQueryBuilder<T> {
/**
* 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<T> createBaseQuery(final Class<T> entityClass) {
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final DataTableController controller = cdiUtil.findBean(
DataTableController.class);
return controller.createQuery(entityClass);
}
}

View File

@ -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.</p>
*
* @author Justin Ross &lt;jross@redhat.com&gt;
*/
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);
}
}
}
}
}

View File

@ -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);
}

View File

@ -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;
/**
* <p>
* Wrapper class that registers access checks (actions) to a Bebop
* component.</p>
*
* @author Michael Pih
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class ComponentAccess {
private Component component;
private List<String> 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<String> 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<Boolean> 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();
}
}

View File

@ -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);
}

View File

@ -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);
}
}
}
}

View File

@ -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;
/**
* <p>A context bar.</p>
*
* @author Justin Ross
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
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<Entry> entries(final PageState state) {
return (List<Entry>) 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<Entry> 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);
}
}
}

View File

@ -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 <T> the type of the entities the query should return.
*/
public interface DataQueryBuilder<T> 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<T> makeDataQuery(DataTable<T> table, PageState state);
/**
* @return the name of the column in the query that serves as the primary
* key for the items
*/
String getKeyColumn();
}

View File

@ -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;
/**
* <h4>General</h4>
*
* 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 <code>DataQueryBuilder</code> may dynamically
* construct the query during each request, or return the same named query for
* each request; the <code>DataTable</code> 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 <code>DataTable</code> 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 <code>addColumn</code> methods for more
* information.
*
*
* This class sets the XSL "class" attribute to "dataTable"
*
* <h4>Pagination</h4>
*
* <code>DataTable</code> 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
* <code>DataTable</code>, 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:
*
* <blockquote><pre><code>
* DataTable table = new DataTable(...);
* Paginator paginator = new Paginator(table, ...);
* table.setPaginator(paginator);
* </code></pre></blockquote>
*
* The <code>setPaginator</code> call is required due to a design flaw in the
* <code>Paginator</code> component.
* <p>
*
* <h4>Globalization</h4>
*
* The <code>DataTable</code> will ordinarily interpret the labels of its column
* headers as plain text, and spit them out on the screen verbatim. However, if
* <code>setResouceBundle</code> is called, <code>DataTable</code> will instead
* interpret the column header labels as keys into the specified resource
* bundle, thus attempting to globalize the column headers at runtime.
* <p>
*
* @author Stanislav Freidin
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
* @param <T> Type of the entities in the table.
*/
public class DataTable<T> extends Table implements PaginationModelBuilder {
private DataQueryBuilder<T> dataQueryBuilder;
private SingleSelectionModel<String> 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<T> dataQueryBuilder,
final SingleSelectionModel<String> 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<T> dataQueryBuilder,
final SingleSelectionModel<T> 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<T> dataQueryBuilder) {
this(dataQueryBuilder,
new ParameterSingleSelectionModel<T>(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 <code>DataQuery</code>
* 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
* <code>DataQuery</code> 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 <code>attribute</code> 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 <code>DataQuery</code>
* 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 <code>DataQuery</code>
* 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<T> getDataQueryBuilder() {
return dataQueryBuilder;
}
/**
* @param builder the new {@link DataQueryBuilder} for this table
*/
public void setDataQueryBuilder(final DataQueryBuilder<T> builder) {
Assert.isUnlocked(this);
dataQueryBuilder = builder;
}
/**
* @return the {@link SingleSelectionModel} that will determine the order
*/
public SingleSelectionModel<String> 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<String> 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<T> query) {
final Iterator<QueryListener> iterator = queryListeners
.getListenerIterator(QueryListener.class);
QueryEvent<T> 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 <code>DataQuery</code>
*/
public CriteriaQuery<T> 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
* <code>DataTable</code> has been added as the model builder.
*
* @param paginator the parent <code>Paginator</code>
* @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<T> 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<String> 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<String> 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 <code>DataBuilderAdapter</code>
*/
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 <E> CriteriaQuery<E> createQuery(final DataTable<E> table,
final PageState state) {
final CriteriaQuery<E> query = table.getDataQueryBuilder()
.makeDataQuery(table, state);
final Root<E> 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 <code>DataQueryTableModel</code>
*
* @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.<p>
* 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("&nbsp;", 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
* <code>addOrder</code> 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.
* <p>
* Note that each column ALREADY has a unique key, which can be retrieved by
* calling <code>TableColumn.getHeaderKey()</code>. 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);
}
}
}

View File

@ -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
* <blockquote><pre><code>
* DomainObjectPropertySheet mySheet =
* new DomainObjectPropertySheet(myDomainObjectSelectionModel);
* mySheet.add("Name:", ContentPage.NAME);
* mySheet.add("Title:", ContentPage.TITLE);
* </code></pre></blockquote>
*
* 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,
* <blockquote><pre><code>
* mySheet.add("Address Line 1:", "user.address.street");
* </code></pre></blockquote>
*
* The code above tells the <code>DomainObjectPropertySheet</code> 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, <code>DomainObjectPropertySheet</code> retrieves the
* values for its properties directly from the underlying {@link DataObject} of
* the {@link DomainObject}. This means that the Java <code>getXXX</code>
* methods of the <code>DomainObject</code> 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 <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class DomainObjectPropertySheet extends PropertySheet {
private List<Property> 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<Property> 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
* <code>object.get(attribute).toString()</code>
* <p>
* 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<Property> 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<Property> 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<Object> value = getPropertyValue(obj,
attribute,
state);
if (value.isPresent()) {
return value.get().toString();
} else {
return (String) defaultMsg.localize();
}
}
}
/**
* A more advanced attribute formatter. Follows the path to the value by
* following the names in the attribute string. For example, if the string
* says "foo.bar.baz", the formatter will attempt to call
* obj.get("foo").get("bar").get("baz");
*/
private class RecursiveAttributeFormatter extends DefaultAttributeFormatter {
/**
* Constructor, simply calls the super class. Uses a default value for
* empty attributes.
*/
public RecursiveAttributeFormatter() {
super();
}
/**
* Constructor which takes a custom GlobalizedMessage to be used as a
* default value.
*
* @param def GlobalizedMessage used as default value
*/
public RecursiveAttributeFormatter(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) {
if (obj == null) {
return (String) getDefaultValue().localize();
}
final StringTokenizer tokenizer
= new StringTokenizer(attribute, ".");
String token = null;
Object currentObject = obj;
while (tokenizer.hasMoreTokens()) {
token = tokenizer.nextToken();
// Null check
currentObject = getPropertyValue(currentObject, token, state);
if (currentObject == null) {
return (String) getDefaultValue().localize();
}
}
// Extract leaf value
if (token == null) {
return (String) getDefaultValue().localize();
}
return currentObject.toString();
}
}
private Optional<Object> getPropertyValue(final Object obj,
final String property,
final PageState state) {
final BeanInfo beanInfo;
try {
beanInfo = Introspector.getBeanInfo(obj.getClass());
} catch (IntrospectionException ex) {
throw new UnexpectedErrorException(ex);
}
final Optional<PropertyDescriptor> propertyDescriptor = Arrays
.stream(beanInfo.getPropertyDescriptors())
.filter(current -> property.equals(current.getName()))
.findAny();
if (propertyDescriptor.isPresent()) {
final Method readMethod = propertyDescriptor
.get()
.getReadMethod();
final Object value;
try {
final Object tmp = readMethod.invoke(obj);
if (tmp instanceof LocalizedString) {
final LocalizedString localizedString
= (LocalizedString) tmp;
final Object selectedLanguage = state.getValue(
selectedLanguageParam);
final Locale selectedLocale;
if (selectedLanguage instanceof Locale) {
selectedLocale = (Locale) selectedLanguage;
} else {
selectedLocale = new Locale((String) selectedLanguage);
}
if (localizedString.hasValue(selectedLocale)) {
value = localizedString.getValue(selectedLocale);
} else {
value = "";
}
} else {
value = tmp;
}
} catch (IllegalAccessException | InvocationTargetException ex) {
throw new UnexpectedErrorException(ex);
}
return Optional.ofNullable(value);
} else {
return Optional.empty();
}
}
}

View File

@ -1,108 +0,0 @@
/*
* Copyright (C) 2002-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.RequestLocal;
import com.arsdigita.globalization.Globalized;
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.l10n.GlobalizationHelper;
/**
*
* This class holds methods to support consistent formatting across the system.
*
* @version $Revision$ $Date$
* @version $Id$
*/
public class FormatStandards implements Globalized {
private static RequestLocal s_dateFormat = new RequestLocal();
private static RequestLocal s_dateTimeFormat = new RequestLocal();
private static void initialize(PageState ps) {
Locale l = CdiUtil.createCdiUtil().findBean(GlobalizationHelper.class).
getNegotiatedLocale();
s_dateFormat.set(ps, DateFormat.getDateInstance(DATE_DISPLAY_FORMAT, l));
s_dateTimeFormat.set(ps, DateFormat.getDateTimeInstance(
DATE_DISPLAY_FORMAT, TIME_DISPLAY_FORMAT, l));
}
/**
* @return A globalized DateFormat instance for formatting the date only.
* @see #getDateTimeFormat()
*/
public static DateFormat getDateFormat() {
PageState ps = PageState.getPageState();
Object obj = s_dateFormat.get(ps);
if (obj == null) {
initialize(ps);
obj = s_dateFormat.get(ps);
}
return (DateFormat) obj;
}
/**
* @return A globalized DateFormat instance for formatting the date and
* time.
* @see #getDateFormat()
*/
public static DateFormat getDateTimeFormat() {
PageState ps = PageState.getPageState();
Object obj = s_dateTimeFormat.get(ps);
if (obj == null) {
initialize(ps);
obj = s_dateTimeFormat.get(ps);
}
return (DateFormat) obj;
}
/**
* Formats a date value according to formatting standards and localization.
* In English This will show the date as "Mmm DD, YYYY" or "Jan 23, 2002."
* This method discards the clock time.
*
* @param d The date to format.
* @return A properly formatted date.
* @see #formatDateTime(Date)
*/
public static String formatDate(Date d) {
return (d == null) ? null : getDateFormat().format(d);
}
/**
* Formats a date and time value according to formatting standards and
* localization. This method includes the date and the time. In English, it
* will appear as "Mmm DD, YYYY HH:MM AM" or "Jan 23, 2002, 5:44 PM.
*
* @param d The date to format.
* @return A properly formatted date and time.
*/
public static String formatDateTime(Date d) {
return (d == null) ? null : getDateTimeFormat().format(d);
}
}

View File

@ -1,86 +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 static com.arsdigita.bebop.Component.*;
import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.PageState;
import com.arsdigita.xml.Element;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
* A simple layout panel with top, bottom, left, right, and body sections.
*
* @author Justin Ross &lt;jross@redhat.com&gt;
*/
public class LayoutPanel extends ComponentMap {
private static final Logger LOGGER = LogManager.getLogger(LayoutPanel.class);
public final void setTop(final Component top) {
put("top", top);
}
public final void setLeft(final Component left) {
put("left", left);
}
public final void setBody(final Component body) {
put("body", body);
}
public final void setRight(final Component right) {
put("right", right);
}
public final void setBottom(final Component bottom) {
put("bottom", bottom);
}
@Override
public void generateXML(final PageState state, final Element parent) {
if (isVisible(state)) {
final Element layout = parent.newChildElement("bebop:layoutPanel",
BEBOP_XML_NS);
section(state, layout, "top");
section(state, layout, "left");
section(state, layout, "body");
section(state, layout, "right");
section(state, layout, "bottom");
}
}
private void section(final PageState state,
final Element parent,
final String key) {
final Component section = get(key);
if (section != null) {
final Element elem = parent.newChildElement("bebop:" + key,
BEBOP_XML_NS);
section.generateXML(state, elem);
}
}
}

View File

@ -1,584 +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.ActionLink;
import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.FormSection;
import com.arsdigita.bebop.List;
import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.SingleSelectionModel;
import com.arsdigita.bebop.Table;
import com.arsdigita.bebop.Tree;
import com.arsdigita.bebop.event.ActionEvent;
import com.arsdigita.bebop.event.ActionListener;
import com.arsdigita.bebop.event.FormProcessListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.event.FormSubmissionListener;
import com.arsdigita.bebop.event.TableActionAdapter;
import com.arsdigita.bebop.event.TableActionEvent;
import com.arsdigita.bebop.form.Widget;
import com.arsdigita.bebop.parameters.ArrayParameter;
import com.arsdigita.bebop.parameters.IntegerParameter;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.toolbox.ToolboxConstants;
import com.arsdigita.util.Assert;
import com.arsdigita.xml.Element;
import java.util.Iterator;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
/**
*
*/
public class ModalPanel extends ComponentMap {
private static final Logger LOGGER = LogManager.getLogger(ModalPanel.class);
private final IndexStack m_stack;
private Component m_default;
public ModalPanel() {
m_stack = new IndexStack();
m_default = new NullComponent();
put("__null__", m_default);
}
public void register(final Page page) {
super.register(page);
page.addComponentStateParam(this, m_stack);
// All this work is done to keep Bebop's notion of visibility
// in line with what ModalPanel thinks.
final Iterator iter = children();
while (iter.hasNext()) {
page.setVisibleDefault((Component) iter.next(), false);
}
page.addActionListener(new VisibilityListener());
}
private class VisibilityListener implements ActionListener {
public final void actionPerformed(final ActionEvent e) {
final PageState state = e.getPageState();
if (state.isVisibleOnPage(ModalPanel.this)) {
final Iterator iter = children();
while (iter.hasNext()) {
((Component) iter.next()).setVisible(state, false);
}
}
}
}
public final void generateXML(final PageState state,
final Element parent) {
top(state).setVisible(state, true);
if (isVisible(state)) {
top(state).generateXML(state, parent);
}
}
public final void add(final Component component) {
Assert.isUnlocked(this);
Assert.exists(component, Component.class);
put(component, component);
}
public void reset(final PageState state) {
super.reset(state);
clear(state);
}
public final void clear(final PageState state) {
LOGGER.debug("Clearing the stack");
m_stack.clear(state);
}
public final void push(final PageState state, final Component pushed) {
if (Assert.isEnabled()) {
Assert.exists(pushed, Component.class);
Assert.isTrue(containsKey(pushed),
"Component " + pushed + " is not a child "
+ "of this container");
}
if (!pushed.equals(top(state))) {
m_stack.push(state, state.getPage().stateIndex(pushed));
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Pushed " + top(state) + " visible");
LOGGER.debug("Stack is " + m_stack.toDebugString(state));
LOGGER.debug("Here", new Throwable());
}
}
}
public final void pop(final PageState state) {
if (m_stack.isEmpty(state)) {
LOGGER.debug("The stack is empty; nothing was popped");
} else {
m_stack.pop(state);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Popped " + top(state) + " visible");
LOGGER.debug("Stack is " + m_stack.toDebugString(state));
LOGGER.debug("Here", new Throwable());
}
}
}
public final Component top(final PageState state) {
if (m_stack.isEmpty(state)) {
return getDefault();
} else {
return state.getPage().getComponent(m_stack.top(state));
}
}
public final void setDefault(final Component defaalt) {
if (Assert.isEnabled()) {
Assert.isUnlocked(this);
Assert.exists(defaalt, Component.class);
Assert.isTrue(containsValue(defaalt),
defaalt + " is not one of my children");
}
m_default = defaalt;
LOGGER.debug("Default set to " + defaalt);
}
public final Component getDefault() {
return m_default;
}
// XXX for thinking about: in a different UI component framework,
// these connect defs could be reduced to just one or two.
// XXX does using toggle links in here make more sense from a
// saner-transition-management pov?
public final void connect(final ActionLink orig,
final Component dest) {
orig.addActionListener(new NavigationListener(dest));
}
public final void connect(final Table orig,
final int column,
final Component dest) {
orig.addTableActionListener(new TableNavigationListener(column, dest));
}
public final void connect(final List orig,
final Component dest) {
orig.addActionListener(new NavigationListener(dest));
}
public final void connect(final Tree orig,
final Component dest) {
orig.addActionListener(new NavigationListener(dest));
}
public final void connect(final FormSection orig,
final Component dest) {
orig.addProcessListener(new FormNavigationListener(dest));
}
public final void connect(final FormSection origForm,
final Widget origWidget,
final Object value,
final Component dest) {
origForm.addProcessListener(new WidgetNavigationListener(origWidget,
value, dest));
}
// Variants to handle forms.
public final void connect(final ActionLink orig,
final FormSection dest) {
connect(orig, (Component) dest);
dest.addSubmissionListener(new CancelListener(dest));
}
public final void connect(final Table orig,
final int column,
final FormSection dest) {
connect(orig, column, (Component) dest);
dest.addSubmissionListener(new CancelListener(dest, orig
.getRowSelectionModel()));
}
public final void connect(final List orig,
final FormSection dest) {
connect(orig, (Component) dest);
dest.addSubmissionListener(new CancelListener(dest, orig
.getSelectionModel()));
}
public final void connect(final Tree orig,
final FormSection dest) {
connect(orig, (Component) dest);
dest.addSubmissionListener(new CancelListener(dest, orig
.getSelectionModel()));
}
public final void connect(final FormSection orig,
final FormSection dest) {
connect(orig, (Component) dest);
dest.addSubmissionListener(new CancelListener(dest));
}
public final void connect(final Form origForm,
final Widget origWidget,
final Object value,
final FormSection dest) {
connect(origForm, origWidget, value, (Component) dest);
dest.addSubmissionListener(new CancelListener(dest));
}
public final void connect(final FormSection orig) {
orig.addProcessListener(new FinishListener());
}
public final void connect(final FormSection orig,
final SingleSelectionModel model) {
orig.addProcessListener(new FinishListener(model));
}
public final void resume(final FormSection orig,
final Component dest) {
orig.addProcessListener(new ResumeListener(dest));
}
protected final class NavigationListener implements ActionListener {
private final Component m_target;
public NavigationListener(final Component target) {
Assert.exists(target, Component.class);
m_target = target;
}
public final void actionPerformed(final ActionEvent e) {
final PageState state = e.getPageState();
final Object source = e.getSource();
if (source instanceof Tree && !((Tree) source).isSelected(state)) {
// Tree fires an action event on expand. We do not
// want to do any work in that case.
} else {
push(state, m_target);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Navigating to " + m_target);
}
}
}
}
protected final class TableNavigationListener extends TableActionAdapter {
private final int m_column;
private final Component m_target;
public TableNavigationListener(final int column,
final Component target) {
Assert.exists(target, "Component target");
m_column = column;
m_target = target;
}
public final void cellSelected(final TableActionEvent e) {
if (e.getColumn().intValue() == m_column) {
push(e.getPageState(), m_target);
}
}
}
protected final class FormNavigationListener
implements FormProcessListener {
private final Component m_target;
public FormNavigationListener(final Component target) {
Assert.exists(target, "Component target");
m_target = target;
}
@Override
public final void process(final FormSectionEvent e)
throws FormProcessException {
push(e.getPageState(), m_target);
}
}
protected final class WidgetNavigationListener
implements FormProcessListener {
private final Widget m_widget;
private final Object m_value;
private final Component m_target;
public WidgetNavigationListener(final Widget widget,
final Object value,
final Component target) {
Assert.exists(widget, "Widget widget");
Assert.exists(value, "String value");
Assert.exists(target, "Component target");
m_widget = widget;
m_value = value;
m_target = target;
}
@Override
public final void process(final FormSectionEvent e)
throws FormProcessException {
final PageState state = e.getPageState();
if (m_value.equals(m_widget.getValue(state))) {
push(state, m_target);
}
}
}
protected final class CancelListener implements FormSubmissionListener {
private final Cancellable m_cancellable;
private SingleSelectionModel m_model;
public CancelListener(final FormSection form) {
Assert.exists(form, "FormSection form");
if (form instanceof Cancellable) {
m_cancellable = (Cancellable) form;
} else {
m_cancellable = null;
LOGGER.warn("Form " + form + " does not "
+ "implement Cancellable.");
// See note above (import statement)!!
// StackTraces.log("The form was created at", form, s_log, "warn");
}
}
public CancelListener(final FormSection form,
final SingleSelectionModel model) {
this(form);
Assert.exists(model, "SingleSelectionModel model");
m_model = model;
}
@Override
public final void submitted(final FormSectionEvent e)
throws FormProcessException {
final PageState state = e.getPageState();
if (m_cancellable != null && m_cancellable.isCancelled(state)) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Form processing is cancelled; reverting to "
+ "pre-excursion state");
}
pop(state);
// If we got here via a list or table, clear its
// selection upon cancelling. If we were strictly
// correct, we'd revert to the former selection in the
// model, but we're in no position to support that.
if (m_model != null) {
m_model.clearSelection(state);
}
throw new FormProcessException(
"cancelled",
new GlobalizedMessage("toolbox.ui.cancel_msg",
ToolboxConstants.TOOLBOX_BUNDLE));
}
}
}
protected final class FinishListener implements FormProcessListener {
private SingleSelectionModel m_model = null;
public FinishListener() {
super();
}
public FinishListener(final SingleSelectionModel model) {
this();
m_model = model;
}
public final void process(final FormSectionEvent e)
throws FormProcessException {
final PageState state = e.getPageState();
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Form processing went as planned and there is "
+ "no subsequent step; reverting to "
+ "pre-excursion state");
}
pop(state);
if (m_model != null) {
m_model.clearSelection(state);
}
}
}
protected final class ResumeListener implements FormProcessListener {
private final Component m_target;
public ResumeListener(final Component target) {
m_target = target;
}
public final void process(final FormSectionEvent e)
throws FormProcessException {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Resuming the pre-excursion state");
}
final PageState state = e.getPageState();
while (!top(state).equals(m_target)) {
pop(state);
}
}
}
protected final class ResetListener implements ActionListener {
public ResetListener() {
super();
}
public final void actionPerformed(final ActionEvent e) {
reset(e.getPageState());
}
}
private class IndexStack extends ArrayParameter {
IndexStack() {
super(new IntegerParameter("stack"));
}
final boolean isEmpty(final PageState state) {
final Integer[] stack = (Integer[]) state.getValue(this);
return stack == null || stack.length == 0;
}
final void clear(final PageState state) {
state.setValue(this, null);
}
final int top(final PageState state) {
final Integer[] stack = (Integer[]) state.getValue(this);
if (stack == null || stack.length == 0) {
throw new IllegalStateException("The stack is empty");
} else {
return stack[stack.length - 1].intValue();
}
}
final void push(final PageState state, final int index) {
final Integer[] before = (Integer[]) state.getValue(this);
if (before == null || before.length == 0) {
state.setValue(this, new Integer[]{new Integer(index)});
} else {
final Integer[] after = new Integer[before.length + 1];
for (int i = 0; i < before.length; i++) {
after[i] = before[i];
}
after[before.length] = new Integer(index);
state.setValue(this, after);
}
}
final void pop(final PageState state) {
final Integer[] before = (Integer[]) state.getValue(this);
if (before == null || before.length == 0) {
throw new IllegalStateException("The stack is empty");
} else {
final Integer[] after = new Integer[before.length - 1];
for (int i = 0; i < after.length; i++) {
after[i] = before[i];
}
state.setValue(this, after);
}
}
final String toDebugString(final PageState state) {
final StringBuffer buffer = new StringBuffer();
final Integer[] stack = (Integer[]) state.getValue(this);
if (stack == null || stack.length == 0) {
return "[]";
} else {
for (int i = 0; i < stack.length; i++) {
buffer.append(",");
buffer.append(stack[i]);
}
return "[" + buffer.toString().substring(1) + "] <- top";
}
}
}
}

View File

@ -1,104 +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.Page;
import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.FormModel;
import com.arsdigita.xml.Element;
import java.util.Iterator;
import java.util.Collections;
import javax.servlet.ServletException;
/**
* @author Justin Ross &lt;jross@redhat.com&gt;
* @version $Id$
*/
public final class NullComponent implements Component {
public void generateXML(PageState state, Element parent) {
// Empty
}
public void respond(PageState state) throws ServletException {
// Empty
}
public Iterator children() {
return Collections.EMPTY_LIST.iterator();
}
public void register(Page page) {
// Empty
}
public void register(Form form, FormModel model) {
// Empty
}
public String getClassAttr() {
return null;
}
public void setClassAttr(String clacc) {
// Empty
}
public String getStyleAttr() {
return null;
}
public void setStyleAttr(String style) {
// Empty
}
public String getIdAttr() {
return null;
}
public void setIdAttr(String id) {
// Empty
}
public Component setKey(String key) {
return null;
}
public String getKey() {
return null;
}
public boolean isVisible(PageState state) {
return false;
}
public void setVisible(PageState state, boolean visible) {
// Empty
}
public void lock() {
// Empty
}
public boolean isLocked() {
return true;
}
}

View File

@ -1,62 +0,0 @@
/*
* Copyright (C) 2017 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 com.arsdigita.bebop.Component;
import com.arsdigita.bebop.PageState;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.util.Assert;
import com.arsdigita.xml.Element;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public final class Property {
private final String title;
private final String value;
public Property(final String title, final String value) {
super();
Assert.exists(title, "String title");
this.title = title;
this.value = value;
}
public Property(final GlobalizedMessage title, final String value) {
this(title.localize().toString(), value);
}
public Property(final GlobalizedMessage title, final GlobalizedMessage value) {
this(title.localize().toString(), value.localize().toString());
}
public Property(final String title, final GlobalizedMessage value) {
this(title, value.localize().toString());
}
public void generateXML(final PageState state, final Element parent) {
final Element elem = parent.newChildElement("bebop:property",
Component.BEBOP_XML_NS);
elem.addAttribute("title", title);
elem.addAttribute("value", value);
}
}

View File

@ -1,65 +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.xml.Element;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author Justin Ross
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public abstract class PropertyList extends SimpleComponent {
private static final RequestLocal PROPERTIES = new RequestLocal() {
@Override
protected final Object initialValue(final PageState state) {
return new ArrayList<>();
}
};
public PropertyList() {
super();
}
@SuppressWarnings("unchecked")
protected List<Property> properties(final PageState state) {
return (List<Property>) PROPERTIES.get(state);
}
@Override
public final void generateXML(final PageState state, final Element parent) {
if (isVisible(state)) {
final Element nav = parent.newChildElement("bebop:propertyList",
BEBOP_XML_NS);
properties(state).forEach(property -> property.generateXML(state,
nav));
}
}
}

View File

@ -1,47 +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.xml.Element;
public class ProxyComponent extends ComponentMap implements Resettable {
private final Component m_child;
public ProxyComponent(final Component child) {
m_child = child;
put("child", child);
}
@Override
public boolean isVisible(final PageState state) {
return m_child.isVisible(state);
}
@Override
public void generateXML(final PageState state, final Element parent) {
m_child.generateXML(state, parent);
}
}

View File

@ -1,50 +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 com.arsdigita.bebop.event.PageEvent;
import javax.persistence.criteria.CriteriaQuery;
/**
* This event is fired by the {@link DataTable} class
*
* @param <T> Type of the entities retrieved by the query.
* @see QueryListener
*/
public class QueryEvent<T> extends PageEvent {
private static final long serialVersionUID = -3616223193853983580L;
private CriteriaQuery<T> query;
public QueryEvent(final Component source,
final PageState state,
final CriteriaQuery<T> query) {
super(source, state);
this.query = query;
}
public CriteriaQuery<T> getDataQuery() {
return query;
}
}

View File

@ -1,31 +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 java.util.EventListener;
/**
* This listener can be added to {@link DataTable} in order to
* set filters on the query, or perform other customisations.
*/
public interface QueryListener extends EventListener {
void queryPending(QueryEvent event);
}

View File

@ -1,123 +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.Form;
import com.arsdigita.bebop.FormModel;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.SimpleComponent;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.util.Assert;
import com.arsdigita.xml.Element;
import java.util.ArrayList;
import java.util.Iterator;
/**
* <p>
* A simple layout panel with top, bottom, left, right, and body sections.</p>
*
* @author Justin Ross &lt;jross@redhat.com&gt;
* @version $Id$
*/
public class Section extends SimpleComponent {
private final ArrayList m_children;
private Component m_heading;
private Component m_body;
public Section(final Component heading, final Component body) {
m_children = new ArrayList(2);
m_heading = heading;
m_body = body;
}
public Section(final GlobalizedMessage heading, final Component body) {
this(new Label(heading), body);
}
public Section(final Component heading) {
this(heading, new NullComponent());
}
public Section(final GlobalizedMessage heading) {
this(heading, new NullComponent());
}
public Section() {
this(new NullComponent(), new NullComponent());
}
public final void setHeading(final Component heading) {
Assert.exists(heading, "Component header");
Assert.isUnlocked(this);
m_heading = heading;
}
public final void setHeading(final GlobalizedMessage message) {
setHeading(new Label(message));
}
public final void setBody(final Component body) {
Assert.exists(body, "Component body");
Assert.isUnlocked(this);
m_body = body;
}
public void register(final Page page) {
super.register(page);
m_children.add(m_heading);
m_children.add(m_body);
}
public void register(final Form form, final FormModel model) {
super.register(form, model);
m_children.add(m_heading);
m_children.add(m_body);
}
public final Iterator children() {
return m_children.iterator();
}
public final void generateXML(final PageState state, final Element parent) {
if (isVisible(state)) {
final Element section = parent.newChildElement("bebop:section",
BEBOP_XML_NS);
final Element heading = section.newChildElement("bebop:heading",
BEBOP_XML_NS);
m_heading.generateXML(state, heading);
final Element body = section.newChildElement("bebop:body",
BEBOP_XML_NS);
m_body.generateXML(state, body);
}
}
}

View File

@ -1,115 +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.SimpleContainer;
import com.arsdigita.bebop.PageState;
import org.libreccm.security.Party;
import com.arsdigita.xml.Element;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.security.Shiro;
/**
* <p>A <code>SecurityContainer</code> adds an access check to a
* {@link com.arsdigita.bebop.Component}. The child component is made
* invisible if the current user cannot access the it.</p>
*
* <p><b>Warning:</b> - A call to <code>setVisible(state, true)</code> does
* not necessarily mean that <code>isVisible(state)</code> will return
* true, since the <code>isVisible</code> also takes security checks
* into account.</p>
*
* <p>General usage of the <code>SecurityContainer</code> is as follows:</p>
*
* <blockquote><code><pre>
* MyComponent c = new MyComponent();
* SecurityContainer sc = new SecurityContainer(c) {
* protected boolean canAccess(User user, PageState state) {
* return ( user != null );
* }
* };
* add(sc);
* </pre></code></blockquote>
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
* @author Michael Pih
*/
public abstract class SecurityContainer extends SimpleContainer {
/**
* This default constructor should be followed by calls to
* <code>add</code>.
* */
public SecurityContainer() {}
/**
* Create a <code>SecurityContainer</code> around a child component.
*
* @param component The child component
*/
public SecurityContainer(final Component component) {
add(component);
}
/**
* Is the component visible?
*
* @param state The page state
* @return true if the component is visible, false otherwise
*/
@Override
public boolean isVisible(final PageState state) {
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final Shiro shiro = cdiUtil.findBean(Shiro.class);
final Party party = shiro.getUser().get();
return ( super.isVisible(state) && canAccess(party, state) );
}
/**
* Returns true if the current user can access the child component.
*
* @param party The party
* @param state The page state
* @return true if the access checks pass, false otherwise
*/
protected abstract boolean canAccess(final Party party,
final PageState state);
/**
* Generates the XML for the child component if this
* component is visible.
*
* @param state The page state
* @param parent The parent DOM element
*/
@Override
public void generateXML(final PageState state,
final Element parent) {
if ( isVisible(state) ) {
super.generateXML(state, parent);
}
}
}

View File

@ -1,343 +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.ActionLink;
import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.List;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.Resettable;
import com.arsdigita.bebop.SingleSelectionModel;
import com.arsdigita.bebop.Tree;
import com.arsdigita.bebop.event.ChangeEvent;
import com.arsdigita.bebop.event.ChangeListener;
import com.arsdigita.bebop.list.ListModelBuilder;
import com.arsdigita.bebop.tree.TreeModelBuilder;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.util.Assert;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
/**
* @param <T> Type managed by the {@link SingleSelectionModel} used in instances
* of this class.
*
* @author unknown
* @author <a href="jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class SelectionPanel<T> extends LayoutPanel implements Resettable {
private static final Logger LOGGER = LogManager.getLogger(
SelectionPanel.class);
private SingleSelectionModel<T> selectionModel;
private Component selector;
private ActionGroup actionGroup;
private final ModalPanel body;
private Component introPane;
private Component itemPane;
private ActionLink addLink;
private Form addForm;
private ActionLink editLink;
private Form editForm;
private ActionLink deleteLink;
private Form deleteForm;
protected void build(final Component title,
final Component selector,
final SingleSelectionModel<T> model) {
selectionModel = model;
this.selector = selector;
final Section section = new Section();
setLeft(section);
section.setHeading(title);
actionGroup = new ActionGroup();
section.setBody(actionGroup);
actionGroup.setSubject(selector);
}
protected SelectionPanel() {
body = new ModalPanel();
setBody(body);
introPane = new NullComponent();
body.add(introPane);
body.setDefault(introPane);
itemPane = new NullComponent();
body.add(itemPane);
addLink = null;
addForm = null;
editLink = null;
editForm = null;
deleteLink = null;
deleteForm = null;
}
public SelectionPanel(final Component title,
final Component selector) {
this();
if (Assert.isEnabled()) {
Assert.exists(title, Component.class);
Assert.exists(selector, Component.class);
Assert.isTrue(selector instanceof Tree || selector instanceof List);
}
// Making up now for some untoward modeling in Bebop.
if (selector instanceof List) {
final List list = (List) selector;
list.addChangeListener(new SelectionListener());
build(title, list, list.getSelectionModel());
} else {
final Tree tree = (Tree) selector;
tree.addChangeListener(new SelectionListener());
build(title, tree, tree.getSelectionModel());
}
}
public SelectionPanel(final Component title,
final Component selector,
final SingleSelectionModel<T> model) {
this();
if (Assert.isEnabled()) {
Assert.exists(title, Component.class);
Assert.exists(selector, Component.class);
}
build(title, selector, model);
}
public SelectionPanel(final GlobalizedMessage title,
final Component selector) {
this(new Label(title), selector);
}
public SelectionPanel(final GlobalizedMessage title,
final Component selector,
final SingleSelectionModel<T> model) {
this(new Label(title), selector, model);
}
public SelectionPanel(final Component title,
final TreeModelBuilder builder) {
this(title, new Tree(builder));
}
public SelectionPanel(final GlobalizedMessage title,
final TreeModelBuilder builder) {
this(new Label(title), builder);
}
public SelectionPanel(final Component title,
final ListModelBuilder builder) {
this(title, new List(builder));
}
public SelectionPanel(final GlobalizedMessage title,
final ListModelBuilder builder) {
this(new Label(title), builder);
}
@Override
public void reset(final PageState state) {
LOGGER.debug("Resetting to default initial state");
if (selector instanceof Resettable) {
((Resettable) selector).reset(state);
} else {
selectionModel.clearSelection(state);
}
// The SelectionListener, on hearing the clearSelection event,
// will reset the components in m_body.
}
public final void addAction(final Component action) {
actionGroup.addAction(action);
}
public final void addAction(final Component action, final String clacc) {
actionGroup.addAction(action, clacc);
}
public final Component getSelector() {
return selector;
}
protected final void setSelector(final Component selector) {
this.selector = selector;
}
public final void setSelectionModel(final SingleSelectionModel<T> model) {
selectionModel = model;
}
public final SingleSelectionModel<T> getSelectionModel() {
return selectionModel;
}
public final ActionLink getAddLink() {
return addLink;
}
public final Form getAddForm() {
return addForm;
}
public final void setAdd(final GlobalizedMessage message,
final Form form) {
setAdd(new ActionLink(new Label(message)), form);
}
public final void setAdd(final ActionLink addLink,
final Form form) {
Assert.exists(addLink, "ActionLink addLink");
Assert.exists(form, "Form form");
Assert.isUnlocked(this);
addForm = form;
body.add(addForm);
this.addLink = addLink;
body.connect(addLink, addForm);
}
public final ActionLink getEditLink() {
return editLink;
}
public final Form getEditForm() {
return editForm;
}
public final void setEdit(final GlobalizedMessage message,
final Form form) {
setEdit(new ActionLink(new Label(message)), form);
}
public final void setEdit(final ActionLink editLink,
final Form form) {
Assert.exists(editLink, "ActionLink editLink");
Assert.exists(form, "Form form");
Assert.isUnlocked(this);
editForm = form;
body.add(editForm);
this.editLink = editLink;
body.connect(editLink, editForm);
body.connect(editForm);
}
public final ActionLink getDeleteLink() {
return deleteLink;
}
public final Form getDeleteForm() {
return deleteForm;
}
public final void setDelete(final GlobalizedMessage message,
final Form form) {
setDelete(new ActionLink(new Label(message)), form);
}
public final void setDelete(final ActionLink deleteLink,
final Form form) {
Assert.exists(deleteLink, "ActionLink deleteLink");
Assert.exists(form, "Form form");
Assert.isUnlocked(this);
deleteForm = form;
body.add(deleteForm);
this.deleteLink = deleteLink;
body.connect(deleteLink, deleteForm);
}
public final ModalPanel getBody() {
return body;
}
public final Component getIntroPane() {
return introPane;
}
public final void setIntroPane(final Component pane) {
Assert.exists(pane, Component.class);
Assert.isUnlocked(this);
introPane = pane;
body.add(introPane);
body.setDefault(introPane);
}
public final Component getItemPane() {
return itemPane;
}
public final void setItemPane(final Component pane) {
Assert.exists(pane, "Component pane");
Assert.isUnlocked(this);
itemPane = pane;
body.add(itemPane);
}
public class SelectionListener implements ChangeListener {
@Override
public final void stateChanged(final ChangeEvent e) {
LOGGER.debug("Selection state changed; I may change "
+ "the body's visible pane");
final PageState state = e.getPageState();
body.reset(state);
if (selectionModel.isSelected(state)) {
LOGGER.debug("The selection model is selected; displaying "
+ "the item pane");
body.push(state, itemPane);
}
}
}
}

View File

@ -1,66 +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 org.libreccm.pagemodel.ui;
import com.arsdigita.bebop.tree.TreeNode;
import com.arsdigita.kernel.KernelConfig;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.l10n.GlobalizationHelper;
import org.libreccm.web.CcmApplication;
import java.util.Locale;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Deprecated
public class ApplicationTreeNode implements TreeNode {
private final CcmApplication application;
public ApplicationTreeNode(final CcmApplication application) {
this.application = application;
}
public CcmApplication getApplication() {
return application;
}
@Override
public Object getKey() {
return application.getPrimaryUrl();
}
@Override
public Object getElement() {
final GlobalizationHelper globalizationHelper = CdiUtil.createCdiUtil().findBean(GlobalizationHelper.class);
final Locale locale = globalizationHelper.getNegotiatedLocale();
if (application.getTitle().hasValue(locale)) {
return application.getTitle().hasValue(locale);
} else {
final Locale defaultLocale = KernelConfig.getConfig().getDefaultLocale();
return application.getTitle().getValue(defaultLocale);
}
}
}

View File

@ -1,54 +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 org.libreccm.pagemodel.ui;
import com.arsdigita.bebop.tree.TreeNode;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.web.CcmApplication;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Deprecated
class ApplicationTypeTreeNode implements TreeNode {
private final Class<? extends CcmApplication> appType;
protected ApplicationTypeTreeNode(
final Class<? extends CcmApplication> appType) {
this.appType = appType;
}
@Override
public Object getKey() {
return appType.getName();
}
@Override
public Object getElement() {
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final PageModelTreeController controller = cdiUtil.findBean(
PageModelTreeController.class);
return controller.getAppTypeTitle(appType);
}
}

View File

@ -1,42 +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 org.libreccm.pagemodel.ui;
import com.arsdigita.bebop.Tree;
import com.arsdigita.toolbox.ui.LayoutPanel;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Deprecated
public class PageModelPane extends LayoutPanel {
private final Tree tree;
public PageModelPane() {
super();
setClassAttr("sidebarNavPanel");
tree = new Tree(new PageModelTreeModelBuilder());
}
}

View File

@ -1,48 +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 org.libreccm.pagemodel.ui;
import org.libreccm.web.ApplicationManager;
import org.libreccm.web.ApplicationType;
import org.libreccm.web.CcmApplication;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Deprecated
@RequestScoped
public class PageModelTreeController {
@Inject
private ApplicationManager applicationManager;
public String getAppTypeTitle(final Class<? extends CcmApplication> appType) {
final ApplicationType applicationType = applicationManager.
getApplicationTypes().get(appType.getClass().getName());
return applicationManager.getApplicationTypeTitle(applicationType);
}
}

View File

@ -1,48 +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 org.libreccm.pagemodel.ui;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.Tree;
import com.arsdigita.bebop.tree.TreeModel;
import com.arsdigita.bebop.tree.TreeModelBuilder;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Deprecated
class PageModelTreeModelBuilder implements TreeModelBuilder {
@Override
public TreeModel makeModel(final Tree tree, final PageState state) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void lock() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public boolean isLocked() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}

View File

@ -1,62 +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 org.libreccm.pagemodel.ui;
import com.arsdigita.bebop.tree.TreeNode;
import com.arsdigita.kernel.KernelConfig;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.l10n.GlobalizationHelper;
import org.libreccm.pagemodel.PageModel;
import java.util.Locale;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Deprecated
class PageModelTreeNode implements TreeNode {
private final PageModel pageModel;
protected PageModelTreeNode(final PageModel pageModel) {
this.pageModel = pageModel;
}
@Override
public Object getKey() {
return pageModel.getName();
}
@Override
public Object getElement() {
final GlobalizationHelper globalizationHelper = CdiUtil.createCdiUtil().
findBean(GlobalizationHelper.class);
final Locale locale = globalizationHelper.getNegotiatedLocale();
if (pageModel.getTitle().hasValue(locale)) {
return pageModel.getTitle().getValue(locale);
} else {
final Locale defaultLocale = KernelConfig.getConfig().
getDefaultLocale();
return pageModel.getTitle().getValue(defaultLocale);
}
}
}

View File

@ -1,82 +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 org.libreccm.pagemodel.ui;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.tree.TreeModel;
import com.arsdigita.bebop.tree.TreeNode;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.pagemodel.PageModelRepository;
import org.libreccm.web.CcmApplication;
import java.util.Iterator;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@Deprecated
class PageTreeModel implements TreeModel {
@Override
public TreeNode getRoot(final PageState state) {
return new RootNode();
}
@Override
public boolean hasChildren(final TreeNode node, final PageState state) {
if (node instanceof RootNode) {
return true;
} else if (node instanceof ApplicationTreeNode) {
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final PageModelRepository pageModelRepo = cdiUtil.findBean(
PageModelRepository.class);
final CcmApplication application = ((ApplicationTreeNode) node)
.getApplication();
final long count = pageModelRepo.countLiveByApplication(application);
return count > 0;
} else if (node instanceof PageModelTreeNode) {
return false;
} else {
throw new IllegalArgumentException(String.format(
"Unexpected node type: \"%s\".", node.getClass().getName()));
}
}
@Override
public Iterator getChildren(final TreeNode node, final PageState state) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
private class RootNode implements TreeNode {
@Override
public Object getKey() {
return "-1";
}
@Override
public Object getElement() {
return "PageModels";
}
}
}