Removed depcrecated Bebop Tree component

pull/28/head
Jens Pelzetter 2022-03-22 19:38:51 +01:00
parent 8f380e40ec
commit 0e3ae4e99f
8 changed files with 0 additions and 1317 deletions

View File

@ -1,784 +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.bebop;
import static com.arsdigita.bebop.Component.*;
import com.arsdigita.bebop.event.ActionEvent;
import com.arsdigita.bebop.event.ActionListener;
import com.arsdigita.bebop.event.ChangeEvent;
import com.arsdigita.bebop.event.ChangeListener;
import com.arsdigita.bebop.event.EventListenerList;
import com.arsdigita.bebop.event.TreeExpansionEvent;
import com.arsdigita.bebop.event.TreeExpansionListener;
import com.arsdigita.bebop.parameters.ParameterModel;
import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.bebop.tree.DefaultTreeCellRenderer;
import com.arsdigita.bebop.tree.TreeCellRenderer;
import com.arsdigita.bebop.tree.TreeModel;
import com.arsdigita.bebop.tree.TreeModelBuilder;
import com.arsdigita.bebop.tree.TreeNode;
import com.arsdigita.util.Assert;
import com.arsdigita.util.LockableImpl;
import com.arsdigita.xml.Element;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.Iterator;
/**
* Used to print a tree structure. Nodes can be in expanded or collapsed state.
* <code>Tree</code> uses the getChildren() and getRoot() methods from
* TreeModel and traverses the iterator to get to all the nodes.
*
* This class keeps track of which nodes are expanded and collapsed and the
* hierarchy of nodes, and displays the tree correspondingly.
*
* @author David Lutterkort
* @author Stanislav Freidin
* @author Tri Tran
* @version $Id$
*/
public class Tree extends SimpleComponent implements Resettable {
private static final Logger LOGGER = LogManager.getLogger(Tree.class);
private static final boolean s_selectAttributeEnabled = BebopConfig
.getConfig().isTreeSelectEnabled();
// Any node id in the currentState is equivalent
// to that node being expanded. If node id is
// NOT in the currentState, then it's collapsed.
private static final String CURRENT_STATE = "state";
private static final String EXPAND_EVENT = "expand";
private static final String COLLAPSE_EVENT = "collapse";
private static final String SELECT = "sel";
private static final String SELECT_EVENT = "s";
private static final boolean EXPANDED = true;
private static final boolean NOT_EXPANDED = false; // Collapsed
private static final boolean LEAF = true;
private static final boolean NOT_LEAF = false;
protected StringParameter m_currentState;
protected TreeModelBuilder m_builder;
private RequestLocal m_model;
private TreeModel m_tree;
private EventListenerList m_listeners;
private SingleSelectionModel m_selection;
private ChangeListener m_changeListener;
private Element treeElement;
private TreeCellRenderer m_renderer;
/**
* Constructs a new <code>Tree</code> using the specified
* {@link TreeModelBuilder}. The {@link TreeModelBuilder} will instantiate a
* {@link TreeModel} during each request.
*
* @param b the {@link TreeModelBuilder}
*/
public Tree(TreeModelBuilder b) {
super();
m_currentState = new StringParameter(CURRENT_STATE);
m_builder = b;
m_renderer = new DefaultTreeCellRenderer();
m_selection = new ParameterSingleSelectionModel(new StringParameter(
SELECT));
m_listeners = new EventListenerList();
m_model = new RequestLocal() {
protected Object initialValue(PageState s) {
return getModelBuilder().makeModel(Tree.this, s);
}
};
m_tree = null;
}
/**
* Deprecated constructor that takes a default {@link TreeModel} and wraps
* it in a dummy TreeModelBuilder.
*
* @param t the TreeModel
*
* @deprecated This constructor has been deprecated in favor of
* <code>Tree(TreeModelBuilder b)</code>. It is not practical to hardwire
* the <code>TreeModel</code> into the <code>Tree</code>, since the model
* may change during each request. It is possible to write the
* model-instantiation code in {@link TreeModel#getRoot(PageState)}, but the
* {@link TreeModelBuilder} fits better into the pattern which has already
* been established by {@link List} and {@link Table}
*/
public Tree(TreeModel t) {
this(new WrapperModelBuilder());
m_tree = t;
}
/**
* Registers the two parameters to the page.
*/
public void register(Page p) {
Assert.isUnlocked(this);
p.addComponent(this);
p.addComponentStateParam(this, m_currentState);
p.addComponentStateParam(this, getSelectionModel().getStateParameter());
}
/**
* Clears the request state of the tree.
*/
public void reset(final PageState state) {
clearSelection(state);
clearExpansionState(state);
}
/**
* Returns the tree model used for this tree.
*
* @return a <code>TreeModel</code>.
*
* @see #setTreeModel setTreeModel
* @see TreeModel
* @deprecated Use {@link #getTreeModel(PageState)} instead
*/
public final TreeModel getTreeModel() {
return m_tree;
}
/**
* Returns the {@link TreeModel} used by the tree for the current request.
*
* @param s the page state
*/
public TreeModel getTreeModel(PageState s) {
return (TreeModel) m_model.get(s);
}
/**
* @return the {@link TreeModelBuilder} used to build the tree model for
* this tree.
*/
public final TreeModelBuilder getModelBuilder() {
return m_builder;
}
/**
* @param b the new {@link TreeModelBuilder} for the tree
*/
public void setModelBuilder(TreeModelBuilder b) {
Assert.isUnlocked(this);
m_builder = b;
}
/**
* Sets the tree model used for this tree.
*
* @return a <code>TreeModel</code>.
*
* @see #setTreeModel setTreeModel
* @see TreeModel
*/
public void setTreeModel(TreeModel m) {
Assert.isUnlocked(this);
m_tree = m;
}
/**
* Sets the selection model, which keeps track of which node is currently
* selected. It can be used to manipulate the selection programmatically.
*
* @param m the new selection model
*/
public void setSelectionModel(SingleSelectionModel m) {
Assert.isUnlocked(this);
m_selection = m;
LOGGER.debug("New model: " + m);
}
/**
* Gets the selection model, which keeps track of which node is currently
* selected. It can be used to manipulate the selection programmatically.
*
* @return the model used by the tree to keep track of the selected node.
*/
public final SingleSelectionModel getSelectionModel() {
return m_selection;
}
/**
* Gets the key for the selected node. This will only be a valid key if
* {@link #isSelected isSelected} is <code>true</code>.
*
* @param state represents the state of the current request
*
* @return the key for the selected node.
*
* @pre isSelected(state)
*/
public Object getSelectedKey(PageState state) {
return m_selection.getSelectedKey(state);
}
/**
* Sets the selection to the one with the specified key. If <code>key</code>
* was not selected already, fires the {@link
* ChangeEvent}.
*
* @param state represents the state of the current request
* @param key the key for the selected node
*
* @see #fireStateChanged fireStateChanged
*/
public void setSelectedKey(PageState state, Object key) {
m_selection.setSelectedKey(state, key);
}
/**
* Returns <code>true</code> if one of the nodes is currently selected.
*
* @param state represents the state of the current request
*
* @return <code>true</code> if one of the nodes is selected;
* <code>false</code> otherwise.
*/
public boolean isSelected(PageState state) {
return m_selection.isSelected(state);
}
/**
* Clears the selection in the request represented by <code>state</code>.
*
* @param state represents the state of the current request
*
* @post ! isSelected(state)
*/
public void clearSelection(PageState state) {
m_selection.clearSelection(state);
}
/**
* Tells whether the tree has state on the request for tree node expansion.
*/
public final boolean hasExpansionState(final PageState state) {
return state.getValue(m_currentState) != null;
}
/**
* Clears any tree node expansion state on the request.
*/
public final void clearExpansionState(final PageState state) {
state.setValue(m_currentState, null);
}
/**
* Creates the change listener used for forwarding change events fired by
* the selection model to change listeners registered with the tree. The
* returned change listener refires the event with the tree, rather than the
* selection model, as source.
*
* @return the change listener used internally by the tree.
*/
protected ChangeListener createChangeListener() {
return new ChangeListener() {
public void stateChanged(ChangeEvent e) {
fireStateChanged(e.getPageState());
}
};
}
/**
* Adds a change listener. A change event is fired whenever the selected
* tree node changes during the processing of a request. The change event
* that listeners receive names the tree as the source.
*
* @param l the change listener to run when the selected item changes in a
* request
*
* @pre ! isLocked()
*/
public void addChangeListener(ChangeListener l) {
Assert.isUnlocked(this);
if (m_changeListener == null) {
m_changeListener = createChangeListener();
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Adding listener " + l + " to " + this);
}
m_selection.addChangeListener(m_changeListener);
}
m_listeners.add(ChangeListener.class, l);
}
/**
* Removes a change listener. The listener should have been previously added
* with {@link #addChangeListener addChangeListener}, although no error is
* signalled if the change listener is not found among the tree's listeners.
*
* @param l the change listener to remove from the tree
*/
public void removeChangeListener(ChangeListener l) {
Assert.isUnlocked(this);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Removing listener " + l + " from " + this);
}
m_listeners.remove(ChangeListener.class, l);
}
/**
* Fires a change event to signal that the selected list item has changed in
* the request represented by <code>state</code>. The source of the event is
* the tree.
*
* @param state represents the state of the current request
*/
protected void fireStateChanged(PageState state) {
Iterator i = m_listeners.getListenerIterator(ChangeListener.class);
ChangeEvent e = null;
while (i.hasNext()) {
if (e == null) {
e = new ChangeEvent(this, state);
}
((ChangeListener) i.next()).stateChanged(e);
}
}
/**
* Adds a listener that is notified whenever a user clicks on any part of
* the tree, either to expand or collapse a node, or to select a node. The
* listener is run whenever {@link #respond respond} is called.
*
* @pre l != null
* @pre ! isLocked()
*/
public void addActionListener(ActionListener l) {
Assert.isUnlocked(this);
m_listeners.add(ActionListener.class, l);
}
/**
* Removes a previously added <code>ActionListener</code>.
*
* @see #addActionListener addActionListener
*/
public void removeActionListener(ActionListener l) {
Assert.isUnlocked(this);
m_listeners.remove(ActionListener.class, l);
}
/**
* Notifies listeners that some part of the tree was clicked by the user.
* The source of the event is the tree.
*
* @pre data != null
* @see #respond respond
*/
protected void fireActionEvent(PageState data) {
Iterator i = m_listeners.getListenerIterator(ActionListener.class);
ActionEvent e = null;
while (i.hasNext()) {
if (e == null) {
e = new ActionEvent(this, data);
}
((ActionListener) i.next()).actionPerformed(e);
}
}
/**
* Adds a listener that is notified whenever a tree node is expanded or
* collpased, either by a user's click or by explicit calls to {@link
* #expand expand} or {@link #collapse collapse}.
*
* @pre l != null
* @pre ! isLocked()
*/
public void addTreeExpansionListener(TreeExpansionListener l) {
Assert.isUnlocked(this);
m_listeners.add(TreeExpansionListener.class, l);
}
/**
* Removes a previously added <code>TreeExpansionListener</code>.
*
* @pre ! isLocked()
* @see #addTreeExpansionListener addTreeExpansionListener
*/
public void removeTreeExpansionListener(TreeExpansionListener l) {
Assert.isUnlocked(this);
m_listeners.remove(TreeExpansionListener.class, l);
}
/**
* Notifies all registered {@link
* com.arsdigita.bebop.event.TreeExpansionListener
* TreeExpansionListeners} that a node in the tree has been expanded.
*
* @pre state != null
* @pre nodeKey != null
*/
protected void fireTreeExpanded(PageState state, Object nodeKey) {
Iterator i = m_listeners
.getListenerIterator(TreeExpansionListener.class);
TreeExpansionEvent e = null;
while (i.hasNext()) {
if (e == null) {
e = new TreeExpansionEvent(this, state, nodeKey);
}
((TreeExpansionListener) i.next()).treeExpanded(e);
}
}
/**
* Notifies all registered {@link
* com.arsdigita.bebop.event.TreeExpansionListener
* TreeExpansionListeners} that a node in the tree has been collapsed.
*
* @pre state != null
* @pre nodeKey != null
*/
protected void fireTreeCollapsed(PageState state, Object nodeKey) {
Iterator i = m_listeners
.getListenerIterator(TreeExpansionListener.class);
TreeExpansionEvent e = null;
while (i.hasNext()) {
if (e == null) {
e = new TreeExpansionEvent(this, state, nodeKey);
}
((TreeExpansionListener) i.next()).treeCollapsed(e);
}
}
/**
* Notifies the <code>Tree</code> that a node has been selected. Changes the
* currently selected tree component.
*/
public void respond(PageState data) throws javax.servlet.ServletException {
String action = data.getControlEventName();
String node = data.getControlEventValue();
if (EXPAND_EVENT.equals(action)) {
expand(node, data);
} else if (COLLAPSE_EVENT.equals(action)) {
collapse(node, data);
} else if (SELECT_EVENT.equals(action)) {
setSelectedKey(data, data.getControlEventValue());
} else {
throw new javax.servlet.ServletException("Unknown event '" + action
+ "'");
}
fireActionEvent(data);
}
//////////////////////////////
// MANAGE TREE'S NODE STATE //
//////////////////////////////
/**
* Determines whether the node at the specified display row is collapsed.
*
* @return <code>true</code> if the node at the specified display row is
* collapsed; <code>false</code> otherwise.
*/
public boolean isCollapsed(String nodeKey, PageState data) {
String stateString = (String) data.getValue(m_currentState);
String spaceId = " " + nodeKey + " ";
int idIndex;
if (stateString == null) {
return true;
} else {
idIndex = stateString.indexOf(spaceId);
}
// == -1 means it's not found in current state, thus it's collapsed
return (idIndex == -1);
}
/**
* Collapses a node in the tree and makes its children visible.
*
* @param nodeKey the key that the tree model uses to identify the node
* @param data represents the current request
*
* @pre nodeKey != null
* @pre data != null
*/
public void collapse(String nodeKey, PageState data) {
Assert.exists(nodeKey);
Assert.exists(data);
StringBuffer newCurrentState = new StringBuffer("");
String stateString = (String) data.getValue(m_currentState);
int idIndex;
String spaceId = " " + nodeKey + " ";
int idLength = spaceId.length();
if (stateString != null) {
idIndex = stateString.indexOf(spaceId);
// Found it; it should currently be expanded, so collapse it
if (idIndex != -1) {
newCurrentState
.append(stateString.substring(0, idIndex))
.append(" ");
if (stateString.length() > (idIndex + idLength)) {
newCurrentState.append(stateString.substring(idIndex
+ idLength));
}
data.setValue(m_currentState, newCurrentState.toString());
fireTreeCollapsed(data, nodeKey);
}
}
}
/**
* Expands a node in the tree and makes its children visible.
*
* @param nodeKey the key that the tree model uses to identify the node
* @param data represents the current request
*
* @pre nodeKey != null
* @pre data != null
*/
public void expand(String nodeKey, PageState data) {
Assert.exists(nodeKey);
Assert.exists(data);
String stateString = (String) data.getValue(m_currentState);
String spaceId = " " + nodeKey + " ";
StringBuffer newCurrentState = new StringBuffer("");
if (stateString != null) {
// Can't find it; it should currently be collapsed, so expand it
if ((stateString.indexOf(spaceId)) == -1) {
// Start with existing stateString...
newCurrentState.append(stateString);
// Add to newCurrentState string the new node Id
newCurrentState.append(spaceId);
// Set the value of the current state
data.setValue(m_currentState, newCurrentState.toString());
fireTreeExpanded(data, nodeKey);
}
} else {
// Add to newCurrentState string the new node Id
newCurrentState.append(spaceId);
// Set the value of the current state
data.setValue(m_currentState, newCurrentState.toString());
fireTreeExpanded(data, nodeKey);
}
}
/////////////////////////////////////////////
// PRINT THE TREE DIRECTLY OR GENERATE DOM //
/////////////////////////////////////////////
/**
* Returns the renderer currently used to render tree nodes.
*
* @return the current tree node renderer.
*/
public final TreeCellRenderer getCellRenderer() {
return m_renderer;
}
/**
* Sets the cell renderer to be used when generating output with
* {@link #generateXML generateXML}.
*
* @param r a <code>TreeCellRenderer</code> value
*/
public void setCellRenderer(TreeCellRenderer r) {
Assert.isUnlocked(this);
m_renderer = r;
}
private boolean hasSelectedChild(TreeModel tree, TreeNode node,
PageState data, Object selKey) {
String nodeKey = (String) node.getKey();
if ((selKey != null) && (selKey.equals(nodeKey) || selKey.toString()
.equals(nodeKey))) {
return true;
}
Iterator i = tree.getChildren(node, data);
while (i.hasNext()) {
TreeNode child = (TreeNode) i.next();
if (hasSelectedChild(tree, child, data, selKey)) {
// At this point we should close the opened DataQuery pointed to by Iterator (i).
// Since the data query is wrapped within DataQueryIterator, we don't have
// access to it directly, so this looks like the only viable option ...
while (i.hasNext()) {
}
return true;
}
}
return false;
}
/**
* Builds a DOM representing the tree.
*
*/
protected void generateTree(PageState data, Element parent, TreeNode node,
TreeModel tree) {
Element t_node = parent.newChildElement("bebop:t_node", BEBOP_XML_NS);
String nodeKey = node.getKey().toString();
Object selKey = getSelectedKey(data);
boolean isSelected = (selKey != null)
&& (selKey.equals(nodeKey) || selKey.toString()
.equals(nodeKey));
boolean hasChildren = tree.hasChildren(node, data);
if (s_selectAttributeEnabled) {
boolean hasSelectedChild = false;
if (!isSelected && hasChildren) {
hasSelectedChild = hasSelectedChild(tree, node, data, selKey);
}
t_node.addAttribute("isSelected", String.valueOf(isSelected
| hasSelectedChild));
}
if (hasChildren) {
boolean collapsed = isCollapsed(nodeKey, data);
data
.setControlEvent(this, collapsed ? EXPAND_EVENT : COLLAPSE_EVENT,
nodeKey);
try {
t_node.addAttribute("href", data.stateAsURL());
} catch (java.io.IOException ioe) {
// TODO: stateAsURL failed
}
data.clearControlEvent();
if (collapsed) {
// Collapsed
t_node.addAttribute("collapsed", "t");
data.setControlEvent(this, SELECT_EVENT, nodeKey);
Component c = getCellRenderer().getComponent(this, data,
node.getElement(),
isSelected,
NOT_EXPANDED,
NOT_LEAF,
nodeKey);
c.generateXML(data, t_node);
} else {
// Expanded
t_node.addAttribute("expanded", "t");
data.setControlEvent(this, SELECT_EVENT, nodeKey);
Component c = getCellRenderer().getComponent(this, data,
node.getElement(),
isSelected,
EXPANDED, NOT_LEAF,
nodeKey);
c.generateXML(data, t_node);
t_node.addAttribute("indentStart", "t");
for (Iterator i = tree.getChildren(node, data); i.hasNext();) {
generateTree(data, t_node, (TreeNode) i.next(), tree);
}
t_node.addAttribute("indentClose", "t");
}
} else {
// No children, no need for link...
t_node.addAttribute("childless", "t");
data.setControlEvent(this, SELECT_EVENT, nodeKey);
Component c = getCellRenderer().getComponent(this, data,
node.getElement(),
isSelected,
NOT_EXPANDED, LEAF,
nodeKey);
c.generateXML(data, t_node);
}
}
/**
* Services the request by building a DOM tree with the nodes first and then
* the included page.
*/
public void generateXML(PageState data, Element parent) {
TreeModel tree = getTreeModel(data);
if (!isVisible(data)) {
return;
}
treeElement = parent.newChildElement("bebop:tree", BEBOP_XML_NS);
exportAttributes(treeElement);
TreeNode _rootNode = tree.getRoot(data);
generateTree(data, treeElement, _rootNode, tree);
}
/**
* Manage the selected item by manipulating the state parameter.
*
* @deprecated The {@link ParameterSingleSelectionModel} contains all the
* functionality of this class
*/
public static class TreeSingleSelectionModel
extends ParameterSingleSelectionModel {
public TreeSingleSelectionModel(ParameterModel m) {
super(m);
}
}
/**
* Locks the <code>Tree</code> and prohibits further modifications.
*/
public void lock() {
getModelBuilder().lock();
super.lock();
}
/**
* Returns the tree model of the tree. A wrapper class to make deprecated
* constructor work.
*/
private static class WrapperModelBuilder extends LockableImpl
implements TreeModelBuilder {
public WrapperModelBuilder() {
super();
}
public TreeModel makeModel(Tree t, PageState s) {
return t.getTreeModel();
}
}
}

View File

@ -1,70 +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.bebop.tree;
import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.ControlLink;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.Tree;
/**
* The interface
* describes how a tree node (component) can be rendered.
*
* @author David Lutterkort
* @author Tri Tran
*
* @see TreeModel
* @see TreeNode
* @see Tree
* @version $Id$ */
public class DefaultTreeCellRenderer implements TreeCellRenderer {
/**
* Returns node component to be displayed. The component's
* <code>generateXML</code> or <code>print</code> is called
* to render the node.
*
* @param tree the <code>Tree</code> in which this node is being displayed
* @param state represents the state of the current request
* @param value the object returned by the TreeModel for that node,
* such as pretty name
* @param isSelected true if the node is selected
* @param isExpanded true if the node is expanded (not collapsed)
* @param isLeaf true if the node is a leaf node (no children)
* @param key the object uniquely identify that node (primary key)
* @return the component used to generate the output for the node item
*/
public Component getComponent (Tree tree, PageState state, Object value,
boolean isSelected, boolean isExpanded,
boolean isLeaf, Object key) {
Label l = new Label(value.toString());
// Bold if selected
if (isSelected) {
l.setFontWeight(Label.BOLD);
return l;
}
// Currently, we are not doing anything special here for
// collapsed/expanded node, or leaf node... Also not doing anything
// fancy with node's key. We are leaving this to Tree.java for now
// to set the appropriate attributes...
return new ControlLink(l);
}
}

View File

@ -1,55 +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.bebop.tree;
import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.Tree;
/**
* The interface
* describes how a tree node (component) can be rendered.
*
* @author David Lutterkort
* @author Tri Tran
*
* @see TreeModel
* @see TreeNode
* @see Tree
* @version $Id$ */
public interface TreeCellRenderer {
/**
* Returns node component to be displayed. The component's
* <code>generateXML</code> or <code>print</code> is called
* to render the node.
*
* @param tree the <code>Tree</code> in which this node is being displayed
* @param state represents the state of the current request
* @param value the object returned by the TreeModel for that node
* @param isSelected true if the node is selected
* @param isExpanded true if the node is expanded (not collapsed)
* @param isLeaf true if the node is a leaf node (no children)
* @param key the object uniquely identify that node (primary key)
* @return the component used to generate the output for the node item
*/
Component getComponent (Tree tree, PageState state, Object value,
boolean isSelected, boolean isExpanded,
boolean isLeaf, Object key);
}

View File

@ -1,52 +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.bebop.tree;
import com.arsdigita.bebop.PageState;
import java.util.Iterator;
/**
* The interface
* describes a model for a tree structure.
*
* @author David Lutterkort
* @author Stanislav Freidin
* @author Tri Tran
*
* @version $Id$ */
public interface TreeModel {
/**
* Obtain the root node of the tree, passing
* in PageState for permissioning purposes
*/
TreeNode getRoot(PageState data);
/**
* Check whether the node has children
*/
boolean hasChildren(TreeNode n, PageState data);
/**
* Check whether a given node has children, passing
* in PageState for permissioning purposes
*/
Iterator<TreeNode> getChildren(TreeNode n, PageState data);
}

View File

@ -1,42 +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.bebop.tree;
import com.arsdigita.bebop.Tree;
import com.arsdigita.bebop.PageState;
import com.arsdigita.util.Lockable;
/**
* The interface builds a
* {@link TreeModel} for a {@link Tree}.
*
* @author Stanislav Freidin
*
* @version $Id$ */
public interface TreeModelBuilder extends Lockable {
/**
* Builds a {@link TreeModel} to be used in the current request
*
* @param t The {@link Tree} that will use the model
* @param s The page state
*/
TreeModel makeModel(Tree t, PageState s);
}

View File

@ -1,48 +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.bebop.tree;
/**
* The interface
* describes a node for a tree.
*
* @author David Lutterkort
* @author Stanislav Freidin
* @author Tri Tran
*
* @version $Id$ */
public interface TreeNode {
/**
* Obtain a unique ID representing the node
* @return
*/
Object getKey();
/**
* Get the element of the tree node. The concrete type
* of the object returned is specific to each implementation
* of the <code>TreeModel</code> and should be documented
* there.
*
* @return the element for the tree node
*/
Object getElement();
}

View File

@ -1,172 +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 org.libreccm.categorization;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.tree.TreeModel;
import com.arsdigita.bebop.tree.TreeNode;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.libreccm.cdi.utils.CdiUtil;
import java.util.Iterator;
import java.util.Objects;
/**
* Implements the {@link com.arsdigita.bebop.tree.TreeModel} interface for
* categories.
*
* @author Daniel Berrange
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter </a>
*/
public class CategoryTreeModelLite implements TreeModel {
private static final Logger LOGGER = LogManager.getLogger(
CategoryTreeModelLite.class);
// String m_order = null;
private final Category root;
/**
* Initialises with the passed in the root Category.
*
* @param root the root category for this TreeModel
*/
// public CategoryTreeModelLite(Category root) {
// this(root, null);
// }
/**
* Initializes with the passed in the root Category.
*
* @param root the root category for this TreeModel
*/
public CategoryTreeModelLite(final Category root) {
// super(root.getUniqueId(),
// "com.arsdigita.categorization.getRootCategory",
// "com.arsdigita.categorization.getSubCategories");
// m_order = order;
this.root = root;
}
// @Override
// protected DataQueryTreeIterator getDataQueryTreeIterator(DataQueryTreeNode node,
// String getSubCategories) {
// return new CategoryTreeIterator(node, getSubCategories, m_order);
// }
@Override
public TreeNode getRoot(final PageState data) {
return new CategoryTreeNode(root);
}
@Override
public boolean hasChildren(final TreeNode node, final PageState state) {
Objects.requireNonNull(node);
if (node.getKey() == null
|| !(node.getKey() instanceof Long)) {
throw new IllegalArgumentException(
"The key of the provided TreeNode is null or not a Long.");
}
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final CategoryTreeModelLiteController controller = cdiUtil
.findBean(CategoryTreeModelLiteController.class);
return controller.hasSubCategories((long) node.getKey());
}
@Override
public Iterator<TreeNode> getChildren(
final TreeNode node, final PageState state
) {
Objects.requireNonNull(node);
if (node.getKey() == null
|| !(node.getKey() instanceof Long)) {
throw new IllegalArgumentException(
"The key of the provided TreeNode is null or not a Long.");
}
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final CategoryTreeModelLiteController controller = cdiUtil
.findBean(CategoryTreeModelLiteController.class);
return controller
.findSubCategories((long) node.getKey())
.stream()
.map(this::buildTreeNode)
.iterator();
}
private TreeNode buildTreeNode(final Category category) {
return new CategoryTreeNode(category);
}
private class CategoryTreeNode implements TreeNode {
private final Category category;
public CategoryTreeNode(final Category category) {
this.category = category;
}
@Override
public Object getKey() {
if (category == null) {
return null;
} else {
return category.getObjectId();
}
}
@Override
public Object getElement() {
if (category.getTitle().getValues().isEmpty()) {
return category.getName();
} else {
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final CategoryTreeModelLiteController controller = cdiUtil
.findBean(CategoryTreeModelLiteController.class);
return controller.getTitle(category);
}
}
}
// private static class CategoryTreeIterator extends DataQueryTreeIterator {
//
// public CategoryTreeIterator(DataQueryTreeNode node, String getSubCategories, String order) {
// super(node, getSubCategories);
// if (order != null) {
// addOrder(order);
// }
// }
//
// @Override
// public Object next() {
// DataQueryTreeNode node = (DataQueryTreeNode) super.next();
//
// // m_nodes.getLink
// node.setValue(Category.IS_ABSTRACT,
// (Boolean) m_nodes.get(Category.IS_ABSTRACT));
// return node;
// }
//
// }
}

View File

@ -1,94 +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 org.libreccm.categorization;
import org.hibernate.LazyInitializationException;
import org.libreccm.l10n.GlobalizationHelper;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.transaction.Transactional;
/**
* CDI bean used as interface between Bebop ({@link CategoryTreeModelLite}) and
* CDI. The CDI beans primarly takes are care of transactions and avoids
* {@link LazyInitializationException}.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
class CategoryTreeModelLiteController {
@Inject
private CategoryManager categoryManager;
@Inject
private CategoryRepository categoryRepo;
@Inject
private GlobalizationHelper globalizationHelper;
@Transactional(Transactional.TxType.REQUIRED)
protected boolean hasSubCategories(final long categoryId) {
final Category category = categoryRepo
.findById(categoryId)
.orElseThrow(() -> new IllegalArgumentException(String
.format("No Category with ID %d in the database.",
categoryId)));
return categoryManager.hasSubCategories(category);
}
@Transactional(Transactional.TxType.REQUIRED)
protected List<Category> findSubCategories(final long categoryId) {
final Category category = categoryRepo
.findById(categoryId)
.orElseThrow(() -> new IllegalArgumentException(String
.format("No Category with ID %d in the database.",
categoryId)));
return new ArrayList<>(category.getSubCategories());
}
@Transactional(Transactional.TxType.REQUIRED)
protected String getTitle(final Category ofCategory) {
Objects.requireNonNull(ofCategory);
final Category category = categoryRepo
.findById(ofCategory.getObjectId())
.orElseThrow(
() -> new IllegalArgumentException(
String.format(
"No Category with ID %d available.",
ofCategory.getObjectId()
)
)
);
return globalizationHelper.getValueFromLocalizedString(
category.getTitle()
);
}
}