package org.exist.client.xacml;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import com.sun.xacml.Policy;
import com.sun.xacml.PolicySet;
import com.sun.xacml.PolicyTreeElement;
public class RootNode extends AbstractTreeNode implements PolicyElementContainer
{
private List children;
private List originalChildren;
private List listeners = new ArrayList(2);
public RootNode()
{
super(null);
children = new ArrayList();
originalChildren = Collections.EMPTY_LIST;
}
public void add(PolicyTreeElement element)
{
add(-1, element);
}
public void add(int index, PolicyTreeElement element)
{
if(element == null)
return;
if(element instanceof Policy)
add(index, new PolicyNode(this, (Policy)element));
else if(element instanceof PolicySet)
add(index, new PolicySetNode(this, (PolicySet)element));
else
throw new IllegalArgumentException("Only Policies and PolicySets can be top level elements.");
}
public void add(PolicyElementNode node)
{
add(-1, node);
}
public void add(int index, PolicyElementNode node)
{
if(node == null)
return;
if(node instanceof AbstractPolicyNode)
{
if(index < 0)
index = children.size();
children.add(index, node);
setModified(true);
nodeAdded(node, index);
}
else
throw new IllegalArgumentException("Only PolicyNodes and PolicySetNodes can be top level elements.");
}
public void remove(PolicyElementNode node)
{
if(node == null)
return;
int index = children.indexOf(node);
if(index < 0)
return;
children.remove(index);
setModified(true);
nodeRemoved(node, index);
}
public boolean containsId(String id)
{
for(Iterator it = children.iterator();it.hasNext();)
{
if(((AbstractPolicyNode)it.next()).getId().toString().equals(id))
return true;
}
return false;
}
public int getChildCount()
{
return children.size();
}
public XACMLTreeNode getChild(int index)
{
return (XACMLTreeNode)children.get(index);
}
public int indexOfChild(Object child)
{
return children.indexOf(child);
}
public boolean isModified(boolean deep)
{
if(super.isModified(deep))
return true;
if(deep)
{
for(Iterator it = children.iterator(); it.hasNext();)
{
PolicyElementNode child = (PolicyElementNode)it.next();
if(child.isModified(true))
return true;
}
}
return false;
}
public void revert(boolean deep)
{
children = originalChildren;
if(deep)
{
for(Iterator it = children.iterator(); it.hasNext();)
((PolicyElementNode)it.next()).revert(true);
}
super.revert(deep);
}
public void commit(boolean deep)
{
originalChildren = children;
if(deep)
{
for(Iterator it = children.iterator(); it.hasNext();)
((PolicyElementNode)it.next()).commit(true);
}
super.commit(deep);
}
public Set getRemovedDocumentNames()
{
Set ret = new HashSet();
for(Iterator originalIt = originalChildren.iterator(); originalIt.hasNext();)
{
AbstractPolicyNode originalChild = (AbstractPolicyNode)originalIt.next();
String documentName = originalChild.getDocumentName();
if(!documentNameExists(documentName))
ret.add(documentName);
}
return ret;
}
private boolean documentNameExists(String documentName)
{
for(Iterator currentIt = children.iterator(); currentIt.hasNext();)
{
AbstractPolicyNode currentChild = (AbstractPolicyNode)currentIt.next();
String currentDocName = currentChild.getDocumentName();
if(currentDocName != null && currentDocName.equals(documentName))
return true;
}
return false;
}
public void addNodeChangeListener(NodeChangeListener listener)
{
if(listener != null)
listeners.add(listener);
}
public void removeNodeChangeListener(NodeChangeListener listener)
{
if(listener != null)
listeners.remove(listener);
}
public void nodeChanged(XACMLTreeNode node)
{
for(Iterator it = listeners.iterator(); it.hasNext();)
((NodeChangeListener)it.next()).nodeChanged(node);
}
public void nodeAdded(XACMLTreeNode node, int newIndex)
{
for(Iterator it = listeners.iterator(); it.hasNext();)
((NodeChangeListener)it.next()).nodeAdded(node, newIndex);
}
public void nodeRemoved(XACMLTreeNode removedNode, int oldChildIndex)
{
for(Iterator it = listeners.iterator(); it.hasNext();)
((NodeChangeListener)it.next()).nodeRemoved(removedNode, oldChildIndex);
}
public String serialize(boolean indent)
{
throw new UnsupportedOperationException("Cannot serialize the root node");
}
}