| /* |
| * Copyright 2000-2014 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.util.ArrayUtil; |
| import com.intellij.util.CommonProcessors; |
| import com.intellij.util.Processor; |
| import com.intellij.util.ReflectionUtil; |
| import org.jetbrains.annotations.Nullable; |
| |
| import java.lang.annotation.Annotation; |
| import java.lang.reflect.Method; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.List; |
| |
| /** |
| * @author peter |
| */ |
| public class JavaMethodSignature { |
| private final String myMethodName; |
| private final Class[] myMethodParameters; |
| |
| public JavaMethodSignature(final String methodName, final Class... methodParameters) { |
| myMethodName = methodName; |
| myMethodParameters = methodParameters.length == 0 ? ArrayUtil.EMPTY_CLASS_ARRAY : methodParameters; |
| } |
| |
| public JavaMethodSignature(Method method) { |
| this(method.getName(), method.getParameterTypes()); |
| } |
| |
| public String getMethodName() { |
| return myMethodName; |
| } |
| |
| @Nullable |
| public final Method findMethod(final Class aClass) { |
| Method method = getDeclaredMethod(aClass); |
| if (method == null && aClass.isInterface()) { |
| method = getDeclaredMethod(Object.class); |
| } |
| return method; |
| } |
| |
| private boolean processMethods(final Class aClass, Processor<Method> processor) { |
| return processMethodWithSupers(aClass, findMethod(aClass), processor); |
| } |
| |
| @Nullable |
| private Method getDeclaredMethod(final Class aClass) { |
| final Method method = ReflectionUtil.getMethod(aClass, myMethodName, myMethodParameters); |
| return method == null ? ReflectionUtil.getDeclaredMethod(aClass, myMethodName, myMethodParameters) : method; |
| } |
| |
| private boolean processMethodWithSupers(final Class aClass, final Method method, final Processor<Method> processor) { |
| if (method != null) { |
| if (!processor.process(method)) return false; |
| } |
| final Class superClass = aClass.getSuperclass(); |
| if (superClass != null) { |
| if (!processMethods(superClass, processor)) return false; |
| } |
| else { |
| if (aClass.isInterface()) { |
| if (!processMethods(Object.class, processor)) return false; |
| } |
| } |
| for (final Class anInterface : aClass.getInterfaces()) { |
| if (!processMethods(anInterface, processor)) return false; |
| } |
| return true; |
| } |
| |
| public final List<Method> getAllMethods(final Class startFrom) { |
| final List<Method> result = new ArrayList<Method>(); |
| processMethods(startFrom, new CommonProcessors.CollectProcessor<Method>(result)); |
| return result; |
| } |
| |
| @Nullable |
| public final <T extends Annotation> Method findAnnotatedMethod(final Class<T> annotationClass, final Class startFrom) { |
| CommonProcessors.FindFirstProcessor<Method> processor = new CommonProcessors.FindFirstProcessor<Method>() { |
| @Override |
| protected boolean accept(Method method) { |
| final T annotation = method.getAnnotation(annotationClass); |
| return annotation != null && ReflectionUtil.isAssignable(method.getDeclaringClass(), startFrom); |
| } |
| }; |
| processMethods(startFrom, processor); |
| return processor.getFoundValue(); |
| } |
| |
| @Nullable |
| public final <T extends Annotation> T findAnnotation(final Class<T> annotationClass, final Class startFrom) { |
| CommonProcessors.FindFirstProcessor<Method> processor = new CommonProcessors.FindFirstProcessor<Method>() { |
| @Override |
| protected boolean accept(Method method) { |
| final T annotation = method.getAnnotation(annotationClass); |
| return annotation != null; |
| } |
| }; |
| processMethods(startFrom, processor); |
| final Method foundMethod = processor.getFoundValue(); |
| return foundMethod == null ? null : foundMethod.getAnnotation(annotationClass); |
| } |
| |
| public String toString() { |
| return myMethodName + Arrays.asList(myMethodParameters); |
| } |
| |
| @Override |
| public boolean equals(final Object o) { |
| if (this == o) return true; |
| if (o == null || getClass() != o.getClass()) return false; |
| |
| final JavaMethodSignature that = (JavaMethodSignature)o; |
| |
| if (!myMethodName.equals(that.myMethodName)) return false; |
| if (!Arrays.equals(myMethodParameters, that.myMethodParameters)) return false; |
| |
| return true; |
| } |
| |
| @Override |
| public int hashCode() { |
| int result = myMethodName.hashCode(); |
| result = 31 * result + Arrays.hashCode(myMethodParameters); |
| return result; |
| } |
| } |