/*==========================================================================*\
| $Id: ExitPreventingSecurityManager.java,v 1.1 2012/03/05 14:17:44 stedwar2 Exp $
|*-------------------------------------------------------------------------*|
| Copyright (C) 2012 Virginia Tech
|
| This file is part of the Student-Library.
|
| The Student-Library 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 3 of the
| License, or (at your option) any later version.
|
| The Student-Library 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 the Student-Library; if not, see <http://www.gnu.org/licenses/>.
\*==========================================================================*/
package student.testingsupport;
import java.security.AccessController;
import java.security.Permission;
import java.security.PrivilegedAction;
//-------------------------------------------------------------------------
/**
* A custom security manager used by {@link student.TestCase} to detect
* and report calls to System.exit() without actually terminating the JVM.
* With this security manager in place, any call to System.exit() will be
* turned into a {@link ExitCalledException}.
* <p>
* This security manager is designed to work in conjunction with any other
* security manager currently installed. It chains to an existing security
* manager and delegates all checks other than System.exit() checks to
* the other manager. This way it can easily be "added" on top of a
* sandboxing security manager without requiring that manager to be
* rewritten.
* </p>
*
* @author Stephen Edwards
* @author Last changed by $Author: stedwar2 $
* @version $Revision: 1.1 $, $Date: 2012/03/05 14:17:44 $
*/
public class ExitPreventingSecurityManager
extends SecurityManager
{
//~ Fields ................................................................
private SecurityManager parent;
//~ Constructor ...........................................................
// ----------------------------------------------------------
/**
* Create a new manager with the given security manager as its "parent".
* All checks other than System.exit() checks will be delegated to the
* parent, if one is provided.
*
* @param parent The security manager to chain to (delegate to) for all
* other checks besides System.exit() calls.
*/
public ExitPreventingSecurityManager(SecurityManager parent)
{
this.parent = parent;
}
//~ Public Methods ........................................................
// ----------------------------------------------------------
/**
* {@inheritDoc}
*/
@Override
public void checkPermission(Permission perm)
{
if (parent != null)
{
parent.checkPermission(perm);
}
}
// ----------------------------------------------------------
/**
* {@inheritDoc}
*/
@Override
public void checkPermission(Permission perm, Object context)
{
if (parent != null)
{
parent.checkPermission(perm, context);
}
}
// ----------------------------------------------------------
/**
* {@inheritDoc}
*/
@Override
public void checkExit(int status)
{
if (parent != null)
{
parent.checkExit(status);
}
throw new ExitCalledException(status);
}
// ----------------------------------------------------------
/**
* Install a new instance of this class as the current security manager,
* taking any existing security manager and using it as the parent to
* chain to.
*/
public static void install()
{
AccessController.doPrivileged( new PrivilegedAction<Void>()
{
public Void run()
{
SecurityManager current = System.getSecurityManager();
if (current == null
|| !(current instanceof ExitPreventingSecurityManager))
{
System.setSecurityManager(
new ExitPreventingSecurityManager(current));
}
return null;
}
});
}
// ----------------------------------------------------------
/**
* If the current security manager is an instance of this class,
* uninstall it and replace it with its parent, if any.
*/
public static void uninstall()
{
AccessController.doPrivileged( new PrivilegedAction<Void>()
{
public Void run()
{
SecurityManager current = System.getSecurityManager();
if (current != null
&& current instanceof ExitPreventingSecurityManager)
{
System.setSecurityManager(
((ExitPreventingSecurityManager)current).parent);
}
return null;
}
});
}
}