KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > avalon > excalibur > lang > ThreadContext


1 /*
2  * Copyright (C) The Apache Software Foundation. All rights reserved.
3  *
4  * This software is published under the terms of the Apache Software License
5  * version 1.1, a copy of which has been included with this distribution in
6  * the LICENSE.txt file.
7  */

8 package org.apache.avalon.excalibur.lang;
9
10 import java.util.HashMap JavaDoc;
11 import java.util.Map JavaDoc;
12 import java.util.Iterator JavaDoc;
13
14 /**
15  * The ThreadContext defines a set of data that is associated
16  * with a particular thread. In particular this is useful as a
17  * location to centralize management of ThreadLocal-type variables.
18  * As such the type of data contained in <code>ThreadContext</code>
19  * is usually data such as ContextClassLoader, Transaction ID,
20  * User ID/Subject, etc. Note that these ThreadLocal variables may
21  * not actually be implemented using the <code>ThreadLocal</code>
22  * class but need to model such behaviour.
23  *
24  * <p>These variables are managed by the ThreadContext. However as it
25  * is not possible to inject code to be executed at the start of a
26  * thread, new threads may not be activated and the variables may not
27  * be set appropriately. In such cases it is recomended that the developer
28  * use <code>InheritableThreadLocal</code> as the underlying representation
29  * of the variable. By doing this the <code>InheritableThreadLocal</code>
30  * will maintain the appropriate state in newly created Thread.</p>
31  *
32  * <p>The policy chosend to manage such state is pluggable by the user.
33  * It is expected developers will provide a policy object that will manage
34  * thread local variables. For instance an application server may choose to
35  * keep the name of the application, the Subject it is running as and perhaps
36  * other state in such variables.</p>
37  *
38  * @author <a HREF="mailto:peter@apache.org">Peter Donald</a>
39  */

40 public final class ThreadContext
41 {
42     /**
43      * Permission used to guard setThreadContext method.
44      */

45     private final static RuntimePermission JavaDoc c_setThreadContext =
46         new RuntimePermission JavaDoc( "ThreadContext.setThreadContext" );
47
48     private final static InheritableThreadLocal JavaDoc c_context = new InheritableThreadLocal JavaDoc();
49
50     ///Accessor object used to provide policy with access to variables in context
51
private final ThreadContextAccessor m_accessor = new InnerThreadContextAccessor();
52
53     ///The policy for ThreadContext
54
private final ThreadContextPolicy m_policy;
55
56     ///Basic map to store variable mappings placed in context.
57
private final HashMap JavaDoc m_map;
58
59     /**
60      * Retrieve the ThreadContext associated with the current thread.
61      *
62      * @return the ThreadContext associated with the current thread.
63      */

64     public static ThreadContext getThreadContext()
65     {
66         return (ThreadContext)c_context.get();
67     }
68
69     /**
70      * Set the ThreadContext associated with the current thread.
71      * This code will also call <code>deactivate()</code> on the old
72      * <code>ThreadContext</code> if present and <code>activate()</code>
73      * on new <code>ThreadContext</code> (if not null).
74      *
75      * @param threadContext the new ThreadContext
76      * @exception SecurityException if the caller does not have permission to set thread pool
77      */

78     public static void setThreadContext( final ThreadContext threadContext )
79         throws SecurityException JavaDoc
80     {
81         final SecurityManager JavaDoc securityManager = System.getSecurityManager();
82         if( null != securityManager )
83         {
84             securityManager.checkPermission( c_setThreadContext );
85         }
86
87         final ThreadContext oldThreadContext = (ThreadContext)c_context.get();
88         if( null != oldThreadContext ) oldThreadContext.deactivate();
89
90         c_context.set( threadContext );
91         if( null != threadContext )
92         {
93             threadContext.activate();
94         }
95     }
96
97     /**
98      * Constructor that places values specified in <code>Map</code>
99      * into <code>ThreadContext</code>.
100      *
101      * @param map the Map
102      */

103     public ThreadContext( final ThreadContextPolicy policy, final Map JavaDoc map )
104     {
105         if( null == policy )
106         {
107             throw new NullPointerException JavaDoc( "policy property is null" );
108         }
109
110         if( null == map )
111         {
112             throw new NullPointerException JavaDoc( "map property is null" );
113         }
114
115         m_policy = policy;
116         m_map = new HashMap JavaDoc();
117
118         final Iterator JavaDoc keys = map.keySet().iterator();
119         while( keys.hasNext() )
120         {
121             final Object JavaDoc key = keys.next();
122             final Object JavaDoc value = map.get( key );
123             final String JavaDoc keyString = key.toString();
124             
125             m_policy.verifyKeyValue( keyString, value );
126             m_map.put( keyString, value );
127         }
128     }
129
130     /**
131      * Utility method to call activate on policy object.
132      */

133     private void activate()
134     {
135         m_policy.activate( m_accessor );
136     }
137
138     /**
139      * Utility method to call deactivate on policy object.
140      */

141     private void deactivate()
142     {
143         m_policy.deactivate( m_accessor );
144     }
145
146     /**
147      * Inner class to offer accessor interface to policy object.
148      */

149     private class InnerThreadContextAccessor implements ThreadContextAccessor
150     {
151         public boolean containsKey( final String JavaDoc key )
152         {
153             if( null == m_map ) return false;
154             else return m_map.containsKey( key );
155         }
156
157         public Object JavaDoc get( final String JavaDoc key )
158         {
159             if( null == m_map ) return null;
160             else return m_map.get( key );
161         }
162     }
163 }
164
Popular Tags