update copyright
[fedora-idea.git] / xml / dom-openapi / src / com / intellij / util / xml / DomReflectionUtil.java
blobbd2d052da899f9417c446064a33d2f9d21dd0e3b
1 /*
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;
29 /**
30 * @author peter
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) {
43 return annotation;
46 return 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;
64 methods[i] = getter;
65 aClass = getter.getReturnType();
66 if (List.class.isAssignableFrom(aClass)) {
67 aClass = ReflectionUtil.getRawType(extractCollectionElementType(getter.getGenericReturnType()));
70 return methods;
73 @Nullable
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) {
91 try {
92 //if (object instanceof Factory) {
93 // return ((net.sf.cglib.proxy.InvocationHandler)((Factory)object).getCallback(0)).invoke(object, method, args);
94 //}
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) {
109 throw (Error)cause;
111 else if (cause instanceof RuntimeException) {
112 throw (RuntimeException) cause;
114 throw new RuntimeException(e);
116 catch (ProcessCanceledException e) {
117 throw e;
119 catch (Throwable throwable) {
120 throw new RuntimeException(throwable);
124 @Nullable
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) {
143 return argument;
146 else if (argument instanceof Class) {
147 return argument;
153 return null;