package org.exist.client.xacml;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
/**
* XACML (exactly one)
* |
* --Top-level PolicySet (zero or more)
* |
* --Target (exactly one, may be empty)
* |
* --Policy (zero or more)
* |
* --Target (exactly one, may be empty)
* |
* --Rule (zero or more)
* |
* --Target (exactly one, may be empty)
* |
* --Condition (exactly one, may be empty)
*
*/
public class XACMLTreeModel implements NodeChangeListener, TreeModel
{
private List listeners = new ArrayList(2);
private RootNode root;
private XACMLTreeModel() {}
public XACMLTreeModel(RootNode root)
{
if(root == null)
throw new NullPointerException("Root node cannot be null");
this.root = root;
root.addNodeChangeListener(this);
}
public Object getRoot()
{
return root;
}
public int getChildCount(Object parent)
{
if(parent instanceof NodeContainer)
return ((NodeContainer)parent).getChildCount();
return 0;
}
public boolean isLeaf(Object parent)
{
return !(parent == root || parent instanceof PolicyElementNode);
}
public Object getChild(Object parent, int index)
{
if(parent instanceof NodeContainer)
return ((NodeContainer)parent).getChild(index);
return null;
}
public int getIndexOfChild(Object parent, Object child)
{
if(parent instanceof NodeContainer)
return ((NodeContainer)parent).indexOfChild(child);
return -1;
}
public void valueForPathChanged(TreePath path, Object newValue)
{
//do nothing
}
public void addTreeModelListener(TreeModelListener listener)
{
if(listener != null)
listeners.add(listener);
}
public void removeTreeModelListener(TreeModelListener listener)
{
if(listener != null)
listeners.remove(listener);
}
public boolean hasUnsavedChanges()
{
return root.isModified(true);
}
public void revert()
{
root.revert(true);
}
public void commit()
{
root.commit(true);
}
public void nodeChanged(XACMLTreeNode node)
{
TreePath path = getPathToNode(node);
TreeModelEvent event = new TreeModelEvent(this, path);
for(Iterator it = listeners.iterator(); it.hasNext();)
((TreeModelListener)it.next()).treeNodesChanged(event);
}
public void nodeAdded(XACMLTreeNode node, int newIndex)
{
TreeModelEvent event = getEvent(node, newIndex);
for(Iterator it = listeners.iterator(); it.hasNext();)
((TreeModelListener)it.next()).treeNodesInserted(event);
}
public void nodeRemoved(XACMLTreeNode removedNode, int oldChildIndex)
{
TreeModelEvent event = getEvent(removedNode, oldChildIndex);
for(Iterator it = listeners.iterator(); it.hasNext();)
((TreeModelListener)it.next()).treeNodesRemoved(event);
}
private TreeModelEvent getEvent(XACMLTreeNode node, int index)
{
TreePath path = getPathToNode(node.getParent());
int[] childIndices = { index };
Object[] child = { node };
TreeModelEvent event = new TreeModelEvent(this, path, childIndices, child);
return event;
}
public static TreePath getPathToNode(XACMLTreeNode node)
{
NodeContainer parent = node.getParent();
if(parent == null)
return new TreePath(node);
return getPathToNode(parent).pathByAddingChild(node);
}
}