/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