/*
 * 
 * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
 * 
 * The contents of this file are subject to the Sun Community Source
 * License v3.0/Jini Technology Specific Attachment v 1.0 (the
 * "License"). You may not use this file except in compliance with the
 * License. You may obtain a copy of the License at
 * http://wwws.sun.com/software/jini/licensing/SCSL3_JiniTSA1.html.
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 * the License for the specific language governing rights and limitations
 * under the License.
 * 
 * The Reference Code is Jini Technology Core Platform code, v2.0. The
 * Developer of the Reference Code is Sun Microsystems, Inc.
 * 
 * Contributor(s): Sun Microsystems, Inc.
 * 
 * The contents of this file comply with the Jini Technology Core
 * Platform Compatibility Kit, v2.0A.
 * 
 * Tester(s): Sun Microsystems, Inc.
 * 
 * Test Platform(s):
 * Java 2 SDK, Standard Edition, Version 1.4.2_03 for Solaris(TM)SPARC/x86
 * Java 2 SDK, Standard Edition, Version 1.4.2_03 for Linux (Intel x86)
 * Java 2 SDK, Standard Edition, Version 1.4.2_03 for Windows (Intel Platform)
 * 
 */

package net.jini.security;

import java.security.AccessControlContext;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;

/**
 * Interface implemented by objects representing security contexts, returned
 * from the {@link Security#getContext getContext} method of the {@link
 * Security} class, which in turn may obtain them from a security manager or
 * policy provider implementing the
 * {@link net.jini.security.policy.SecurityContextSource} interface.
 * Each <code>SecurityContext</code> contains an {@link AccessControlContext}
 * instance representing the access control context in place when the security
 * context was snapshotted; this instance can be passed to one of the
 * <code>doPrivileged</code> methods of the {@link
 * java.security.AccessController} class to restore the
 * <code>AccessControlContext</code> portion of the overall security context.
 * Additional state (if any) carried by the security context can be restored
 * for the duration of a {@link PrivilegedAction} or {@link
 * PrivilegedExceptionAction} by passing that action to the appropriate wrap
 * method of the <code>SecurityContext</code> instance, and then executing the
 * returned "wrapper" action.  These two operations--restoring the access
 * control context, and restoring any additional context encapsulated by the
 * <code>SecurityContext</code> instance--should be performed in conjunction
 * with a single <code>AccessController.doPrivileged</code> call, as
 * illustrated below:
 * <pre>
 *      // snapshot context
 *      SecurityContext ctx = Security.getContext();
 *
 *      // restore context
 *      AccessController.doPrivileged(
 *          ctx.wrap(action), ctx.getAccessControlContext());
 * </pre>
 *
 * @author Sun Microsystems, Inc.
 * 
 * @since 2.0
 */
public interface SecurityContext {

    /**
     * Returns a security context-restoring <code>PrivilegedAction</code> that
     * wraps the given action, or returns the action itself if the security
     * context does not include any non-<code>AccessControlContext</code> state
     * to restore.  The <code>run</code> method of the "wrapper" action (if
     * any) restores the non-<code>AccessControlContext</code> state of the
     * security context before invoking the <code>run</code> method of the
     * wrapped action, and unrestores that state after the wrapped action's
     * <code>run</code> method has completed (normally or otherwise).  The
     * value returned or exception thrown by the wrapped action's
     * <code>run</code> method is propagated through the <code>run</code>
     * method of the wrapper action.
     *
     * @param action the action to be wrapped
     * @return security context-restoring action wrapping <code>action</code>,
     * or <code>action</code> if no wrapping is necessary
     * @throws NullPointerException if <code>action</code> is <code>null</code>
     */
    PrivilegedAction wrap(PrivilegedAction action);

    /**
     * Returns a security context-restoring
     * <code>PrivilegedExceptionAction</code> that wraps the given action, or
     * returns the action itself if the security context does not include any
     * non-<code>AccessControlContext</code> state to restore.  The
     * <code>run</code> method of the "wrapper" action (if any) restores the
     * non-<code>AccessControlContext</code> state of the security context
     * before invoking the <code>run</code> method of the wrapped action, and
     * unrestores that state after the wrapped action's <code>run</code> method
     * has completed (normally or otherwise).  The value returned or exception
     * thrown by the wrapped action's <code>run</code> method is propagated
     * through the <code>run</code> method of the wrapper action.
     *
     * @param action the action to be wrapped
     * @return security context-restoring action wrapping <code>action</code>,
     * or <code>action</code> if no wrapping is necessary
     * @throws NullPointerException if <code>action</code> is <code>null</code>
     */
    PrivilegedExceptionAction wrap(PrivilegedExceptionAction action);

    /**
     * Returns access control context portion of snapshotted security context.
     *
     * @return access control context portion of snapshotted security context
     */
    AccessControlContext getAccessControlContext();
}
