/Users/lyon/j4p/src/javagroup/util/Namespace.java

1    /* 
2     * This class is free software, do with it as you please. 
3     */ 
4     
5    package javagroup.util; 
6     
7    import java.util.Hashtable; 
8     
9    /** 
10    * Lightweight pseudo-namespace management class.   Designed as a replacement 
11    * for static code with state. 
12    * <p/> 
13    * TODO: more verbose explanation, discussion of usefulness and 
14    * implementation pattern essential. 
15    * 
16    * @author Luke Gorrie 
17    */ 
18   public class Namespace { 
19    
20       /** 
21        * child namespace 
22        */ 
23       protected Namespace _child; 
24    
25       // hashtable of instances, keyed by class 
26       private Hashtable _classToInstanceMap; 
27    
28       /* static 
29        */ 
30    
31       // top-level namespace 
32       private static Namespace __defaultNamespace; 
33    
34       static { 
35           __defaultNamespace = new Namespace(); 
36       } 
37    
38       /** 
39        * Constructs a Namespace with no root node.     The root node is assigned 
40        * when the Namespace is registered. 
41        */ 
42       public Namespace() { 
43    
44           _classToInstanceMap = new Hashtable(); 
45    
46       } 
47    
48       /** 
49        * Accessor method for gettting the namespace for the calling code. 
50        * This method should always be used to get a Namespace instance for 
51        * querying. 
52        * 
53        * @return The Namespace object the caller-code is supposed to use. 
54        */ 
55       public static Namespace getNamespace() { 
56    
57           return __defaultNamespace; 
58    
59       } 
60    
61       /** 
62        * Register the default instance for a class.   This should only be done 
63        * from the class that is being registered, and only from its static 
64        * init {} block, eg: <p> <code> class Foo { static { 
65        * Namespace.getNamespace() .registerDefaultInstanceForClass(Foo.class, 
66        * new Foo()); } } </code> 
67        */ 
68       public static void registerDefaultInstanceForClass(Class klass, 
69                                                          Object instance) { 
70    
71           __defaultNamespace.forceRegisterInstanceForClass(klass, instance); 
72    
73       } 
74    
75       /** 
76        * Register a new Namespace instance. 
77        * 
78        * @param namespace The new namespace to use. 
79        */ 
80       public synchronized void registerNamespace(Namespace namespace) { 
81    
82           if (_child == null) { 
83               _child = namespace; 
84           } else 
85               _child.registerNamespace(namespace); 
86    
87       } 
88    
89       /** 
90        * Register an instance for a class. 
91        * 
92        * @param klass    The class to register the instance for. 
93        * @param instance The instance of that class (must be instanceof the 
94        *                 class). 
95        */ 
96       public void registerInstanceForClass(Class klass, Object instance) { 
97    
98           if (_child != null) { 
99               _child.registerInstanceForClass(klass, instance); 
100              return; 
101          } 
102   
103          // check that it is an instance of the right class 
104          if (!klass.isInstance(instance)) 
105              throw new IllegalArgumentException(instance.toString() + 
106                      " is not an instance of " + 
107                      klass.getName()); 
108   
109          _classToInstanceMap.put(klass, instance); 
110   
111      } 
112   
113      /** 
114       * Get the registered instance for a given class. 
115       * 
116       * @param klass The class to get an instance of. 
117       * @return The registered instance for the given class. 
118       */ 
119      public Object getInstanceForClass(Class klass) { 
120   
121          Object instance; 
122   
123          if (_child != null) { 
124              instance = _child.getInstanceForClass(klass); 
125              if (instance != null) { 
126                  return instance; 
127              } 
128          } 
129   
130          return _classToInstanceMap.get(klass); 
131   
132      } 
133   
134      // register instance in this object without consulting the rest of the chain 
135      void forceRegisterInstanceForClass(Class klass, Object instance) { 
136   
137          _classToInstanceMap.put(klass, instance); 
138   
139      } 
140   
141  } 
142   
143   
144