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]>