Removed depcrecated packages com.arsdigita.toolbox.ui and org.libreccm.pagemodel.ui
parent
af6bee2cdc
commit
7cd39aa321
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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 <jross@redhat.com>
|
|
||||||
*/
|
|
||||||
public class ActionGroup extends ComponentSet {
|
|
||||||
|
|
||||||
private static final Logger LOGGER = LogManager.getLogger(ActionGroup.class);
|
|
||||||
|
|
||||||
private Component m_subject;
|
|
||||||
private final ArrayList m_actions = new ArrayList();
|
|
||||||
|
|
||||||
public static final String ADD = "add";
|
|
||||||
public static final String EDIT = "edit";
|
|
||||||
public static final String DELETE = "delete";
|
|
||||||
public static final String RETURN = "return";
|
|
||||||
|
|
||||||
public final void setSubject(final Component subject) {
|
|
||||||
Assert.exists(subject, "Component subject");
|
|
||||||
Assert.isUnlocked(this);
|
|
||||||
|
|
||||||
m_subject = subject;
|
|
||||||
add(m_subject);
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void addAction(final Component action, final String clacc) {
|
|
||||||
Assert.exists(action, "Component action");
|
|
||||||
Assert.isUnlocked(this);
|
|
||||||
|
|
||||||
m_actions.add(new Object[]{action, clacc});
|
|
||||||
add(action);
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void addAction(final Component action) {
|
|
||||||
addAction(action, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public final void generateXML(final PageState state, final Element parent) {
|
|
||||||
if (isVisible(state)) {
|
|
||||||
final Element layout = parent.newChildElement("bebop:actionGroup",
|
|
||||||
BEBOP_XML_NS);
|
|
||||||
|
|
||||||
final Element subject = layout.newChildElement("bebop:subject",
|
|
||||||
BEBOP_XML_NS);
|
|
||||||
|
|
||||||
if (m_subject != null) {
|
|
||||||
m_subject.generateXML(state, subject);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Iterator iter = m_actions.iterator(); iter.hasNext();) {
|
|
||||||
final Object[] spec = (Object[]) iter.next();
|
|
||||||
final Component component = (Component) spec[0];
|
|
||||||
final String clacc = (String) spec[1];
|
|
||||||
|
|
||||||
if (component.isVisible(state)) {
|
|
||||||
final Element action = layout
|
|
||||||
.newChildElement("bebop:action", BEBOP_XML_NS);
|
|
||||||
|
|
||||||
if (clacc != null) {
|
|
||||||
action.addAttribute("class", clacc);
|
|
||||||
}
|
|
||||||
|
|
||||||
component.generateXML(state, action);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
@ -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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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(" ", 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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 <jross@redhat.com>
|
|
||||||
*/
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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 <jross@redhat.com>
|
|
||||||
* @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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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 <jross@redhat.com>
|
|
||||||
* @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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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.
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue