package org.exist.client.xacml;
import java.net.URI;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.sun.xacml.AbstractPolicy;
import com.sun.xacml.Policy;
import com.sun.xacml.PolicySet;
import com.sun.xacml.PolicyTreeElement;
import com.sun.xacml.Target;
import com.sun.xacml.combine.CombiningAlgorithm;
import com.sun.xacml.combine.PolicyCombiningAlgorithm;
public class PolicySetNode extends AbstractPolicyNode
{
private List children;
private List originalChildren;
public PolicySetNode(NodeContainer parent, PolicySet policySet)
{
this(parent, null, policySet);
}
public PolicySetNode(NodeContainer parent, String documentName, PolicySet policySet)
{
super(parent, documentName, policySet);
List toCopy = policySet.getChildren();
children = new ArrayList(toCopy.size());
for(Iterator it = toCopy.iterator(); it.hasNext();)
add((AbstractPolicy)it.next());
originalChildren = new ArrayList(children);
}
public PolicyTreeElement create()
{
return createPolicySet();
}
public PolicyTreeElement create(URI id)
{
return createPolicySet(id);
}
public PolicySet createPolicySet()
{
return createPolicySet(null);
}
public PolicySet createPolicySet(URI id)
{
CombiningAlgorithm alg = getCombiningAlgorithm();
if(!(alg instanceof PolicyCombiningAlgorithm))
throw new IllegalStateException("Combining algorithm must be a policy combining algorithm");
PolicyCombiningAlgorithm algorithm = (PolicyCombiningAlgorithm)alg;
Target target = getTarget().getTarget();
List copy = new ArrayList(children.size());
for(Iterator it = children.iterator(); it.hasNext();)
copy.add(((PolicyElementNode)it.next()).create());
URI useId = (id == null) ? getId() : id;
return new PolicySet(useId, algorithm, getDescription(), target, copy);
}
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.getParent() != this)
throw new IllegalArgumentException("Cannot add a PolicyElementNode to a parent other than its declared parent.");
if(node instanceof AbstractPolicyNode)
{
if(index < 0)
index = children.size()+1;
if(index == 0)
throw new IllegalArgumentException("Cannot insert AbstractPolicy before Target");
children.add(index-1, 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+1);
}
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() + 1; //+1 for the target
}
public XACMLTreeNode getChild(int index)
{
return (index == 0) ? getTarget() : (XACMLTreeNode)children.get(index-1);
}
public int indexOfChild(Object child)
{
if(child == getTarget())
return 0;
int ret = children.indexOf(child);
return (ret >= 0) ? ret+1 : -1;
}
public boolean isModified(boolean deep)
{
if(super.isModified(deep))
return true;
if(deep)
{
for(Iterator it = children.iterator(); it.hasNext();)
{
if(((PolicyElementNode)it.next()).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);
}
}