View Javadoc

1   //
2   // Copyright (c) 2003, Caltha - Gajda, Krzewski, Mach, Potempski Sp.J.
3   // All rights reserved.
4   //
5   // Redistribution and use in source and binary forms, with or without modification, 
6   // are permitted provided that the following conditions are met:
7   //
8   // * Redistributions of source code must retain the above copyright notice, 
9   //	 this list of conditions and the following disclaimer.
10  // * Redistributions in binary form must reproduce the above copyright notice, 
11  //	 this list of conditions and the following disclaimer in the documentation 
12  //	 and/or other materials provided with the distribution.
13  // * Neither the name of the Caltha - Gajda, Krzewski, Mach, Potempski Sp.J. 
14  //	 nor the names of its contributors may be used to endorse or promote products 
15  //	 derived from this software without specific prior written permission.
16  //
17  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
18  // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
19  // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  // IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
21  // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
22  // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
23  // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
24  // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
25  // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
26  // POSSIBILITY OF SUCH DAMAGE.
27  //
28  
29  package org.objectledge.context;
30  
31  import java.util.HashMap;
32  import java.util.Map;
33  
34  /***
35   * Context gives the application an ability to reference arbitrary objects using String names.
36   * 
37   * <p>The bindings are local to the calling thread. This is a convenient way of passing data 
38   * associated with a stream of processing without putting them into method attributes. This is 
39   * especialy convenient with data that are not needed at a specific stage of processing, but may 
40   * be needed by the nested stages - for example security credentials.</p>
41   * 
42   * <p><b>Note!</b>It is important to clear the context before the thread departs from within 
43   * application boundaries - otherwise the references may prevent the objects (and as a result 
44   * large graphs of objects including classes and classloaders) from being garbage collected, while
45   * being otherwise being eligible to collection.</p>  
46   *
47   * @author <a href="Rafal.Krzewski">rafal@caltha.pl</a>
48   * @version $Id: Context.java,v 1.8 2005/11/18 11:39:33 rafal Exp $
49   */
50  public class Context
51  {
52      /*** storage of the context attributes, specific to a thread. */
53      private static ThreadLocal threadAttributes = new ThreadLocal();
54  
55      /***
56       * Return the value of a context attribute.
57       * 
58       * @param name the attribute name.
59       * @return the value of the attribute.
60       */
61      public Object getAttribute(String name)
62      {
63          return getAttributes().get(name); 
64      }
65  
66      /***
67       * Return the value of a context attribute.
68       * 
69       * <p>Class object and the class name String are considered to be equivalent keys.</p>
70       * 
71       * @param <T> the type reflected by key Class object, to avoid casting on the caller's side.
72       * @param key a Class key of the attribute.
73       * @return the value of the attribute.
74       */
75      public <T> T getAttribute(Class<T> key)
76      {
77          return (T)getAttributes().get(key.getName()); 
78      }
79  
80      /***
81       * Sets a new value of a context attribute.
82       * 
83       * @param name the name of the attribute.
84       * @param value the new value of the attribute.
85       * @return the old value of the attribute.
86       */    
87      public Object setAttribute(String name, Object value)
88      {
89          return getAttributes().put(name, value);
90      }
91  
92      /***
93       * Sets a new value of a context attribute.
94       *
95       * <p>Class object and the class name String are considered to be equivalent keys.</p>
96       *       
97       * @param key Class key of the attribute.
98       * @param value the new value of the attribute.
99       * @return the old value of the attribute.
100      */    
101     public Object setAttribute(Class key, Object value)
102     {
103         return getAttributes().put(key.getName(), value);
104     }
105     
106     /***
107      * Removes a context attribute.
108      * 
109      * @param name the name of the attribute.
110      * @return the old value of the attribute.
111      */
112     public Object removeAttribute(String name)
113     {
114         return getAttributes().remove(name);
115     }
116 
117     /***
118      * Removes a context attribute.
119      * 
120      * <p>Class object and the class name String are considered to be equivalent keys.</p>
121      *       
122      * @param key Class key of the attribute.
123      * @return the old value of the attribute.
124      */
125     public Object removeAttribute(Class key)
126     {
127         return getAttributes().remove(key.getName());
128     }
129     
130     /***
131      * Removes all context attributes.
132      */
133     public void clearAttributes()
134     {
135         getAttributes().clear();
136     }
137     
138     // - implementation -----------------------------------------------------
139     
140     private Map getAttributes()
141     {
142         Map attributes = (Map)threadAttributes.get();
143         if(attributes == null)
144         {
145             attributes = new HashMap();
146             threadAttributes.set(attributes);
147         }
148         return attributes;
149     }
150 }