blob: 46563b656369400ac31eb169eed847f12272e306 [file] [log] [blame]
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.util.xml;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ReflectionUtil;
import org.jetbrains.annotations.Nullable;
import java.lang.annotation.Annotation;
import java.lang.reflect.*;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
/**
* @author peter
*/
public class DomReflectionUtil {
private DomReflectionUtil() {
}
public static <T extends Annotation> T findAnnotationDFS(final Class<?> rawType, final Class<T> annotationType) {
T annotation = rawType.getAnnotation(annotationType);
if (annotation != null) return annotation;
for (Class aClass : rawType.getInterfaces()) {
annotation = findAnnotationDFS(aClass, annotationType);
if (annotation != null) {
return annotation;
}
}
return null;
}
public static boolean canHaveIsPropertyGetterPrefix(final Type type) {
return boolean.class.equals(type) || Boolean.class.equals(type)
|| Boolean.class.equals(DomUtil.getGenericValueParameter(type));
}
public static JavaMethod[] getGetterMethods(final String[] path, final Class<? extends DomElement> startClass) {
final JavaMethod[] methods = new JavaMethod[path.length];
Class aClass = startClass;
for (int i = 0; i < path.length; i++) {
final JavaMethod getter = findGetter(aClass, path[i]);
assert getter != null : "Couldn't find getter for property " + path[i] + " in class " + aClass;
methods[i] = getter;
aClass = getter.getReturnType();
if (List.class.isAssignableFrom(aClass)) {
aClass = ReflectionUtil.getRawType(extractCollectionElementType(getter.getGenericReturnType()));
}
}
return methods;
}
@Nullable
public static JavaMethod findGetter(Class aClass, String propertyName) {
final String capitalized = StringUtil.capitalize(propertyName);
Method method = ReflectionUtil.getMethod(aClass, "get" + capitalized);
if (method != null) return JavaMethod.getMethod(aClass, method);
method = ReflectionUtil.getMethod(aClass, "is" + capitalized);
if (method == null) return null;
final JavaMethod javaMethod = JavaMethod.getMethod(aClass, method);
return canHaveIsPropertyGetterPrefix(javaMethod.getGenericReturnType()) ? javaMethod : null;
}
public static Object invokeMethod(final Method method, final Object object, final Object... args) {
try {
return method.invoke(object, args);
}
catch (IllegalArgumentException e) {
throw new RuntimeException("Calling method " + method + " on object " + object + " with arguments " + Arrays.asList(args), e);
}
catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
catch (InvocationTargetException e) {
final Throwable cause = e.getCause();
if (cause instanceof ProcessCanceledException) {
throw (ProcessCanceledException)cause;
}
else if (cause instanceof Error) {
throw (Error)cause;
}
else if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
}
throw new RuntimeException(e);
}
catch (ProcessCanceledException e) {
throw e;
}
catch (Throwable throwable) {
throw new RuntimeException(throwable);
}
}
@Nullable
public static Type extractCollectionElementType(Type returnType) {
if (returnType instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType)returnType;
final Type rawType = parameterizedType.getRawType();
if (rawType instanceof Class) {
final Class<?> rawClass = (Class<?>)rawType;
if (List.class.equals(rawClass) || Collection.class.equals(rawClass)) {
final Type[] arguments = ReflectionUtil.getActualTypeArguments(parameterizedType);
if (arguments.length == 1) {
final Type argument = arguments[0];
if (argument instanceof WildcardType) {
final Type[] upperBounds = ((WildcardType)argument).getUpperBounds();
if (upperBounds.length == 1) {
return upperBounds[0];
}
}
else if (argument instanceof ParameterizedType) {
if (DomUtil.getGenericValueParameter(argument) != null) {
return argument;
}
}
else if (argument instanceof Class) {
return argument;
}
}
}
}
}
return null;
}
}