2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com
.intellij
.util
.xml
;
18 import com
.intellij
.openapi
.progress
.ProcessCanceledException
;
19 import com
.intellij
.openapi
.util
.text
.StringUtil
;
20 import com
.intellij
.util
.ReflectionUtil
;
21 import org
.jetbrains
.annotations
.Nullable
;
23 import java
.lang
.annotation
.Annotation
;
24 import java
.lang
.reflect
.*;
25 import java
.util
.Arrays
;
26 import java
.util
.Collection
;
27 import java
.util
.List
;
32 public class DomReflectionUtil
{
33 private DomReflectionUtil() {
36 public static <T
extends Annotation
> T
findAnnotationDFS(final Class
<?
> rawType
, final Class
<T
> annotationType
) {
37 T annotation
= rawType
.getAnnotation(annotationType
);
38 if (annotation
!= null) return annotation
;
40 for (Class aClass
: rawType
.getInterfaces()) {
41 annotation
= findAnnotationDFS(aClass
, annotationType
);
42 if (annotation
!= null) {
49 public static <T
extends Annotation
> T
findAnnotationDFS(final Method method
, final Class
<T
> annotationClass
) {
50 return JavaMethodSignature
.getSignature(method
).findAnnotation(annotationClass
, method
.getDeclaringClass());
53 public static boolean canHaveIsPropertyGetterPrefix(final Type type
) {
54 return boolean.class.equals(type
) || Boolean
.class.equals(type
)
55 || Boolean
.class.equals(DomUtil
.getGenericValueParameter(type
));
58 public static JavaMethod
[] getGetterMethods(final String
[] path
, final Class
<?
extends DomElement
> startClass
) {
59 final JavaMethod
[] methods
= new JavaMethod
[path
.length
];
60 Class aClass
= startClass
;
61 for (int i
= 0; i
< path
.length
; i
++) {
62 final JavaMethod getter
= findGetter(aClass
, path
[i
]);
63 assert getter
!= null : "Couldn't find getter for property " + path
[i
] + " in class " + aClass
;
65 aClass
= getter
.getReturnType();
66 if (List
.class.isAssignableFrom(aClass
)) {
67 aClass
= ReflectionUtil
.getRawType(extractCollectionElementType(getter
.getGenericReturnType()));
74 public static JavaMethod
findGetter(Class aClass
, String propertyName
) {
75 final String capitalized
= StringUtil
.capitalize(propertyName
);
76 Method method
= ReflectionUtil
.getMethod(aClass
, "get" + capitalized
);
77 if (method
!= null) return JavaMethod
.getMethod(aClass
, method
);
79 method
= ReflectionUtil
.getMethod(aClass
, "is" + capitalized
);
80 if (method
== null) return null;
82 final JavaMethod javaMethod
= JavaMethod
.getMethod(aClass
, method
);
83 return canHaveIsPropertyGetterPrefix(javaMethod
.getGenericReturnType()) ? javaMethod
: null;
86 public static Object
invokeMethod(final JavaMethodSignature method
, final Object object
, final Object
... args
) {
87 return invokeMethod(method
.findMethod(object
.getClass()), object
, args
);
90 public static Object
invokeMethod(final Method method
, final Object object
, final Object
... args
) {
92 //if (object instanceof Factory) {
93 // return ((net.sf.cglib.proxy.InvocationHandler)((Factory)object).getCallback(0)).invoke(object, method, args);
95 return method
.invoke(object
, args
);
97 catch (IllegalArgumentException e
) {
98 throw new RuntimeException("Calling method " + method
+ " on object " + object
+ " with arguments " + Arrays
.asList(args
), e
);
100 catch (IllegalAccessException e
) {
101 throw new RuntimeException(e
);
103 catch (InvocationTargetException e
) {
104 final Throwable cause
= e
.getCause();
105 if (cause
instanceof ProcessCanceledException
) {
106 throw (ProcessCanceledException
)cause
;
108 else if (cause
instanceof Error
) {
111 else if (cause
instanceof RuntimeException
) {
112 throw (RuntimeException
) cause
;
114 throw new RuntimeException(e
);
116 catch (ProcessCanceledException e
) {
119 catch (Throwable throwable
) {
120 throw new RuntimeException(throwable
);
125 public static Type
extractCollectionElementType(Type returnType
) {
126 if (returnType
instanceof ParameterizedType
) {
127 ParameterizedType parameterizedType
= (ParameterizedType
)returnType
;
128 final Type rawType
= parameterizedType
.getRawType();
129 if (rawType
instanceof Class
) {
130 final Class
<?
> rawClass
= (Class
<?
>)rawType
;
131 if (List
.class.equals(rawClass
) || Collection
.class.equals(rawClass
)) {
132 final Type
[] arguments
= ReflectionUtil
.getActualTypeArguments(parameterizedType
);
133 if (arguments
.length
== 1) {
134 final Type argument
= arguments
[0];
135 if (argument
instanceof WildcardType
) {
136 final Type
[] upperBounds
= ((WildcardType
)argument
).getUpperBounds();
137 if (upperBounds
.length
== 1) {
138 return upperBounds
[0];
141 else if (argument
instanceof ParameterizedType
) {
142 if (DomUtil
.getGenericValueParameter(argument
) != null) {
146 else if (argument
instanceof Class
) {