/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt 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;
import java.io.File;
import java.net.URL;
import java.security.CodeSource;
import java.security.PermissionCollection;
import java.security.Permission;
import java.security.ProtectionDomain;
import java.util.HashSet;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Properties;
import java.util.Enumeration;
import java.lang.reflect.Constructor;
import org.jboss.test.visitor.TypeHierarchyTraversal;
import org.jboss.test.visitor.PropertiesVisitorImpl;
/**
* A Test PolicyPlugin.
*
* @author <a href="adrian@jboss.com">Adrian Brock</a>
* @version $Revision: 62656 $
*/
public class TestsPolicyPlugin extends PolicyPlugin
{
private HashSet<Permission> classPermissions = new HashSet<Permission>();
private static final URL codeSourceLocation;
static
{
URL temp = null;
ProtectionDomain pd = TestsPolicyPlugin.class.getProtectionDomain();
if (pd != null)
{
CodeSource cs = pd.getCodeSource();
if (cs != null)
{
temp = cs.getLocation();
}
}
codeSourceLocation = temp;
}
/**
* This ctor scans for properties using the TypeHierarchyTraversal and
* PropertiesVisitorImpl to pickup testclass specific permissions. Only
* class/interfaces properties are currently consulted for properties of
* the form 'test.Permission.N' where N=[0-9]+
* The value format of the test.Permission.N property is:
* perm-class, name [, actions]
* which conforms to the BasicPermission(String name, String actions) and
* BasicPermission(String name) sigs.
* @param clazz
*/
public TestsPolicyPlugin(Class clazz)
{
// Augment the policy with testcase clazz data
PropertiesVisitorImpl visitor = new PropertiesVisitorImpl();
TypeHierarchyTraversal.visit(clazz, visitor);
HashMap<Class, Properties> typeProperties = visitor.getTypeProperties();
Iterator<Properties> iter = typeProperties.values().iterator();
ClassLoader loader = Thread.currentThread().getContextClassLoader();
while( iter.hasNext() )
{
Properties props = iter.next();
Enumeration names = props.propertyNames();
while( names.hasMoreElements() )
{
String name = (String) names.nextElement();
// Any test.Permission.N is what we are looking for
if( name.matches("test.Permission.[0-9]+") )
{
// Permission value syntax is perm-class, name [, actions]
String value = props.getProperty(name);
String[] info = value.split(", ");
try
{
// Create the permission based on the number of args
Class pc = loader.loadClass(info[0]);
Permission p;
if( info.length == 1 )
{
p = (Permission) pc.newInstance();
}
else if( info.length == 2 )
{
Class[] sig = {String.class};
Object[] args = {info[1]};
Constructor ctor = pc.getConstructor(sig);
p = (Permission) ctor.newInstance(args);
}
else
{
Class[] sig = {String.class, String.class};
Object[] args = {info[1], info[2]};
Constructor ctor = pc.getConstructor(sig);
p = (Permission) ctor.newInstance(args);
}
classPermissions.add(p);
}
catch(ClassNotFoundException e)
{
// We could break out ClassNotFoundException to create lazy loaded...
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
}
}
public PermissionCollection getPermissions(CodeSource codesource)
{
URL url = codesource.getLocation();
if (url != null)
{
// Is this us?
if (url.equals(codeSourceLocation))
return allPermissions();
// Is this a test location?
File file = new File(url.toString());
String name = file.getName();
if (name.indexOf("tests") != -1 || name.indexOf("test-classes") != -1 || name.indexOf("-test.jar") != -1)
{
// TODO: Make configurable
PermissionCollection pc = fileReadPermissions();
// Needed for the class loading tests
pc.add(new RuntimePermission("createClassLoader"));
pc.add(new RuntimePermission("getProtectionDomain"));
// Add any class declared permissions
Iterator iter = classPermissions.iterator();
while( iter.hasNext() )
{
Permission p = (Permission) iter.next();
pc.add(p);
}
return pc;
}
}
return allPermissions();
}
}