1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.onemind.commons.java.datastructure;
22
23 import java.util.*;
24 /***
25 * Associate a class and an value object and resolve the mapping through the
26 * class hierachy.
27 *
28 * For example, if a value object A is assosiated with Number class that
29 * means it is associated with the Number class and all the subclasses of
30 * object class. However, if a mapping exists for Integer, the InheritableValueMap
31 * will return the value object associated for the Integer.
32 *
33 * The stopClass controls when the InheritableValueMap stop resolving mapping and
34 * return null (when c==stopClass.getSuperClass()). The stopClass also control
35 * the hierachy of object that can be added the the map - meaning
36 * stopClass.isAssignableFrom(c) must evaluate to true when c is added as mapping key.
37 *
38 * @author TiongHiang Lee (thlee@onemindsoft.org)
39 * @version $Id: InheritableValueMap.java,v 1.3 2005/02/17 19:57:31 thlee Exp $ $Name: $
40 */
41 public class InheritableValueMap
42 {
43
44 /*** the mapping * */
45 private Map _map = new HashMap();
46
47 /*** the stop class * */
48 private Class _stopClass;
49
50 /***
51 * Use Object.class as stop class {@inheritDoc}
52 */
53 public InheritableValueMap()
54 {
55 this(Object.class);
56 }
57
58 /***
59 * {@inheritDoc}
60 * @param stopClass the stop class
61 */
62 public InheritableValueMap(Class stopClass)
63 {
64 _stopClass = stopClass;
65 }
66
67 /***
68 * Add the mapping between the class c and the object o. The object o must be the stopClass or a subclass of the stopClass
69 * @param c the class
70 * @param o the object
71 */
72 public void put(Class c, Object o)
73 {
74 if (!_stopClass.isAssignableFrom(c))
75 {
76 throw new IllegalArgumentException("Cannot add key class " + c
77 + " that is not a subclass of stopClass " + _stopClass);
78 }
79 _map.put(c, o);
80 }
81
82 /***
83 * Resolve the object associated with class c
84 * @param c the class
85 * @return the object associated with class c, or null
86 */
87 public Object resolve(Class c)
88 {
89 if (c == null)
90 {
91 return null;
92 } else if (!_stopClass.isAssignableFrom(c))
93 {
94 throw new RuntimeException(
95 "Cannot get entry for key class that is not a subclass of stopClass "
96 + _stopClass);
97 }
98 while (c != _stopClass.getSuperclass())
99 {
100 Object o = _map.get(c);
101 if (o != null)
102 {
103 return o;
104 }
105 c = c.getSuperclass();
106 }
107 return null;
108 }
109
110 /***
111 * Return the key classes
112 * @return the classes
113 */
114 public final Set keySet()
115 {
116 return _map.keySet();
117 }
118
119 /***
120 * Resolve all the mapping that could have apply to c in class c's inheritance hierachy
121 * @param c the class
122 * @return the Collection contains all the mappings
123 */
124 public Collection resolveAll(Class c)
125 {
126 if (!_stopClass.isAssignableFrom(c))
127 {
128 throw new RuntimeException(
129 "Cannot get entry for key class that is not a subclass of stopClass "
130 + _stopClass);
131 }
132 List l = new ArrayList();
133 while (c != _stopClass.getSuperclass())
134 {
135 Object o = _map.get(c);
136 if (o != null)
137 {
138 l.add(o);
139 }
140 c = c.getSuperclass();
141 }
142 return l;
143 }
144 }