shiro-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From lhazlew...@apache.org
Subject svn commit: r806369 - in /incubator/shiro/trunk: ./ core/src/main/java/org/apache/shiro/authz/ core/src/main/java/org/apache/shiro/mgt/ core/src/main/java/org/apache/shiro/subject/ core/src/main/java/org/apache/shiro/subject/support/ core/src/main/java...
Date Thu, 20 Aug 2009 21:38:25 GMT
Author: lhazlewood
Date: Thu Aug 20 21:38:24 2009
New Revision: 806369

URL: http://svn.apache.org/viewvc?rev=806369&view=rev
Log:
SHIRO-25 - began initial support for RunAs capabilities - started with Runnable/Callable support.
 Also fixed various minor typos.  root pom.xml - commented out the DocBook plugin as it is
not being used

Added:
    incubator/shiro/trunk/core/src/main/java/org/apache/shiro/subject/support/
    incubator/shiro/trunk/core/src/main/java/org/apache/shiro/subject/support/SubjectCallable.java
    incubator/shiro/trunk/core/src/main/java/org/apache/shiro/subject/support/SubjectRunnable.java
    incubator/shiro/trunk/core/src/main/java/org/apache/shiro/subject/support/ThreadedExecutionSupport.java
Modified:
    incubator/shiro/trunk/core/src/main/java/org/apache/shiro/authz/Permission.java
    incubator/shiro/trunk/core/src/main/java/org/apache/shiro/mgt/SecurityManagerAware.java
    incubator/shiro/trunk/core/src/main/java/org/apache/shiro/subject/DelegatingSubject.java
    incubator/shiro/trunk/core/src/main/java/org/apache/shiro/subject/Subject.java
    incubator/shiro/trunk/core/src/main/java/org/apache/shiro/util/ThreadContext.java
    incubator/shiro/trunk/pom.xml

Modified: incubator/shiro/trunk/core/src/main/java/org/apache/shiro/authz/Permission.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/core/src/main/java/org/apache/shiro/authz/Permission.java?rev=806369&r1=806368&r2=806369&view=diff
==============================================================================
--- incubator/shiro/trunk/core/src/main/java/org/apache/shiro/authz/Permission.java (original)
+++ incubator/shiro/trunk/core/src/main/java/org/apache/shiro/authz/Permission.java Thu Aug
20 21:38:24 2009
@@ -22,26 +22,26 @@
  * A Permission represents the ability to perform an action or access a resource.  A Permission
is the most
  * granular, or atomic, unit in a system's security policy and is the cornerstone upon which
fine-grained security
  * models are built.
- *
+ * <p/>
  * <p>It is important to understand a Permission instance only represents functionality
or access - it does not grant it.
  * Granting access to an application functionality or a particular resource is done by the
application's security
  * configuration, typically by assigning Permissions to users, roles and/or groups.
- *
+ * <p/>
  * <p>Most typical systems are what the Shiro team calls <em>role-based</em>
in nature, where a role represents
  * common behavior for certain user types.  For example, a system might have an <em>Aministrator</em>
role, a
  * <em>User</em> or <em>Guest</em> roles, etc.
- *
+ * <p/>
  * <p>But if you have a dynamic security model, where roles can be created and deleted
at runtime, you can't hard-code
- * role names in your code.  In this environment, roles themselves arent aren't very useful.
 What matters is what
+ * role names in your code.  In this environment, roles themselves aren't aren't very useful.
 What matters is what
  * <em>permissions</em> are assigned to these roles.
- *
+ * <p/>
  * <p>Under this paradigm, permissions are immutable and reflect an application's raw
functionality
  * (opening files, accessing a web URL, creating users, etc).  This is what allows a system's
security policy
  * to be dynamic: because Permission classes represent raw functionality and only change
when the application's
  * source code changes, they are immutable at runtime - they represent 'what' the system
can do.  Roles, users, and
  * groups are the 'who' of the application.  Determining 'who' can do 'what' then becomes
a simple exercise of
  * associating Permissions to roles, users, and groups in some way.
- *
+ * <p/>
  * <p>Most applications do this by associating a named role with permissions (i.e.
a role 'has a' collection of
  * Permissions) and then associate users with roles (i.e. a user 'has a' collection of roles)
so that by transitive
  * association, the user 'has' the permissions in their roles.  There are numerous variations
on this theme
@@ -49,13 +49,13 @@
  * have roles, etc, etc).  When employing a permission-based security model instead of a
role-based one, users, roles,
  * and groups can all be created, configured and/or deleted at runtime.  This enables  an
extremely powerful security
  * model.
- *
+ * <p/>
  * <p>A benefit to Shiro is that, although it assumes most systems are based on these
types of static role or
  * dynamic role w/ permission schemes, it does not require a system to model their security
data this way - all
  * Permission checks are relegated to {@link org.apache.shiro.realm.Realm} implementations,
and only those implementatons
  * really determine how a user 'has' a permission or not.  The Realm could use the semantics
described here, or it
  * could utilize some other mechanism entirely - it is always up to the application developer.
- *
+ * <p/>
  * <p>Shiro provides a very powerful default implementation of this interface in the
form of the
  * {@link org.apache.shiro.authz.permission.WildcardPermission WildcardPermission}.  We highly
recommend that you
  * investigate this class before trying to implement your own <code>Permission</code>s.
@@ -69,11 +69,11 @@
     /**
      * Returns <tt>true</tt> if this current instance <em>implies</em>
all the functionality and/or resource access
      * described by the specified <tt>Permission</tt> argument, <tt>false</tt>
otherwise.
-     *
+     * <p/>
      * <p>That is, this current instance must be exactly equal to or a <em>superset</em>
of the functionalty
      * and/or resource access described by the given <tt>Permission</tt> argument.
 Yet another way of saying this
      * would be:
-     *
+     * <p/>
      * <p>If &quot;permission1 implies permission2&quot;, (i.e. <code>permission1.implies(
permission2 ) )</code>,
      * then any Subject granted <tt>permission1</tt> would have ability greater
than or equal to that defined by
      * <tt>permission2</tt>.

Modified: incubator/shiro/trunk/core/src/main/java/org/apache/shiro/mgt/SecurityManagerAware.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/core/src/main/java/org/apache/shiro/mgt/SecurityManagerAware.java?rev=806369&r1=806368&r2=806369&view=diff
==============================================================================
--- incubator/shiro/trunk/core/src/main/java/org/apache/shiro/mgt/SecurityManagerAware.java
(original)
+++ incubator/shiro/trunk/core/src/main/java/org/apache/shiro/mgt/SecurityManagerAware.java
Thu Aug 20 21:38:24 2009
@@ -20,8 +20,9 @@
 
 /**
  * Interface providing a callback method that allows an implementation of this interface
to receive a reference to
- * the {@link org.apache.shiro.mgt.SecurityManager SecurityManager} if they require one.
 This is mostly used by core implementation classes
- * for framework code and is rarely necessary for software developers enabling Shiro in their
applications.
+ * the {@link org.apache.shiro.mgt.SecurityManager SecurityManager} if they require one.
 This is mostly used by core
+ * implementation classes for framework code and is rarely necessary for software developers
enabling Shiro in their
+ * applications.
  *
  * @author Les Hazlewood
  * @since 1.0
@@ -29,10 +30,10 @@
 public interface SecurityManagerAware {
 
     /**
-     * Callback method that allows a component to receive the {@link org.apache.shiro.mgt.SecurityManager
SecurityManager} instance if it
-     * requires one.
+     * Callback method that allows a component to receive the
+     * {@link org.apache.shiro.mgt.SecurityManager SecurityManager} instance if it requires
one.
      *
-     * @param securityManager the application's <code>SecurityManager</code>
+     * @param securityManager the application's {@code SecurityManager}
      */
-    void setSecurityManager(org.apache.shiro.mgt.SecurityManager securityManager);
+    void setSecurityManager(SecurityManager securityManager);
 }

Modified: incubator/shiro/trunk/core/src/main/java/org/apache/shiro/subject/DelegatingSubject.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/core/src/main/java/org/apache/shiro/subject/DelegatingSubject.java?rev=806369&r1=806368&r2=806369&view=diff
==============================================================================
--- incubator/shiro/trunk/core/src/main/java/org/apache/shiro/subject/DelegatingSubject.java
(original)
+++ incubator/shiro/trunk/core/src/main/java/org/apache/shiro/subject/DelegatingSubject.java
Thu Aug 20 21:38:24 2009
@@ -29,6 +29,8 @@
 import org.apache.shiro.session.ProxiedSession;
 import org.apache.shiro.session.Session;
 import org.apache.shiro.session.mgt.DelegatingSession;
+import org.apache.shiro.subject.support.SubjectCallable;
+import org.apache.shiro.subject.support.SubjectRunnable;
 import org.apache.shiro.util.ThreadContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -37,6 +39,7 @@
 import java.net.InetAddress;
 import java.util.Collection;
 import java.util.List;
+import java.util.concurrent.Callable;
 
 /**
  * Implementation of the <tt>Subject</tt> interface that delegates
@@ -324,4 +327,18 @@
         }
     }
 
+    public <V> Callable<V> createCallable(Callable<V> callable) {
+        return new SubjectCallable<V>(this, callable);
+    }
+
+    public Runnable createRunnable(Runnable runnable) {
+        if (runnable instanceof Thread) {
+            String msg = "This implementation does not support Thread arguments because of
JDK ThreadLocal " +
+                    "inheritance mechanisms required by Shiro.  Instead, the method argument
should be a non-Thread " +
+                    "Runnable and the return value from this method can then be given to
an ExecutorService or " +
+                    "another Thread.";
+            throw new UnsupportedOperationException(msg);
+        }
+        return new SubjectRunnable(this, runnable);
+    }
 }

Modified: incubator/shiro/trunk/core/src/main/java/org/apache/shiro/subject/Subject.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/core/src/main/java/org/apache/shiro/subject/Subject.java?rev=806369&r1=806368&r2=806369&view=diff
==============================================================================
--- incubator/shiro/trunk/core/src/main/java/org/apache/shiro/subject/Subject.java (original)
+++ incubator/shiro/trunk/core/src/main/java/org/apache/shiro/subject/Subject.java Thu Aug
20 21:38:24 2009
@@ -18,27 +18,28 @@
  */
 package org.apache.shiro.subject;
 
-import java.util.Collection;
-import java.util.List;
-
 import org.apache.shiro.authc.AuthenticationException;
 import org.apache.shiro.authc.AuthenticationToken;
 import org.apache.shiro.authz.AuthorizationException;
 import org.apache.shiro.authz.Permission;
 import org.apache.shiro.session.Session;
 
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.Callable;
+
 /**
  * A <tt>Subject</tt> represents state and security operations for a <em>single</em>
application user.
  * These operations include authentication (login/logout), authorization (access control),
and
  * session access. It is Shiro's primary mechanism for single-user security functionality.
- *
+ * <p/>
  * <p>Note that there are many *Permission methods in this interface overloaded to
accept String arguments instead of
  * {@link Permission Permission} instances. They are a convenience allowing the caller to
use a String representation of
  * a {@link Permission Permission} if desired.  The underlying Authorization subsystem implementations
will usually
  * simply convert these String values to {@link Permission Permission} instances and then
just call the corresponding
  * type-safe method.  (Shiro's default implementations do String-to-Permission conversion
for these methods using
  * {@link org.apache.shiro.authz.permission.PermissionResolver PermissionResolver}s.)
- *
+ * <p/>
  * <p>These overloaded *Permission methods <em>do</em> forego type-saftey
for the benefit of convenience and simplicity,
  * so you should choose which ones to use based on your preferences and needs.
  *
@@ -51,18 +52,18 @@
     /**
      * Returns this Subject's uniquely-identifying principal, or <tt>null</tt>
if this
      * Subject doesn't yet have account data associated with it (for example, if they haven't
logged in).
-     *
+     * <p/>
      * <p>The term <em>principal</em> is just a fancy security term for
any identifying attribute(s) of an application
      * user, such as a username, or user id, or public key, or anything else you might use
in your application to
      * identify a user.  And although given names and family names (first/last) are technically
principals as well,
      * Shiro expects the object(s) returned from this method to be uniquely identifying attibute(s)
for
      * your application.  This implies that things like given names and family names are
usually poor candidates as
      * return values since they are rarely guaranteed to be unique.</p>
-     *
+     * <p/>
      * <p>Most single-Realm applications would return from this method a single unique
principal as noted above
      * (for example a String username or Long user id, etc, etc).  Single-realm applications
represent the large
      * majority of Shiro applications.</p>
-     *
+     * <p/>
      * <p>However, in <em>multi</em>-Realm configurations, which are fully
supported by Shiro as well, it is
      * possible that the return value encapsulates more than one principal.  Typically multi-realm
applications need to
      * retain the unique principals for <em>each</em> Realm so subsequent security
checks against these Realms can
@@ -82,7 +83,7 @@
      * social security number, nickname, username, etc, are all examples of a principal.
      * <p/>
      * This method returns all of the principals associated with the Subject, and it is expected
that at least one of
-     * the principals contained within this collection represent an absolute unique identifier
for the application.  
+     * the principals contained within this collection represent an absolute unique identifier
for the application.
      * User IDs, such a <code>Long</code> database primary key or UUID, or maybe
a globally unique username or email
      * address are all good candidates for such a unique identifier.  Non-unique things,
such as surnames and
      * given names, are often poor candidates.
@@ -101,7 +102,7 @@
     /**
      * Returns <tt>true</tt> if this Subject is permitted to perform an action
or access a resource summarized by the
      * specified permission string.
-     *
+     * <p/>
      * <p>This is an overloaded method for the corresponding type-safe {@link Permission
Permission} variant.
      * Please see the class-level JavaDoc for more information on these String-based permission
methods.
      *
@@ -115,7 +116,7 @@
     /**
      * Returns <tt>true</tt> if this Subject is permitted to perform an action
or access a resource summarized by the
      * specified permission.
-     *
+     * <p/>
      * <p>More specifically, this method determines if any <tt>Permission</tt>s
associated
      * with the subject {@link Permission#implies(Permission) imply} the specified permission.
      *
@@ -127,7 +128,7 @@
     /**
      * Checks if this Subject implies the given permission strings and returns a boolean
array indicating which
      * permissions are implied.
-     *
+     * <p/>
      * <p>This is an overloaded method for the corresponding type-safe {@link Permission
Permission} variant.
      * Please see the class-level JavaDoc for more information on these String-based permission
methods.
      *
@@ -143,11 +144,11 @@
     /**
      * Checks if this Subject implies the given Permissions and returns a boolean array indicating
which permissions
      * are implied.
-     *
+     * <p/>
      * <p>More specifically, this method should determine if each <tt>Permission</tt>
in
      * the array is {@link Permission#implies(Permission) implied} by permissions
      * already associated with the subject.
-     *
+     * <p/>
      * <p>This is primarily a performance-enhancing method to help reduce the number
of
      * {@link #isPermitted} invocations over the wire in client/server systems.
      *
@@ -161,7 +162,7 @@
 
     /**
      * Returns <tt>true</tt> if this Subject implies all of the specified permission
strings, <tt>false</tt> otherwise.
-     *
+     * <p/>
      * <p>This is an overloaded method for the corresponding type-safe {@link org.apache.shiro.authz.Permission
Permission} variant.
      * Please see the class-level JavaDoc for more information on these String-based permission
methods.
      *
@@ -174,7 +175,7 @@
 
     /**
      * Returns <tt>true</tt> if this Subject implies all of the specified permissions,
<tt>false</tt> otherwise.
-     *
+     * <p/>
      * <p>More specifically, this method determines if all of the given <tt>Permission</tt>s
are
      * {@link Permission#implies(Permission) implied by} permissions already associated with
this Subject.
      *
@@ -185,10 +186,10 @@
 
     /**
      * Ensures this Subject implies the specified permission String.
-     *
+     * <p/>
      * <p>If this subject's existing associated permissions do not {@link Permission#implies(Permission)}
imply}
      * the given permission, an {@link org.apache.shiro.authz.AuthorizationException} will
be thrown.
-     *
+     * <p/>
      * <p>This is an overloaded method for the corresponding type-safe {@link Permission
Permission} variant.
      * Please see the class-level JavaDoc for more information on these String-based permission
methods.
      *
@@ -201,7 +202,7 @@
 
     /**
      * Ensures this Subject {@link Permission#implies(Permission) implies} the specified
<tt>Permission</tt>.
-     *
+     * <p/>
      * <p>If this subject's exisiting associated permissions do not {@link Permission#implies(Permission)
imply}
      * the given permission, an {@link org.apache.shiro.authz.AuthorizationException} will
be thrown.
      *
@@ -215,11 +216,11 @@
      * Ensures this Subject
      * {@link org.apache.shiro.authz.Permission#implies(org.apache.shiro.authz.Permission)
implies} all of the
      * specified permission strings.
-     *
+     * <p/>
      * If this subject's exisiting associated permissions do not
      * {@link org.apache.shiro.authz.Permission#implies(org.apache.shiro.authz.Permission)
imply} all of the given permissions,
      * an {@link org.apache.shiro.authz.AuthorizationException} will be thrown.
-     *
+     * <p/>
      * <p>This is an overloaded method for the corresponding type-safe {@link Permission
Permission} variant.
      * Please see the class-level JavaDoc for more information on these String-based permission
methods.
      *
@@ -233,7 +234,7 @@
      * Ensures this Subject
      * {@link org.apache.shiro.authz.Permission#implies(org.apache.shiro.authz.Permission)
implies} all of the
      * specified permission strings.
-     *
+     * <p/>
      * If this subject's exisiting associated permissions do not
      * {@link org.apache.shiro.authz.Permission#implies(org.apache.shiro.authz.Permission)
imply} all of the given permissions,
      * an {@link org.apache.shiro.authz.AuthorizationException} will be thrown.
@@ -254,7 +255,7 @@
     /**
      * Checks if this Subject has the specified roles, returning a boolean array indicating
      * which roles are associated.
-     *
+     * <p/>
      * <p>This is primarily a performance-enhancing method to help reduce the number
of
      * {@link #hasRole} invocations over the wire in client/server systems.
      *
@@ -298,14 +299,15 @@
      * an {@link AuthenticationException} is thrown, the subclass of which identifies why
the attempt failed.
      * If successful, the account data associated with the submitted principals/credentials
will be
      * associated with this <tt>Subject</tt> and the method will return quietly.
-     *
-     * <p>Upon returninq quietly, this <tt>Subject</tt> instance can be
considered
+     * <p/>
+     * <p>Upon returning quietly, this <tt>Subject</tt> instance can be
considered
      * authenticated and {@link #getPrincipal() getPrincipal()} will be non-null and
      * {@link #isAuthenticated() isAuthenticated()} will be <tt>true</tt>.
      *
      * @param token the token encapsulating the subject's principals and credentials to be
passed to the
      *              Authentication subsystem for verification.
-     * @throws org.apache.shiro.authc.AuthenticationException if the authentication attempt
fails.
+     * @throws org.apache.shiro.authc.AuthenticationException
+     *          if the authentication attempt fails.
      * @since 0.9
      */
     void login(AuthenticationToken token) throws AuthenticationException;
@@ -313,7 +315,7 @@
     /**
      * Returns <tt>true</tt> if this Subject/user has proven their identity <em>during
their current session</em>
      * by providing valid credentials matching those known to the system, <tt>false</tt>
otherwise.
-     *
+     * <p/>
      * <p>Note that even if this Subject's identity has been remembered via 'remember
me' services, this method will
      * still return <tt>false</tt> unless the user has actually logged in with
proper credentials <em>during their
      * current session</em>.  See the
@@ -339,7 +341,7 @@
     /**
      * Returns the application <tt>Session</tt> associated with this Subject.
 Based on the boolean argument,
      * this method functions as follows:
-     *
+     * <p/>
      * <ul>
      * <li>If there is already an existing session associated with this <tt>Subject</tt>,
it is returned and
      * the <tt>create</tt> argument is ignored.</li>
@@ -356,10 +358,45 @@
     Session getSession(boolean create);
 
     /**
-     * Logs out this Subject and invalidates and/or removes any associated entities
-     * (such as a {@link Session Session} and authorization data.  After this method is called,
the Subject is
+     * Logs out this Subject and invalidates and/or removes any associated entities,
+     * such as a {@link Session Session} and authorization data.  After this method is called,
the Subject is
      * considered 'anonymous' and may continue to be used for another log-in if desired.
      */
     void logout();
 
+    /**
+     * Returns a {@code Callable} instance matching the given argument while additionally
ensuring that it will
+     * execute under this Subject's identity.  The returned object can be used with an
+     * {@link java.util.concurrent.ExecutorService ExecutorService} to execute as this Subject.
+     * thread.
+     *
+     * @param callable the callable to execute as this {@code Subject}
+     * @param <V>      the {@code Callable}s return value type
+     * @return a {@code Callable} that can be run as this {@code Subject}.
+     * @since 1.0
+     */
+    <V> Callable<V> createCallable(Callable<V> callable);
+
+    /**
+     * Returns a {@code Runnable} instance matching the given argument while additionally
ensuring that it will
+     * execute under this Subject's identity.  The returned object can be used with an
+     * {@link java.util.concurrent.Executor Executor} or another thread to execute as this
Subject.
+     * <p/>
+     * *Note that if you need a return value to be returned as a result of the runnable's
execution or if you need to
+     * react to any Exceptions, it is highly recommended to use the
+     * {@link #createCallable(java.util.concurrent.Callable) createCallable} method instead
of this one.
+     *
+     * @param runnable the runnable to execute as this {@code Subject}
+     * @return a {@code Runnable} that can be run as this {@code Subject} on another thread.
+     * @see #createCallable(java.util.concurrent.Callable)
+     * @since 1.0
+     */
+    Runnable createRunnable(Runnable runnable);
+
+    /*void runAs(PrincipalCollection identity);
+
+    <V> V runAs(PrincipalCollection identity, Callable<V> work);
+
+    PrincipalCollection getRunAsIdentity();*/
+
 }

Added: incubator/shiro/trunk/core/src/main/java/org/apache/shiro/subject/support/SubjectCallable.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/core/src/main/java/org/apache/shiro/subject/support/SubjectCallable.java?rev=806369&view=auto
==============================================================================
--- incubator/shiro/trunk/core/src/main/java/org/apache/shiro/subject/support/SubjectCallable.java
(added)
+++ incubator/shiro/trunk/core/src/main/java/org/apache/shiro/subject/support/SubjectCallable.java
Thu Aug 20 21:38:24 2009
@@ -0,0 +1,34 @@
+package org.apache.shiro.subject.support;
+
+import org.apache.shiro.subject.Subject;
+
+import java.util.concurrent.Callable;
+
+/**
+ * @since 1.0
+ */
+public class SubjectCallable<V> extends ThreadedExecutionSupport implements Callable<V>
{
+
+    private final Callable<V> callable;
+
+    public SubjectCallable(Subject subject, Callable<V> delegate) {
+        super(subject);
+        if (delegate == null) {
+            throw new IllegalArgumentException("Callable delegate instance cannot be null.");
+        }
+        this.callable = delegate;
+    }
+
+    public V call() throws Exception {
+        try {
+            bindThreadState();
+            return doCall(this.callable);
+        } finally {
+            restoreThreadState();
+        }
+    }
+
+    protected V doCall(Callable<V> target) throws Exception {
+        return target.call();
+    }
+}

Added: incubator/shiro/trunk/core/src/main/java/org/apache/shiro/subject/support/SubjectRunnable.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/core/src/main/java/org/apache/shiro/subject/support/SubjectRunnable.java?rev=806369&view=auto
==============================================================================
--- incubator/shiro/trunk/core/src/main/java/org/apache/shiro/subject/support/SubjectRunnable.java
(added)
+++ incubator/shiro/trunk/core/src/main/java/org/apache/shiro/subject/support/SubjectRunnable.java
Thu Aug 20 21:38:24 2009
@@ -0,0 +1,32 @@
+package org.apache.shiro.subject.support;
+
+import org.apache.shiro.subject.Subject;
+
+/**
+ * @since 1.0
+ */
+public class SubjectRunnable extends ThreadedExecutionSupport implements Runnable {
+
+    private final Runnable runnable;
+
+    public SubjectRunnable(Subject subject, Runnable delegate) {
+        super(subject);
+        if (delegate == null) {
+            throw new IllegalArgumentException("Runnable argument cannot be null.");
+        }
+        this.runnable = delegate;
+    }
+
+    public void run() {
+        try {
+            bindThreadState();
+            doRun();
+        } finally {
+            restoreThreadState();
+        }
+    }
+
+    protected void doRun() {
+        this.runnable.run();
+    }
+}

Added: incubator/shiro/trunk/core/src/main/java/org/apache/shiro/subject/support/ThreadedExecutionSupport.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/core/src/main/java/org/apache/shiro/subject/support/ThreadedExecutionSupport.java?rev=806369&view=auto
==============================================================================
--- incubator/shiro/trunk/core/src/main/java/org/apache/shiro/subject/support/ThreadedExecutionSupport.java
(added)
+++ incubator/shiro/trunk/core/src/main/java/org/apache/shiro/subject/support/ThreadedExecutionSupport.java
Thu Aug 20 21:38:24 2009
@@ -0,0 +1,102 @@
+package org.apache.shiro.subject.support;
+
+import org.apache.shiro.mgt.SecurityManager;
+import org.apache.shiro.session.Session;
+import org.apache.shiro.subject.DelegatingSubject;
+import org.apache.shiro.subject.Subject;
+import org.apache.shiro.util.ThreadContext;
+
+import java.io.Serializable;
+import java.net.InetAddress;
+
+/**
+ * @since 0.1
+ */
+public class ThreadedExecutionSupport {
+
+    private final Subject originalSubject;
+    private final InetAddress originalInetAddress;
+    private final Serializable originalSessionId;
+    private final transient SecurityManager originalSecurityManager;
+
+    /*protected static Subject assertThreadSubject() {
+        Subject subject = ThreadContext.getSubject();
+        if (subject == null) {
+            String msg = "Unable to acquire Subject instance from ThreadLocal via " +
+                    ThreadContext.class.getName() + ".getSubject().  This is most likely
due to a " +
+                    "configuration error - there should always be a Subject present when
using the " +
+                    "single argument " + SubjectCallable.class.getSimpleName() + " constructor.";
+            throw new IllegalStateException(msg);
+        }
+        return subject;
+    }
+
+    public SubjectCallable(Callable<V> delegate) {
+        this(delegate, assertThreadSubject());
+    }*/
+
+    public ThreadedExecutionSupport(Subject subject) {
+        if (subject == null) {
+            throw new IllegalArgumentException("Subject argument cannot be null.");
+        }
+        this.originalSubject = subject;
+
+        //TODO - not an interface call (yuck)
+        if (this.originalSubject instanceof DelegatingSubject) {
+            this.originalSecurityManager = ((DelegatingSubject) this.originalSubject).getSecurityManager();
+        } else {
+            this.originalSecurityManager = ThreadContext.getSecurityManager();
+        }
+
+        Session session = this.originalSubject.getSession(false);
+
+        InetAddress inet = null;
+        if (session != null) {
+            inet = session.getHostAddress();
+        }
+        if (inet == null) {
+            inet = ThreadContext.getInetAddress();
+        }
+        this.originalInetAddress = inet;
+
+        if (session != null) {
+            this.originalSessionId = session.getId();
+        } else {
+            this.originalSessionId = ThreadContext.getSessionId();
+        }
+    }
+
+    public void bindThreadState() {
+        ThreadContext.bind(this.originalSecurityManager);
+        ThreadContext.bind(this.originalSubject);
+        ThreadContext.bind(this.originalInetAddress);
+        ThreadContext.bindSessionId(this.originalSessionId);
+    }
+
+    public void restoreThreadState() {
+        if (originalSubject == null) {
+            ThreadContext.unbindSubject();
+        } else {
+            ThreadContext.bind(originalSubject);
+        }
+        if (originalInetAddress == null) {
+            ThreadContext.unbindInetAddress();
+        } else {
+            ThreadContext.bind(originalInetAddress);
+        }
+        if (originalSecurityManager == null) {
+            ThreadContext.unbindSecurityManager();
+        } else {
+            ThreadContext.bind(originalSecurityManager);
+        }
+        if (originalSessionId == null) {
+            ThreadContext.unbindSessionId();
+        } else {
+            ThreadContext.bindSessionId(originalSessionId);
+        }
+    }
+
+    public void clearAllThreadState() {
+        ThreadContext.clear();
+    }
+}

Modified: incubator/shiro/trunk/core/src/main/java/org/apache/shiro/util/ThreadContext.java
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/core/src/main/java/org/apache/shiro/util/ThreadContext.java?rev=806369&r1=806368&r2=806369&view=diff
==============================================================================
--- incubator/shiro/trunk/core/src/main/java/org/apache/shiro/util/ThreadContext.java (original)
+++ incubator/shiro/trunk/core/src/main/java/org/apache/shiro/util/ThreadContext.java Thu
Aug 20 21:38:24 2009
@@ -18,25 +18,24 @@
  */
 package org.apache.shiro.util;
 
+import org.apache.shiro.mgt.SecurityManager;
+import org.apache.shiro.subject.Subject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import java.io.Serializable;
 import java.net.InetAddress;
 import java.util.HashMap;
 import java.util.Map;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.shiro.mgt.SecurityManager;
-import org.apache.shiro.subject.Subject;
-
 
 /**
  * A ThreadContext provides a means of binding and unbinding objects to the
  * current thread based on key/value pairs.
- *
+ * <p/>
  * <p>An internal {@link java.util.HashMap} is used to maintain the key/value pairs
  * for each thread.</p>
- *
+ * <p/>
  * <p>If the desired behavior is to ensure that bound data is not shared across
  * threads in a pooled or reusable threaded environment, the application (or more likely
a framework) must
  * bind and remove any necessary values at the beginning and end of stack
@@ -121,10 +120,10 @@
 
     /**
      * Binds <tt>value</tt> for the given <code>key</code> to the
current thread.
-     *
+     * <p/>
      * <p>A <tt>null</tt> <tt>value</tt> has the same effect
as if <tt>remove</tt> was called for the given
      * <tt>key</tt>, i.e.:
-     *
+     * <p/>
      * <pre>
      * if ( value == null ) {
      *     remove( key );
@@ -188,7 +187,7 @@
      * Removes <em>all</em> values bound to this ThreadContext, which includes
any Subject, Session, or InetAddress
      * that may be bound by these respective objects' conveninece methods, as well as all
values bound by your
      * application code.
-     *
+     * <p/>
      * <p>This operation is meant as a clean-up operation that may be called at the
end of
      * thread execution to prevent data corruption in a pooled thread environment.
      */
@@ -221,11 +220,11 @@
 
     /**
      * Convenience method that simplifies binding the application's SecurityManager instance
to the ThreadContext.
-     *
+     * <p/>
      * <p>The method's existence is to help reduce casting in code and to simplify
remembering of
      * ThreadContext key names.  The implementation is simple in that, if the SecurityManager
is not <tt>null</tt>,
      * it binds it to the thread, i.e.:
-     *
+     * <p/>
      * <pre>
      * if (securityManager != null) {
      *     put( SECURITY_MANAGER_KEY, securityManager);
@@ -280,11 +279,11 @@
 
     /**
      * Convenience method that simplifies binding a Subject to the ThreadContext.
-     *
+     * <p/>
      * <p>The method's existence is to help reduce casting in your own code and to
simplify remembering of
      * ThreadContext key names.  The implementation is simple in that, if the Subject is
not <tt>null</tt>,
      * it binds it to the thread, i.e.:
-     *
+     * <p/>
      * <pre>
      * if (subject != null) {
      *     put( SUBJECT_KEY, subject );
@@ -336,11 +335,11 @@
 
     /**
      * Convenience method that simplifies binding an InetAddress to the ThreadContext.
-     *
+     * <p/>
      * <p>The method's existence is to help reduce casting in your own code and to
simplify remembering of
      * ThreadContext key names.  The implementation is simple in that, if the inetAddress
is not <tt>null</tt>,
      * it binds it to the thread, i.e.:
-     *
+     * <p/>
      * <pre>
      * if (inetAddress != null) {
      *     put( INET_ADDRESS_KEY, inetAddress );
@@ -385,7 +384,7 @@
         }
     }
 
-    public Serializable unbindSessionId() {
+    public static Serializable unbindSessionId() {
         return (Serializable) remove(SESSION_ID_KEY);
 
     }

Modified: incubator/shiro/trunk/pom.xml
URL: http://svn.apache.org/viewvc/incubator/shiro/trunk/pom.xml?rev=806369&r1=806368&r2=806369&view=diff
==============================================================================
--- incubator/shiro/trunk/pom.xml (original)
+++ incubator/shiro/trunk/pom.xml Thu Aug 20 21:38:24 2009
@@ -111,10 +111,10 @@
                 </executions>
                 <inherited>true</inherited>
             </plugin>
-            <plugin>
+            <!-- <plugin>
                 <groupId>com.agilejava.docbkx</groupId>
                 <artifactId>docbkx-maven-plugin</artifactId>
-                <!-- <version>2.0.7</version> -->
+                <!- - <version>2.0.7</version> - ->
                 <executions>
                     <execution>
                         <goals>
@@ -135,9 +135,9 @@
                 <configuration>
                     <includes>index.xml</includes>
                     <xincludeSupported>true</xincludeSupported>
-                    <!-- <foCustomization>src/docbkx/resources/xsl/fopdf.xsl</foCustomization>
+                    <!- - <foCustomization>src/docbkx/resources/xsl/fopdf.xsl</foCustomization>
                     <htmlCustomization>src/docbkx/resources/xsl/html_chunk.xsl</htmlCustomization>
-                    <htmlStylesheet>css/html.css</htmlStylesheet> -->
+                    <htmlStylesheet>css/html.css</htmlStylesheet> - ->
                     <chunkedOutput>true</chunkedOutput>
                     <entities>
                         <entity>
@@ -163,7 +163,7 @@
                         </copy>
                     </postProcess>
                 </configuration>
-            </plugin>
+            </plugin> -->
         </plugins>
     </build>
 



Mime
View raw message