View Javadoc

1   /*
2    * Copyright (C) 2004 TiongHiang Lee
3    *
4    * This library is free software; you can redistribute it and/or
5    * modify it under the terms of the GNU Lesser General Public
6    * License as published by the Free Software Foundation; either
7    * version 2.1 of the License, or (at your option) any later version.
8    *
9    * This library is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12   * Lesser General Public License for more details.
13   *
14   * You should have received a copy of the GNU Lesser General Public
15   * License along with this library; if not,  write to the Free Software
16   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17   *
18   * Email: thlee@onemindsoft.org
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          {   //add protection
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 }