KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > thoughtworks > xstream > converters > reflection > FieldDictionary


1 package com.thoughtworks.xstream.converters.reflection;
2
3 import java.lang.reflect.Field JavaDoc;
4 import java.util.Iterator JavaDoc;
5 import java.util.Map JavaDoc;
6 import java.util.TreeMap JavaDoc;
7
8 public class FieldDictionary {
9
10     private static final Map JavaDoc keyedByFieldNameCache = new TreeMap JavaDoc();
11     private static final Map JavaDoc keyedByFieldKeyCache = new TreeMap JavaDoc();
12
13     public Iterator JavaDoc serializableFieldsFor(Class JavaDoc cls) {
14         return buildMap(cls, true).values().iterator();
15     }
16
17     public Field JavaDoc field(Class JavaDoc cls, String JavaDoc name, Class JavaDoc definedIn) {
18         Map JavaDoc fields = buildMap(cls, definedIn != null);
19         Field JavaDoc field = (Field JavaDoc) fields.get(definedIn != null ? (Object JavaDoc) new FieldKey(name, definedIn) : (Object JavaDoc) name);
20         if (field == null) {
21             throw new ObjectAccessException("No such field " + cls.getName() + "." + name);
22         } else {
23             return field;
24         }
25     }
26
27     private Map JavaDoc buildMap(Class JavaDoc cls, boolean tupleKeyed) {
28         final String JavaDoc clsName = cls.getName();
29         if (!keyedByFieldNameCache.containsKey(clsName)) {
30             final Map JavaDoc keyedByFieldName = new TreeMap JavaDoc();
31             final Map JavaDoc keyedByFieldKey = new TreeMap JavaDoc();
32             while (!Object JavaDoc.class.equals(cls)) {
33                 Field JavaDoc[] fields = cls.getDeclaredFields();
34                 for (int i = 0; i < fields.length; i++) {
35                     Field JavaDoc field = fields[i];
36                     if (field.getName().startsWith("this$")) {
37                         continue;
38                     }
39                     field.setAccessible(true);
40                     if (!keyedByFieldName.containsKey(field.getName())) {
41                         keyedByFieldName.put(field.getName(), field);
42                     }
43                     keyedByFieldKey.put(new FieldKey(field.getName(), field.getDeclaringClass()), field);
44                 }
45                 cls = cls.getSuperclass();
46             }
47             keyedByFieldNameCache.put(clsName, keyedByFieldName);
48             keyedByFieldKeyCache.put(clsName, keyedByFieldKey);
49         }
50         return (Map JavaDoc) (tupleKeyed ? keyedByFieldKeyCache.get(clsName) : keyedByFieldNameCache.get(clsName));
51     }
52
53     private static class FieldKey implements Comparable JavaDoc {
54         private String JavaDoc fieldName;
55         private Class JavaDoc declaringClass;
56         private Integer JavaDoc depth;
57
58         public FieldKey(String JavaDoc fieldName, Class JavaDoc declaringClass) {
59             this.fieldName = fieldName;
60             this.declaringClass = declaringClass;
61             Class JavaDoc c = declaringClass;
62             int i = 0;
63             while (c.getSuperclass() != null) {
64                 i++;
65                 c = c.getSuperclass();
66             }
67             depth = new Integer JavaDoc(i);
68         }
69
70         public int compareTo(Object JavaDoc o) {
71             FieldKey t = (FieldKey) o;
72             int result = fieldName.compareTo(t.fieldName);
73             if (result == 0) {
74                 result = 0 - depth.compareTo(t.depth);
75             }
76             if (result == 0) {
77                 result = declaringClass.getName().compareTo(t.declaringClass.getName());
78             }
79             return result;
80         }
81     }
82
83 }
84
Popular Tags