2020import java .lang .reflect .InvocationTargetException ;
2121import java .lang .reflect .Method ;
2222import java .lang .reflect .Modifier ;
23- import java .util .ArrayList ;
24- import java .util .Collections ;
25- import java .util .HashMap ;
26- import java .util .List ;
27- import java .util .Map ;
23+ import java .util .*;
2824import java .util .concurrent .ConcurrentHashMap ;
2925
3026import grails .util .GrailsClassUtils ;
31- import org .grails .beans .support .CachedIntrospectionResults ;
27+ import grails .util .GrailsNameUtils ;
28+ import groovy .lang .GroovyObjectSupport ;
29+ import groovy .lang .Script ;
30+ import org .springframework .beans .BeanUtils ;
3231import org .springframework .util .ReflectionUtils ;
3332import org .springframework .util .ReflectionUtils .FieldCallback ;
3433import org .springframework .util .ReflectionUtils .MethodCallback ;
4544 */
4645public class ClassPropertyFetcher {
4746
47+ private static final Set <String > IGNORED_FIELD_NAMES = new HashSet <String >() {{
48+ add ("class" );
49+ add ("metaClass" );
50+ }};
4851 private final Class <?> clazz ;
49- final Map <String , PropertyFetcher > staticFetchers = new HashMap <String , PropertyFetcher >();
50- final Map <String , PropertyFetcher > instanceFetchers = new HashMap <String , PropertyFetcher >();
52+ private final Map <String , PropertyFetcher > staticFetchers = new HashMap <>();
53+ private final Map <String , PropertyFetcher > instanceFetchers = new HashMap <>();
5154 private final ReferenceInstanceCallback callback ;
52- private PropertyDescriptor [] propertyDescriptors ;
55+ private final FieldCallback fieldCallback ;
56+ private final MethodCallback methodCallback ;
5357
5458 private static Map <Class <?>, ClassPropertyFetcher > cachedClassPropertyFetchers = new ConcurrentHashMap <Class <?>, ClassPropertyFetcher >();
5559
@@ -92,27 +96,7 @@ public Object getReferenceInstance() {
9296 protected ClassPropertyFetcher (Class <?> clazz , ReferenceInstanceCallback callback ) {
9397 this .clazz = clazz ;
9498 this .callback = callback ;
95- init ();
96- }
97-
98- public Object getReference () {
99- if (callback != null ) {
100- return callback .getReferenceInstance ();
101- }
102- return null ;
103- }
104-
105- public PropertyDescriptor [] getPropertyDescriptors () {
106- return propertyDescriptors ;
107- }
108-
109- public boolean isReadableProperty (String name ) {
110- return staticFetchers .containsKey (name )
111- || instanceFetchers .containsKey (name );
112- }
113-
114- private void init () {
115- FieldCallback fieldCallback = new ReflectionUtils .FieldCallback () {
99+ fieldCallback = new ReflectionUtils .FieldCallback () {
116100 public void doWith (Field field ) {
117101 if (field .isSynthetic ()) {
118102 return ;
@@ -124,29 +108,31 @@ public void doWith(Field field) {
124108
125109 final String name = field .getName ();
126110 if (name .indexOf ('$' ) == -1 ) {
111+ if (IGNORED_FIELD_NAMES .contains (name )) return ;
112+
127113 boolean staticField = Modifier .isStatic (modifiers );
128114 if (staticField ) {
129- staticFetchers .put (name , new FieldReaderFetcher (field ,
130- staticField ));
115+ staticFetchers .put (name , new FieldReaderFetcher (field ,true ));
131116 } else {
132- instanceFetchers .put (name , new FieldReaderFetcher (
133- field , staticField ));
117+ instanceFetchers .put (name , new FieldReaderFetcher (field , false ));
134118 }
135119 }
136120 }
137121 };
138122
139- MethodCallback methodCallback = new ReflectionUtils .MethodCallback () {
123+ methodCallback = new ReflectionUtils .MethodCallback () {
140124 public void doWith (Method method ) throws IllegalArgumentException ,
141125 IllegalAccessException {
142126 if (method .isSynthetic ()) {
143127 return ;
144128 }
145- if (!Modifier .isPublic (method .getModifiers ())) {
129+ int modifiers = method .getModifiers ();
130+ Class <?> returnType = method .getReturnType ();
131+
132+ if (!Modifier .isPublic (modifiers )) {
146133 return ;
147134 }
148- if (Modifier .isStatic (method .getModifiers ())
149- && method .getReturnType () != Void .class ) {
135+ if (returnType != Void .class && returnType != void .class ) {
150136 if (method .getParameterTypes ().length == 0 ) {
151137 String name = method .getName ();
152138 if (name .indexOf ('$' ) == -1 ) {
@@ -156,22 +142,46 @@ public void doWith(Method method) throws IllegalArgumentException,
156142 } else if (name .length () > 2
157143 && name .startsWith ("is" )
158144 && Character .isUpperCase (name .charAt (2 ))
159- && (method . getReturnType () == Boolean .class ||
160- method . getReturnType () == boolean .class )) {
145+ && (returnType == Boolean .class ||
146+ returnType == boolean .class )) {
161147 name = name .substring (2 );
162148 }
163- PropertyFetcher fetcher = new GetterPropertyFetcher (
164- method , true );
165- staticFetchers .put (name , fetcher );
166- staticFetchers .put (StringUtils .uncapitalize (name ), fetcher );
149+ if (Modifier .isStatic (modifiers )) {
150+ GetterPropertyFetcher fetcher = new GetterPropertyFetcher (method , true );
151+ staticFetchers .put (name , fetcher );
152+ staticFetchers .put (StringUtils .uncapitalize (name ),
153+ fetcher );
154+ } else {
155+ instanceFetchers .put (StringUtils .uncapitalize (name ),
156+ new GetterPropertyFetcher (method , false ));
157+ }
167158 }
168159 }
169160 }
170161 }
171162 };
163+ init ();
164+ }
165+
166+ public Object getReference () {
167+ if (callback != null ) {
168+ return callback .getReferenceInstance ();
169+ }
170+ return null ;
171+ }
172+
173+ public PropertyDescriptor [] getPropertyDescriptors () {
174+ return getPropertyDescriptors (clazz );
175+ }
176+
177+ public boolean isReadableProperty (String name ) {
178+ return staticFetchers .containsKey (name )
179+ || instanceFetchers .containsKey (name );
180+ }
172181
182+ private void init () {
173183 Class <?> superclass = clazz .getSuperclass ();
174- while (superclass != Object .class && superclass != null ) {
184+ while (superclass != Object .class && superclass != Script . class && superclass != GroovyObjectSupport . class && superclass != null ) {
175185 ClassPropertyFetcher superFetcher = ClassPropertyFetcher .forClass (superclass );
176186 staticFetchers .putAll (superFetcher .staticFetchers );
177187 instanceFetchers .putAll (superFetcher .instanceFetchers );
@@ -199,35 +209,10 @@ public void doWith(Method method) throws IllegalArgumentException,
199209 }
200210 }
201211
202- propertyDescriptors = getPropertyDescriptors (clazz );
203- for (PropertyDescriptor desc : propertyDescriptors ) {
204- Method readMethod = desc .getReadMethod ();
205- if (readMethod != null ) {
206- boolean staticReadMethod = Modifier .isStatic (readMethod .getModifiers ());
207- if (staticReadMethod ) {
208- staticFetchers .put (desc .getName (),
209- new GetterPropertyFetcher (readMethod , staticReadMethod ));
210- } else {
211- instanceFetchers .put (desc .getName (),
212- new GetterPropertyFetcher (readMethod , staticReadMethod ));
213- }
214- }
215- }
216212 }
217213
218214 private PropertyDescriptor [] getPropertyDescriptors (Class <?> clazz ) {
219- return CachedIntrospectionResults .forClass (clazz ).getPropertyDescriptors ();
220- }
221-
222- private List <Class <?>> resolveAllClasses (Class <?> c ) {
223- List <Class <?>> list = new ArrayList <Class <?>>();
224- Class <?> currentClass = c ;
225- while (currentClass != Object .class ) {
226- list .add (currentClass );
227- currentClass = currentClass .getSuperclass ();
228- }
229- Collections .reverse (list );
230- return list ;
215+ return BeanUtils .getPropertyDescriptors (clazz );
231216 }
232217
233218 public Object getPropertyValue (String name ) {
@@ -311,14 +296,14 @@ public Class<?> getPropertyType(String name, boolean onlyInstanceProperties) {
311296 return null ;
312297 }
313298
314- public static interface ReferenceInstanceCallback {
315- public Object getReferenceInstance ();
299+ public interface ReferenceInstanceCallback {
300+ Object getReferenceInstance ();
316301 }
317302
318- static interface PropertyFetcher {
319- public Object get (ReferenceInstanceCallback callback )
303+ interface PropertyFetcher {
304+ Object get (ReferenceInstanceCallback callback )
320305 throws IllegalArgumentException , IllegalAccessException , InvocationTargetException ;
321- public Class <?> getPropertyType (String name );
306+ Class <?> getPropertyType (String name );
322307 }
323308
324309 static class GetterPropertyFetcher implements PropertyFetcher {
0 commit comments