KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > de > susebox > java > lang > EnvironmentProvider


1 /*
2  * EnvironmentProvider.java: A central storage for Environment instances.
3  *
4  * Copyright (C) 2002 Heiko Blau
5  *
6  * This file belongs to the Susebox Java Core Library (Susebox JCL).
7  * The Susebox JCL is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as published by the
9  * Free Software Foundation; either version 2.1 of the License, or (at your
10  * option) any later version.
11  *
12  * This software is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.
15  * See the GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License along
18  * with the Susebox JCL. If not, write to the
19  *
20  * Free Software Foundation, Inc.
21  * 59 Temple Place, Suite 330,
22  * Boston, MA 02111-1307
23  * USA
24  *
25  * or check the Internet: http://www.fsf.org
26  *
27  * Contact:
28  * email: heiko@susebox.de
29  */

30
31 package de.susebox.java.lang;
32
33 //-----------------------------------------------------------------------------
34
// Imports
35
//
36
import java.util.Hashtable JavaDoc;
37 import de.susebox.java.lang.ExtNullPointerException;
38
39
40 //-----------------------------------------------------------------------------
41
// Class EnvironmentProvider
42
//
43

44 /**<p>
45  * The <code>EnvironmentProvider</code> is a singleton object to store and provide
46  * {@link Environment} instances. It provides the possibility to register and
47  * retrieve <code>Environment</code> instances on a per object or per class base.
48  *</p><p>
49  * Since an <code>Environment</code> is designed as a substitute for some features
50  * of the JDK {@link java.lang.System} class, the retrieval of the <code>Environment</code>
51  * associated with a class should be possible without additional information about
52  * the context. Class-based <code>Environment</code> objects are also associated with
53  * the thread, that actually registered the instance.
54  *</p>
55  *
56  * @author Heiko Blau
57  */

58 public final class EnvironmentProvider {
59   
60   /**
61    * This method returns an {@link Environment} instance that has been registered
62    * for the given object.
63    *<br>
64    * If there is no specific <code>Environment</code> instance available for the
65    * object then its class name is used to find a more general <code>Environment</code>
66    * instance.
67    *<br>
68    * If still no <code>Environment</code> could be found a default <code>Environment</code>
69    * is returned, usually a {@link DefaultEnvironment} instance.
70    *<br>
71    * The method will always return an <code>Environment</code> instance except
72    * for runtime exceptions.
73    *
74    * @param obj the object thats environment should be retrieved
75    * @return an {@link Environment} instance for the caller
76    * @see Environment
77    * @see DefaultEnvironment
78    */

79   public static Environment getEnvironment(Object JavaDoc obj) {
80     Environment env = null;
81
82     // try to find an environment going up the class hierarchy
83
if (obj != null && _environmentMap != null) {
84       synchronized(_syncMonitor) {
85         Object JavaDoc iterObj = obj;
86           
87         do {
88           if (iterObj instanceof Class JavaDoc) {
89             env = (Environment)_environmentMap.get(new EnvironmentKey((Class JavaDoc)iterObj));
90             iterObj = ((Class JavaDoc)iterObj).getSuperclass();
91           } else {
92             env = (Environment)_environmentMap.get(iterObj);
93             iterObj = iterObj.getClass();
94           }
95           if (env != null) {
96             break;
97           }
98         } while (iterObj instanceof Class JavaDoc);
99       }
100     }
101     
102     // not found ? Than take the default environment
103
if (env == null) {
104       synchronized(_syncMonitor) {
105         if (_defaultEnvironment == null) {
106           _defaultEnvironment = new DefaultEnvironment();
107         }
108         env = _defaultEnvironment;
109       }
110     }
111     return env;
112   }
113   
114   /**
115    * Registering an {@link Environment} for the given object. If this object
116    * is a {@link java.lang.Class} instance, the <code>Environment</code> is
117    * common for all instances of this class and its subclasses.
118    *
119    * @param obj the object the given {@link Environment} is for
120    * @param env the {@link Environment} to store
121    * @throws NullPointerException if one of the parameters is <code>null</code>
122    */

123   public static void setEnvironment(Object JavaDoc obj, Environment env) throws NullPointerException JavaDoc {
124     // test parameters
125
if (obj == null) {
126       throw new ExtNullPointerException("No object given.");
127     } else if (env == null) {
128       throw new ExtNullPointerException("No environment given.");
129     }
130     
131     // create hashtable for the environments
132
synchronized(_syncMonitor) {
133       if (_environmentMap == null) {
134         _environmentMap = new Hashtable JavaDoc();
135       }
136     
137       // store the environment
138
if (obj instanceof Class JavaDoc) {
139         _environmentMap.put(new EnvironmentKey((Class JavaDoc)obj), env);
140       } else {
141         _environmentMap.put(obj, env);
142       }
143     }
144   }
145   
146   
147   /**
148    * Removing a registered {@link Environment}. If the given object is not known
149    * to the <code>EnvironmentProvider</code> the method does nothing.
150    *
151    * @param obj the object thats {@link Environment} should be removed
152    */

153   public static void removeEnvironment(Object JavaDoc obj) {
154     if (obj != null && _environmentMap != null) {
155       if (obj instanceof Class JavaDoc) {
156         _environmentMap.remove(new EnvironmentKey((Class JavaDoc)obj));
157       } else {
158         _environmentMap.remove(obj);
159       }
160     }
161   }
162   
163   
164   //---------------------------------------------------------------------------
165
// inner class
166
//
167

168   /**
169    * This class stores a {@link java.lang.Class} object and the current thread
170    * to form a key for class-based environment registration
171    *
172    * @see EnvironmentProvider#setEnvironment
173    * @see EnvironmentProvider#getEnvironment
174    */

175   static final class EnvironmentKey {
176     
177     /**
178      * The constructor takes the {@link java.lang.Class} object that forms the
179      * first part of the key. It automatically adds the calling thread to the
180      * key
181      *
182      * @param cl the <code>Class</code> object that is the first part of the key.
183      */

184     public EnvironmentKey(Class JavaDoc cl) {
185       synchronized(this) {
186         _class = cl;
187         _thread = Thread.currentThread();
188       }
189     }
190     
191     /**
192      * Checking the equality of this instance to another {@link java.lang.Object}.
193      *
194      * @param obj the reference object with which to compare
195      * @return <code>true</code> if this object is the same as the obj argument;
196      * <code>false</code> otherwise.
197      */

198     public boolean equals(Object JavaDoc obj) {
199       if (obj == this) {
200         return true;
201       } else if (obj == null) {
202         return false;
203       } else if ( ! (obj instanceof EnvironmentKey)) {
204         return false;
205       } else {
206         EnvironmentKey key = (EnvironmentKey)obj;
207         
208         if (_thread == key._thread && _class.equals(key._class)) {
209           return true;
210         } else {
211           return false;
212         }
213       }
214     }
215     
216     /**
217      * Providing the has code for this key.
218      *
219      * @return the hash code for this instance
220      */

221     public int hashCode() {
222       return (_thread.hashCode() << 4) + _class.getName().hashCode();
223     }
224
225     //-------------------------------------------------------------------------
226
// members
227
//
228
private Class JavaDoc _class = null;
229     private Thread JavaDoc _thread = null;
230   }
231   
232   
233   //---------------------------------------------------------------------------
234
// members
235
//
236
private static DefaultEnvironment _defaultEnvironment = null;
237   private static Hashtable JavaDoc _environmentMap = null;
238   private static Object JavaDoc _syncMonitor = new Object JavaDoc();
239 }
240
241
Popular Tags