donaldp     02/04/25 22:38:49

  Modified:    threadcontext/src/java/org/apache/excalibur/threadcontext
                        ThreadContext.java ThreadContextAccessor.java
                        ThreadContextPolicy.java
               threadcontext/src/java/org/apache/excalibur/threadcontext/impl
                        DefaultThreadContextPolicy.java
  Added:       threadcontext/src/test/org/apache/excalibur/threadcontext/test
                        ThreadContextTestCase.java
  Log:
  Make ThreadContextPolicys responsible for restoring the old state/context 
when they are deactivated.
  
  Revision  Changes    Path
  1.5       +13 -19    
jakarta-avalon-excalibur/threadcontext/src/java/org/apache/excalibur/threadcontext/ThreadContext.java
  
  Index: ThreadContext.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-avalon-excalibur/threadcontext/src/java/org/apache/excalibur/threadcontext/ThreadContext.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ThreadContext.java        26 Apr 2002 04:01:22 -0000      1.4
  +++ ThreadContext.java        26 Apr 2002 05:38:49 -0000      1.5
  @@ -36,6 +36,7 @@
    * other state in such variables.</p>
    *
    * @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a>
  + * @version $Revision: 1.5 $ $Date: 2002/04/26 05:38:49 $
    */
   public final class ThreadContext
   {
  @@ -57,6 +58,12 @@
       private final HashMap m_map;
   
       /**
  +     * Map that contains any state that needs to be restored
  +     * by ThreadContextPolicy when the ThreadContext is deactivated.
  +     */
  +    private final HashMap m_oldState = new HashMap();
  +
  +    /**
        * This variable is set to the thread that the ThreadContext
        * is currently active on. A ThreadContext can not be active
        * on multiple threads at the same time.
  @@ -92,7 +99,7 @@
               securityManager.checkPermission( c_setThreadContext );
           }
   
  -        if( threadContext.isActive() )
  +        if( null != threadContext && threadContext.isActive() )
           {
               throw new IllegalArgumentException( "Specified ThreadContext is 
already " +
                                                   "bound to a thread" );
  @@ -157,7 +164,7 @@
        */
       private void activate()
       {
  -        m_policy.activate( m_accessor );
  +        m_policy.activate( m_accessor, m_oldState );
           m_activeThread = Thread.currentThread();
       }
   
  @@ -167,7 +174,8 @@
       private void deactivate()
       {
           m_activeThread = null;
  -        m_policy.deactivate( m_accessor );
  +        m_policy.deactivate( m_accessor, m_oldState );
  +        m_oldState.clear();
       }
   
       /**
  @@ -178,26 +186,12 @@
       {
           public boolean containsKey( final String key )
           {
  -            if( null == m_map )
  -            {
  -                return false;
  -            }
  -            else
  -            {
  -                return m_map.containsKey( key );
  -            }
  +            return m_map.containsKey( key );
           }
   
           public Object get( final String key )
           {
  -            if( null == m_map )
  -            {
  -                return null;
  -            }
  -            else
  -            {
  -                return m_map.get( key );
  -            }
  +            return m_map.get( key );
           }
       }
   }
  
  
  
  1.3       +1 -0      
jakarta-avalon-excalibur/threadcontext/src/java/org/apache/excalibur/threadcontext/ThreadContextAccessor.java
  
  Index: ThreadContextAccessor.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-avalon-excalibur/threadcontext/src/java/org/apache/excalibur/threadcontext/ThreadContextAccessor.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ThreadContextAccessor.java        9 Apr 2002 09:20:54 -0000       1.2
  +++ ThreadContextAccessor.java        26 Apr 2002 05:38:49 -0000      1.3
  @@ -14,6 +14,7 @@
    * world.
    *
    * @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a>
  + * @version $Revision: 1.3 $ $Date: 2002/04/26 05:38:49 $
    */
   public interface ThreadContextAccessor
   {
  
  
  
  1.3       +15 -4     
jakarta-avalon-excalibur/threadcontext/src/java/org/apache/excalibur/threadcontext/ThreadContextPolicy.java
  
  Index: ThreadContextPolicy.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-avalon-excalibur/threadcontext/src/java/org/apache/excalibur/threadcontext/ThreadContextPolicy.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ThreadContextPolicy.java  9 Apr 2002 09:20:54 -0000       1.2
  +++ ThreadContextPolicy.java  26 Apr 2002 05:38:49 -0000      1.3
  @@ -7,38 +7,49 @@
    */
   package org.apache.excalibur.threadcontext;
   
  +import java.util.Map;
  +
   /**
    * The <code>ThreadContextPolicy</code> determines the policy with
    * which items can be added to context. It determines what to do with
    * values when <code>ThreadContext</code> is activated and deactivated.
    * It also determines if a variable can be set.
    *
  + * <p>Note that it is expected that any changes to threads current
  + * state are reversible. And thus when activating that the enough data
  + * is stored in supplied map, so that when deactivate is called it can
  + * reliably restore previous state.</p>
  + *
    * <p>This interface is expected to be used as a Flyweight object.</p>
    *
    * @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a>
  + * @version $Revision: 1.3 $ $Date: 2002/04/26 05:38:49 $
    */
   public interface ThreadContextPolicy
   {
       /**
        * Key used to store <code>ContextClassLoader</code> in 
ThreadContextAccessor.
        */
  -    String CLASSLOADER = "ContextClassLoader";
  +    String CLASSLOADER = ClassLoader.class.getName();
   
       /**
        * The activate method is called when the ThreadContext
        * is associated with a thread.
        *
        * @param accessor the accessor to retrieve values from ThreadContext
  +     * @param oldContext the Map where data required to restore current 
context
  +     *        is stored.
        */
  -    void activate( ThreadContextAccessor accessor );
  +    void activate( ThreadContextAccessor accessor, Map oldContext );
   
       /**
        * The deactivate method is called when the ThreadContext is
        * dis-associated with a thread.
        *
  -     * @param accessor the accessor to retrieve values from ThreadContext
  +     * @param oldContext the set of data needed to restore context
  +     *        to the same state
        */
  -    void deactivate( ThreadContextAccessor accessor );
  +    void deactivate( ThreadContextAccessor accessor, Map oldContext );
   
       /**
        * Verify that the key/value pair is valid.
  
  
  
  1.2       +25 -7     
jakarta-avalon-excalibur/threadcontext/src/java/org/apache/excalibur/threadcontext/impl/DefaultThreadContextPolicy.java
  
  Index: DefaultThreadContextPolicy.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-avalon-excalibur/threadcontext/src/java/org/apache/excalibur/threadcontext/impl/DefaultThreadContextPolicy.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- DefaultThreadContextPolicy.java   10 Apr 2002 10:52:34 -0000      1.1
  +++ DefaultThreadContextPolicy.java   26 Apr 2002 05:38:49 -0000      1.2
  @@ -9,6 +9,7 @@
   
   import org.apache.excalibur.threadcontext.ThreadContextPolicy;
   import org.apache.excalibur.threadcontext.ThreadContextAccessor;
  +import java.util.Map;
   
   /**
    * Default <code>ThreadContextPolicy</code> that just maintains the
  @@ -16,6 +17,7 @@
    * class to extend for those wanting to write their own Policy.
    *
    * @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a>
  + * @version $Revision: 1.2 $ $Date: 2002/04/26 05:38:49 $
    */
   public class DefaultThreadContextPolicy
       implements ThreadContextPolicy
  @@ -27,12 +29,18 @@
        *
        * @param accessor the accessor to retrieve values from ThreadContext
        */
  -    public void activate( final ThreadContextAccessor accessor )
  +    public void activate( final ThreadContextAccessor accessor,
  +                          final Map store )
       {
  -        final ClassLoader classLoader = (ClassLoader)get( accessor, 
CLASSLOADER, null, ClassLoader.class );
  -        if( accessor.containsKey( CLASSLOADER ) ) 
  +        if( accessor.containsKey( CLASSLOADER ) )
           {
  -            Thread.currentThread().setContextClassLoader( classLoader );
  +            final ClassLoader oldLoader =
  +                Thread.currentThread().getContextClassLoader();
  +            store.put( CLASSLOADER, oldLoader );
  +
  +            final ClassLoader newLoader =
  +                (ClassLoader)get( accessor, CLASSLOADER, null, 
ClassLoader.class );
  +            Thread.currentThread().setContextClassLoader( newLoader );
           }
       }
   
  @@ -40,10 +48,18 @@
        * The deactivate method is called when the ThreadContext is
        * dis-associated with a thread.
        *
  -     * @param accessor the accessor to retrieve values from ThreadContext
  +     * @param store the store contianign data required to
  +     *        deactivate context
        */
  -    public void deactivate( final ThreadContextAccessor accessor )
  +    public void deactivate( final ThreadContextAccessor accessor,
  +                            final Map store )
       {
  +        if( accessor.containsKey( CLASSLOADER ) )
  +        {
  +            final ClassLoader classLoader =
  +                (ClassLoader)store.get( CLASSLOADER );
  +            Thread.currentThread().setContextClassLoader( classLoader );
  +        }
       }
   
       /**
  @@ -56,7 +72,9 @@
       public void verifyKeyValue( final String key, final Object value )
           throws IllegalArgumentException
       {
  -        if( key.equals( CLASSLOADER ) && !( value instanceof ClassLoader ) )
  +        if( key.equals( CLASSLOADER ) &&
  +            null != value &&
  +            !( value instanceof ClassLoader ) )
           {
               throw new IllegalArgumentException( "Key " + key + " must be of 
type " +
                                                   ClassLoader.class.getName() 
);
  
  
  
  1.1                  
jakarta-avalon-excalibur/threadcontext/src/test/org/apache/excalibur/threadcontext/test/ThreadContextTestCase.java
  
  Index: ThreadContextTestCase.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included  with this distribution in
   * the LICENSE.txt file.
   */
  package org.apache.excalibur.threadcontext.test;
  
  import java.util.HashMap;
  import java.net.URLClassLoader;
  import java.net.URL;
  import junit.framework.TestCase;
  import org.apache.excalibur.threadcontext.ThreadContext;
  import org.apache.excalibur.threadcontext.ThreadContextPolicy;
  import org.apache.excalibur.threadcontext.impl.DefaultThreadContextPolicy;
  
  /**
   * A basic test case that makes sure the ThreadContext
   * behaves as expected.
   *
   * @author <a href="mailto:[EMAIL PROTECTED]">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/04/26 05:38:49 $
   */
  public class ThreadContextTestCase
      extends TestCase
  {
      public ThreadContextTestCase( final String name )
      {
          super( name );
      }
  
      public void testNullClassPath()
          throws Exception
      {
          final ClassLoader oldValue =
              Thread.currentThread().getContextClassLoader();
  
          final HashMap map = new HashMap();
          final ClassLoader expected = null;
          map.put( ThreadContextPolicy.CLASSLOADER, expected );
          setThreadContext( map );
          final ClassLoader newValue =
              Thread.currentThread().getContextClassLoader();
  
          assertEquals( "In ThreadContext, ContextClassLoader",
                        expected, newValue );
  
          ThreadContext.setThreadContext( null );
  
          final ClassLoader currentValue =
              Thread.currentThread().getContextClassLoader();
          assertEquals( "After Left ThreadContext, ContextClassLoader",
                        oldValue, currentValue );
      }
  
      public void testNonNullClassPath()
          throws Exception
      {
          final ClassLoader oldValue =
              Thread.currentThread().getContextClassLoader();
  
          final HashMap map = new HashMap();
          final ClassLoader expected = new URLClassLoader( new URL[ 0 ] );
          map.put( ThreadContextPolicy.CLASSLOADER, expected );
          setThreadContext( map );
          final ClassLoader newValue =
              Thread.currentThread().getContextClassLoader();
  
          assertEquals( "In ThreadContext, ContextClassLoader",
                        expected, newValue );
  
          ThreadContext.setThreadContext( null );
  
          final ClassLoader currentValue =
              Thread.currentThread().getContextClassLoader();
          assertEquals( "After Left ThreadContext, ContextClassLoader",
                        oldValue, currentValue );
      }
  
      private void setThreadContext( final HashMap map )
      {
          final DefaultThreadContextPolicy policy = new 
DefaultThreadContextPolicy();
          final ThreadContext context = new ThreadContext( policy, map );
          ThreadContext.setThreadContext( context );
      }
  }
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to