KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > cache > aop > CachedType


1 /*
2 * JBoss, the OpenSource J2EE webOS
3 *
4 * Distributable under LGPL license.
5 * See terms of license at gnu.org.
6 */

7 package org.jboss.cache.aop;
8
9 import java.lang.reflect.Field JavaDoc;
10 import java.lang.reflect.Method JavaDoc;
11 import java.lang.reflect.Modifier JavaDoc;
12 import java.util.*;
13
14 /** Represent a cached object type, e.g., whether it is <b>primitive</b> or not.
15  *
16  * @author <a HREF="mailto:harald@gliebe.de">Harald Gliebe</a>
17  * @author Ben Wang
18  */

19
20 public class CachedType
21 {
22    // Types that are considered "primitive".
23
protected static Set immediates =
24          new HashSet(Arrays.asList(new Object JavaDoc[]{
25             String JavaDoc.class,
26             Boolean JavaDoc.class,
27             Double JavaDoc.class,
28             Float JavaDoc.class,
29             Integer JavaDoc.class,
30             Long JavaDoc.class,
31             Short JavaDoc.class,
32             Character JavaDoc.class,
33             Boolean.TYPE,
34             Double.TYPE,
35             Float.TYPE,
36             Integer.TYPE,
37             Long.TYPE,
38             Short.TYPE,
39             Character.TYPE,
40             Class JavaDoc.class}));
41
42    protected Class JavaDoc type;
43    protected boolean immutable;
44    protected boolean immediate;
45
46    // Java Bean attributes (Get/Set)
47
protected List attributes = new ArrayList();
48    protected Map attributeMap = new HashMap(); // Method -> CachedAttribute
49

50    // Java fields
51
protected List fields = new ArrayList();
52    protected Map fieldMap = new HashMap(); // Name -> CachedAttribute
53

54    public CachedType()
55    {
56    }
57
58    public CachedType(Class JavaDoc type)
59    {
60       this.type = type;
61       analyze();
62    }
63
64    public Class JavaDoc getType()
65    {
66       return type;
67    }
68
69    // determines if the object should be stored in the Nodes map or as a subnode
70
public boolean isImmediate()
71    {
72       return immediate;
73    }
74
75    public static boolean isImmediate(Class JavaDoc clazz)
76    {
77       return immediates.contains(clazz);
78    }
79
80    public boolean isImmutable()
81    {
82       return immutable;
83    }
84
85    public List getFields()
86    {
87       return fields;
88    }
89
90    public Field JavaDoc getField(String JavaDoc name)
91    {
92       return (Field JavaDoc) fieldMap.get(name);
93    }
94
95    /*
96    public List getAttributes()
97    {
98       return attributes;
99    }
100
101    public CachedAttribute getAttribute(Method m)
102    {
103       return (CachedAttribute) attributeMap.get(m);
104    }
105
106    protected void setAttributes(List attributes)
107    {
108       this.attributes = attributes;
109
110       attributeMap.clear();
111
112       // TODO: is a class with no set methods immutable ?
113       this.immutable = true;
114
115       for (Iterator i = attributes.iterator(); i.hasNext();) {
116          CachedAttribute attribute = (CachedAttribute) i.next();
117          if (attribute.getGet() != null) {
118             attributeMap.put(attribute.getGet(), attribute);
119          }
120          if (attribute.getSet() != null) {
121             attributeMap.put(attribute.getSet(), attribute);
122             immutable = false;
123          }
124       }
125    }
126    */

127
128    public String JavaDoc toString()
129    {
130       StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
131       sb.append(type.getName()).append(" {\n");
132       for (Iterator i = attributes.iterator(); i.hasNext();) {
133          CachedAttribute attr = (CachedAttribute) i.next();
134          sb
135                .append("\t")
136                .append(attr.getType().getName())
137                .append(" ")
138                .append(attr.getName())
139                .append(" [")
140                .append(attr.getGet() == null
141                ? "<no get>"
142                : attr.getGet().getName())
143                .append(", ")
144                .append(attr.getSet() == null
145                ? "<no set>"
146                : attr.getSet().getName())
147                .append("]\n");
148       }
149       sb.append("}, immutable =" + immutable);
150       return sb.toString();
151    }
152
153    /* ---------------------------------------- */
154
155    private void analyze()
156    {
157
158       /*
159       // We intercept all fields now (instead of setter methods) so there is no need to
160       // track the individual fields.
161       HashMap attributes = new HashMap();
162       Method[] methods = type.getMethods();
163       for (int i = 0; i < methods.length; i++) {
164          Method method = methods[i];
165          if (isGet(method)) {
166             CachedAttribute attribute =
167                   getAttribute(method, attributes, true);
168             attribute.setGet(method);
169             attribute.setType(method.getReturnType());
170          } else if (isSet(method)) {
171             CachedAttribute attribute =
172                   getAttribute(method, attributes, true);
173             attribute.setSet(method);
174             attribute.setType(method.getParameterTypes()[0]);
175          }
176       }
177       this.setAttributes(new ArrayList(attributes.values()));
178       */

179       analyzeFields(type);
180
181       immediate = isImmediate(type);
182
183    }
184
185    void analyzeFields(Class JavaDoc clazz)
186    {
187       if (clazz == null)
188          return;
189
190       analyzeFields(clazz.getSuperclass());
191
192       Field JavaDoc[] classFields = clazz.getDeclaredFields();
193       for (int i = 0; i < classFields.length; i++) {
194          Field JavaDoc f = classFields[i];
195          if(isNonReplicatable(f)) continue;
196
197          f.setAccessible(true);
198          fields.add(f);
199          fieldMap.put(f.getName(), f);
200       }
201    }
202
203    public static boolean isNonReplicatable(Field JavaDoc f) {
204       int mods = f.getModifiers();
205       /**
206        * The following modifiers are ignored in the cache, i.e., they will not be stored in the cache.
207        * Whenever, user trying to access these fields, it will be accessed from the in-memory version.
208        */

209       if (Modifier.isStatic(mods)
210             || Modifier.isTransient(mods)
211             || Modifier.isFinal(mods)) {
212          return true;
213       }
214       return false;
215    }
216
217    /*
218     * converts a get/set method to an attribute name
219     */

220    protected String JavaDoc attributeName(String JavaDoc methodName)
221    {
222       return methodName.substring(3, 4).toLowerCase()
223             + methodName.substring(4);
224    }
225
226    protected CachedAttribute getAttribute(Method JavaDoc method,
227                                           Map map,
228                                           boolean create)
229    {
230       String JavaDoc name = attributeName(method.getName());
231
232       CachedAttribute attribute = (CachedAttribute) map.get(name);
233       if (create && attribute == null) {
234          attribute = new CachedAttribute(name);
235          map.put(name, attribute);
236       }
237       return attribute;
238    }
239
240    protected boolean isGet(Method JavaDoc method)
241    {
242       return method.getName().startsWith("get")
243             && method.getParameterTypes().length == 0
244             && method.getReturnType() != Void.TYPE;
245    }
246
247    protected boolean isSet(Method JavaDoc method)
248    {
249       return method.getName().startsWith("set")
250             && method.getParameterTypes().length == 1
251             && method.getReturnType() == Void.TYPE;
252    }
253
254 } // CachedType
255
Popular Tags