/*
* JBoss, Home of Professional Open Source.
* Copyright 2008, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This 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 software 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 software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.test.security.test;
import java.security.Permission;
import java.security.PermissionCollection;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
/** The PermissionCollection object for NamespacePermissions.
@author Scott.Stark@jboss.org
@version $Revision: 81036 $
*/
public class NamespacePermissionCollection extends PermissionCollection
{
private TreeMap namespacePerms = new TreeMap();
private TreeMap namespaceKeys = new TreeMap(new PermissionName.NameLengthComparator());
/** Creates new NamespacePermission */
public NamespacePermissionCollection()
{
}
public void add(Permission permission)
{
if( this.isReadOnly() )
throw new SecurityException("Cannot add permission to read-only collection");
if( (permission instanceof NamespacePermission) == false )
throw new IllegalArgumentException("Only NamespacePermission can be added, invalid="+permission);
NamespacePermission np = (NamespacePermission) permission;
PermissionName key = np.getFullName();
ArrayList tmp = (ArrayList) namespacePerms.get(key);
if( tmp == null )
{
tmp = new ArrayList();
namespacePerms.put(key, tmp);
namespaceKeys.put(key, key);
}
tmp.add(np);
}
/** Locate the closest permissions assigned to the namespace. This is based
*on the viewing the permission name as a heirarchical PermissionName and
*/
public boolean implies(Permission permission)
{
boolean implies = false;
if( namespacePerms.isEmpty() == true )
return false;
NamespacePermission np = (NamespacePermission) permission;
// See if there is an exact permission for the name
PermissionName key = np.getFullName();
ArrayList tmp = (ArrayList) namespacePerms.get(key);
if( tmp == null )
{ // Find the closest parent position.
SortedMap headMap = namespacePerms.headMap(key);
try
{
PermissionName lastKey = (PermissionName) headMap.lastKey();
if( lastKey.isParent(key) == true )
tmp = (ArrayList) namespacePerms.get(lastKey);
else
{
PermissionName[] keys = {};
keys = (PermissionName[]) headMap.keySet().toArray(keys);
for(int k = keys.length-1; k >= 0; k --)
{
lastKey = keys[k];
if( lastKey.isParent(key) == true )
{
tmp = (ArrayList) namespacePerms.get(lastKey);
break;
}
}
}
}
catch(NoSuchElementException e)
{ /* Assign the first permission
Object firstKey = namespacePerms.firstKey();
tmp = (ArrayList) namespacePerms.get(firstKey);
*/
}
}
// See if the permission is implied by any we found
if( tmp != null )
implies = isImplied(tmp, np);
//log.debug("NPC["+this+"].implies("+np+") -> "+implies);
return implies;
}
public Enumeration elements()
{
Set s = namespaceKeys.keySet();
final Iterator iter = s.iterator();
Enumeration elements = new Enumeration()
{
ArrayList activeEntry;
int index;
public boolean hasMoreElements()
{
boolean hasMoreElements = true;
if( activeEntry == null || index >= activeEntry.size() )
{
hasMoreElements = iter.hasNext();
activeEntry = null;
}
return hasMoreElements;
}
public Object nextElement()
{
Object next = null;
if( activeEntry == null )
{
Object key = iter.next();
activeEntry = (ArrayList) namespacePerms.get(key);
index = 0;
next = activeEntry.get(index ++);
}
else
{
next = activeEntry.get(index ++);
}
return next;
}
};
return elements;
}
private boolean isImplied(ArrayList permissions, NamespacePermission np)
{
boolean isImplied = false;
for(int p = 0; p < permissions.size(); p ++)
{
Permission perm = (Permission) permissions.get(p);
isImplied |= perm.implies(np);
if( isImplied == true )
break;
}
return isImplied;
}
}