1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package net.sf.morph.reflect.support;
17
18 import java.beans.Introspector;
19 import java.lang.reflect.InvocationTargetException;
20 import java.lang.reflect.Method;
21 import java.lang.reflect.Modifier;
22 import java.util.HashMap;
23 import java.util.Map;
24
25 import net.sf.morph.util.NumberUtils;
26
27 /**
28 * Provides easy access to the property information for a class.
29 *
30 * @author Matt Sgarlata
31 * @author Alexander Volanis
32 * @since Feb 3, 2005
33 */
34 public class ReflectionInfo {
35 private Map propertyAccessMethods = new HashMap();
36 private String[] propertyNames;
37
38 public ReflectionInfo(Class clazz) {
39 String propertyName;
40 Method[] methods = clazz.getMethods();
41 for (int i = 0; i < methods.length; i++) {
42 String methodName = methods[i].getName();
43 Class[] parameterTypes = methods[i].getParameterTypes();
44 if (!Modifier.isStatic(methods[i].getModifiers())) {
45
46 if (methodName.length() > 3 &&
47 methodName.indexOf("set") == 0 &&
48 Character.isUpperCase(methodName.charAt(3))) {
49 propertyName = Introspector.decapitalize(methodName.substring(3));
50
51 if (parameterTypes.length == 1) {
52 registerMutator(propertyName, methods[i]);
53 }
54
55 else if (parameterTypes.length == 2 &&
56 NumberUtils.isNumber(parameterTypes[0])) {
57 registerIndexedMutator(propertyName, methods[i]);
58 }
59 }
60
61 else if (methodName.length() > 3 &&
62 methodName.indexOf("get") == 0 &&
63 Character.isUpperCase(methodName.charAt(3))) {
64 propertyName = Introspector.decapitalize(methodName.substring(3));
65
66 if (parameterTypes.length == 0) {
67 registerAccessor(propertyName, methods[i]);
68 }
69
70 else if (parameterTypes.length == 1 &&
71 NumberUtils.isNumber(parameterTypes[0])) {
72 registerIndexedAccessor(propertyName, methods[i]);
73 }
74 }
75
76 else if (methodName.length() > 2 &&
77 methods[i].getReturnType().equals(Boolean.TYPE) &&
78 parameterTypes.length == 0 &&
79 methodName.indexOf("is") == 0 &&
80 Character.isUpperCase(methodName.charAt(2))) {
81 propertyName = Introspector.decapitalize(methodName.substring(2));
82 registerAccessor(propertyName, methods[i]);
83 }
84 }
85 }
86 propertyNames = (String[]) propertyAccessMethods.keySet().toArray(
87 new String[propertyAccessMethods.size()]);
88 }
89
90 protected MethodHolder createOrRetrieveMethodHolder(String propertyName) {
91 MethodHolder holder = (MethodHolder) propertyAccessMethods.get(propertyName);
92 if (holder == null) {
93 holder = new MethodHolder();
94 propertyAccessMethods.put(propertyName, holder);
95 }
96 return holder;
97 }
98
99 protected void registerAccessor(String propertyName, Method method) {
100 createOrRetrieveMethodHolder(propertyName).setAccessor(method);
101 }
102
103 protected void registerMutator(String propertyName, Method method) {
104 createOrRetrieveMethodHolder(propertyName).setMutator(method);
105 }
106
107 protected void registerIndexedAccessor(String propertyName, Method method) {
108 createOrRetrieveMethodHolder(propertyName).setIndexedAccessor(method);
109 }
110
111 protected void registerIndexedMutator(String propertyName, Method method) {
112 createOrRetrieveMethodHolder(propertyName).setIndexedMutator(method);
113 }
114
115 public MethodHolder getMethodHolder(String propertyName) {
116 return (MethodHolder) propertyAccessMethods.get(propertyName);
117 }
118
119 public void set(Object bean, String propertyName, Object value)
120 throws IllegalArgumentException, IllegalAccessException,
121 InvocationTargetException {
122 getMethodHolder(propertyName).invokeMutator(bean, value);
123 }
124
125 public void set(Object bean, String propertyName, Object index,
126 Object value) throws IllegalArgumentException,
127 IllegalAccessException, InvocationTargetException {
128 getMethodHolder(propertyName).invokeIndexedMutator(bean, index,
129 value);
130 }
131
132 public boolean isWriteable(String propertyName) {
133 return
134 getMethodHolder(propertyName) != null &&
135 (
136 getMethodHolder(propertyName).getMutator() != null ||
137 getMethodHolder(propertyName).getIndexedMutator() != null
138 );
139 }
140
141 public boolean isReadable(String propertyName) {
142 return
143 getMethodHolder(propertyName) != null &&
144 (
145 getMethodHolder(propertyName).getAccessor() != null ||
146 getMethodHolder(propertyName).getIndexedAccessor() != null
147 );
148 }
149
150 public String[] getPropertyNames() {
151 return propertyNames;
152 }
153
154 public Object get(Object bean, String propertyName) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
155 return getMethodHolder(propertyName).invokeAccessor(bean);
156 }
157
158 public Object get(Object bean, String propertyName, Object index) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
159 return getMethodHolder(propertyName).invokeIndexedAccessor(bean, index);
160 }
161
162 }