Removed depcrecated Bebop Tree component
parent
8f380e40ec
commit
0e3ae4e99f
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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;
|
||||
// }
|
||||
//
|
||||
// }
|
||||
}
|
||||
|
|
@ -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()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue