| // *************************************************************************************************************************** |
| // * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * |
| // * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * |
| // * to you 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 org.apache.juneau.reflect; |
| |
| import static org.apache.juneau.common.internal.StringUtils.*; |
| import static org.apache.juneau.internal.CollectionUtils.*; |
| import static org.apache.juneau.internal.ConsumerUtils.*; |
| |
| import java.lang.annotation.*; |
| import java.lang.reflect.*; |
| import java.util.*; |
| import java.util.function.*; |
| |
| import org.apache.juneau.*; |
| import org.apache.juneau.internal.*; |
| |
| /** |
| * Contains common methods between {@link ConstructorInfo} and {@link MethodInfo}. |
| * |
| * <h5 class='section'>See Also:</h5><ul> |
| * </ul> |
| */ |
| @FluentSetters |
| public abstract class ExecutableInfo { |
| |
| final ClassInfo declaringClass; |
| final Executable e; |
| final boolean isConstructor; |
| |
| private volatile ParamInfo[] params; |
| private volatile ClassInfo[] paramTypes, exceptionInfos; |
| private volatile Class<?>[] rawParamTypes; |
| private volatile Type[] rawGenericParamTypes; |
| private volatile Parameter[] rawParameters; |
| private volatile Annotation[][] parameterAnnotations; |
| private volatile Annotation[] declaredAnnotations; |
| |
| /** |
| * Constructor. |
| * |
| * @param declaringClass The class that declares this method or constructor. |
| * @param e The constructor or method that this info represents. |
| */ |
| protected ExecutableInfo(ClassInfo declaringClass, Executable e) { |
| this.declaringClass = declaringClass; |
| this.e = e; |
| this.isConstructor = e instanceof Constructor; |
| } |
| |
| /** |
| * Returns metadata about the class that declared this method or constructor. |
| * |
| * @return Metadata about the class that declared this method or constructor. |
| */ |
| public final ClassInfo getDeclaringClass() { |
| return declaringClass; |
| } |
| |
| /** |
| * Returns <jk>true</jk> if this executable represents a {@link Constructor}. |
| * |
| * @return |
| * <jk>true</jk> if this executable represents a {@link Constructor} and can be cast to {@link ConstructorInfo}. |
| * <jk>false</jk> if this executable represents a {@link Method} and can be cast to {@link MethodInfo}. |
| */ |
| public final boolean isConstructor() { |
| return isConstructor; |
| } |
| |
| //----------------------------------------------------------------------------------------------------------------- |
| // Parameters |
| //----------------------------------------------------------------------------------------------------------------- |
| |
| /** |
| * Returns the number of parameters in this executable. |
| * |
| * <p> |
| * Same as calling {@link Executable#getParameterCount()}. |
| * |
| * @return The number of parameters in this executable. |
| */ |
| public final int getParamCount() { |
| return e.getParameterCount(); |
| } |
| |
| /** |
| * Returns <jk>true</jk> if this executable has at least one parameter. |
| * |
| * <p> |
| * Same as calling {@link Executable#getParameterCount()} and comparing with zero. |
| * |
| * @return <jk>true</jk> if this executable has at least one parameter. |
| */ |
| public final boolean hasParams() { |
| return getParamCount() != 0; |
| } |
| |
| /** |
| * Returns <jk>true</jk> if this executable has no parameters. |
| * |
| * <p> |
| * Same as calling {@link Executable#getParameterCount()} and comparing with zero. |
| * |
| * @return <jk>true</jk> if this executable has no parameters. |
| */ |
| public final boolean hasNoParams() { |
| return getParamCount() == 0; |
| } |
| |
| /** |
| * Returns <jk>true</jk> if this executable has this number of arguments. |
| * |
| * <p> |
| * Same as calling {@link Executable#getParameterCount()} and comparing the count. |
| * |
| * @param number The number of expected arguments. |
| * @return <jk>true</jk> if this executable has this number of arguments. |
| */ |
| public final boolean hasNumParams(int number) { |
| return getParamCount() == number; |
| } |
| |
| /** |
| * Returns the parameters defined on this executable. |
| * |
| * <p> |
| * Same as calling {@link Executable#getParameters()} but wraps the results |
| * |
| * @return An array of parameter information, never <jk>null</jk>. |
| */ |
| public final List<ParamInfo> getParams() { |
| return ulist(_getParams()); |
| } |
| |
| /** |
| * Performs an action on every parameter that matches the specified filter. |
| * |
| * @param filter The filter, can be <jk>null</jk>. |
| * @param action The action to perform. |
| * @return This object. |
| */ |
| public ExecutableInfo forEachParam(Predicate<ParamInfo> filter, Consumer<ParamInfo> action) { |
| for (ParamInfo pi : _getParams()) |
| if (test(filter, pi)) |
| action.accept(pi); |
| return this; |
| } |
| |
| /** |
| * Returns parameter information at the specified index. |
| * |
| * @param index The parameter index. |
| * @return The parameter information, never <jk>null</jk>. |
| */ |
| public final ParamInfo getParam(int index) { |
| checkIndex(index); |
| return _getParams()[index]; |
| } |
| |
| /** |
| * Returns the parameter types on this executable. |
| * |
| * @return The parameter types on this executable. |
| */ |
| public final List<ClassInfo> getParamTypes() { |
| return ulist(_getParameterTypes()); |
| } |
| |
| /** |
| * Returns the parameter type of the parameter at the specified index. |
| * |
| * @param index The parameter index. |
| * @return The parameter type of the parameter at the specified index. |
| */ |
| public final ClassInfo getParamType(int index) { |
| checkIndex(index); |
| return _getParameterTypes()[index]; |
| } |
| |
| /** |
| * Returns the raw parameter types on this executable. |
| * |
| * @return The raw parameter types on this executable. |
| */ |
| public final List<Class<?>> getRawParamTypes() { |
| return ulist(_getRawParamTypes()); |
| } |
| |
| /** |
| * Returns the raw parameter type of the parameter at the specified index. |
| * |
| * @param index The parameter index. |
| * @return The raw parameter type of the parameter at the specified index. |
| */ |
| public final Class<?> getRawParamType(int index) { |
| checkIndex(index); |
| return _getRawParamTypes()[index]; |
| } |
| |
| /** |
| * Returns the raw generic parameter types on this executable. |
| * |
| * @return The raw generic parameter types on this executable. |
| */ |
| public final List<Type> getRawGenericParamTypes() { |
| return ulist(_getRawGenericParamTypes()); |
| } |
| |
| /** |
| * Returns the raw generic parameter type of the parameter at the specified index. |
| * |
| * @param index The parameter index. |
| * @return The raw generic parameter type of the parameter at the specified index. |
| */ |
| public final Type getRawGenericParamType(int index) { |
| checkIndex(index); |
| return _getRawGenericParamTypes()[index]; |
| } |
| |
| /** |
| * Returns an array of raw {@link Parameter} objects that represent all the parameters to the underlying executable represented by this object. |
| * |
| * @return An array of raw {@link Parameter} objects, or an empty array if executable has no parameters. |
| * @see Executable#getParameters() |
| */ |
| public final List<Parameter> getRawParameters() { |
| return ulist(_getRawParameters()); |
| } |
| |
| /** |
| * Returns the raw {@link Parameter} object that represents the parameter at the specified index. |
| * |
| * @param index The parameter index. |
| * @return The raw {@link Parameter} object that represents the parameter at the specified index. |
| * @see Executable#getParameters() |
| */ |
| public final Parameter getRawParameter(int index) { |
| checkIndex(index); |
| return _getRawParameters()[index]; |
| } |
| |
| final ParamInfo[] _getParams() { |
| if (params == null) { |
| synchronized(this) { |
| Parameter[] rp = _getRawParameters(); |
| ParamInfo[] l = new ParamInfo[rp.length]; |
| for (int i = 0; i < rp.length; i++) |
| l[i] = new ParamInfo(this, rp[i], i); |
| params = l; |
| } |
| } |
| return params; |
| } |
| |
| final ClassInfo[] _getParameterTypes() { |
| if (paramTypes == null) { |
| synchronized(this) { |
| Class<?>[] ptc = _getRawParamTypes(); |
| // Note that due to a bug involving Enum constructors, getGenericParameterTypes() may |
| // always return an empty array. This appears to be fixed in Java 8 b75. |
| Type[] ptt = _getRawGenericParamTypes(); |
| if (ptt.length != ptc.length) { |
| // Bug in javac: generic type array excludes enclosing instance parameter |
| // for inner classes with at least one generic constructor parameter. |
| if (ptt.length + 1 == ptc.length) { |
| Type[] ptt2 = new Type[ptc.length]; |
| ptt2[0] = ptc[0]; |
| for (int i = 0; i < ptt.length; i++) |
| ptt2[i+1] = ptt[i]; |
| ptt = ptt2; |
| } else { |
| ptt = ptc; |
| } |
| } |
| ClassInfo[] l = new ClassInfo[ptc.length]; |
| for (int i = 0; i < ptc.length; i++) |
| l[i] = ClassInfo.of(ptc[i], ptt[i]); |
| paramTypes = l; |
| } |
| } |
| return paramTypes; |
| } |
| |
| Class<?>[] _getRawParamTypes() { |
| if (rawParamTypes == null) { |
| synchronized(this) { |
| rawParamTypes = e.getParameterTypes(); |
| } |
| } |
| return rawParamTypes; |
| } |
| |
| final Type[] _getRawGenericParamTypes() { |
| if (rawGenericParamTypes == null) { |
| synchronized(this) { |
| rawGenericParamTypes = e.getGenericParameterTypes(); |
| } |
| } |
| return rawGenericParamTypes; |
| } |
| |
| final Parameter[] _getRawParameters() { |
| if (rawParameters == null) { |
| synchronized(this) { |
| rawParameters = e.getParameters(); |
| } |
| } |
| return rawParameters; |
| } |
| |
| private void checkIndex(int index) { |
| int pc = getParamCount(); |
| if (pc == 0) |
| throw new IndexOutOfBoundsException(format("Invalid index ''{0}''. No parameters.", index)); |
| if (index < 0 || index >= pc) |
| throw new IndexOutOfBoundsException(format("Invalid index ''{0}''. Parameter count: {1}", index, pc)); |
| } |
| |
| //----------------------------------------------------------------------------------------------------------------- |
| // Annotations |
| //----------------------------------------------------------------------------------------------------------------- |
| |
| /** |
| * Performs an action on all matching parameter annotations at the specified parameter index. |
| * |
| * @param <A> The annotation type. |
| * @param index The parameter index. |
| * @param type The annotation type. |
| * @param predicate The predicate. |
| * @param consumer The consumer. |
| * @return This object. |
| */ |
| public final <A extends Annotation> ExecutableInfo forEachParameterAnnotation(int index, Class<A> type, Predicate<A> predicate, Consumer<A> consumer) { |
| for (Annotation a : _getParameterAnnotations(index)) |
| if (type.isInstance(a)) |
| consume(predicate, consumer, type.cast(a)); |
| return this; |
| } |
| |
| final Annotation[][] _getParameterAnnotations() { |
| if (parameterAnnotations == null) { |
| synchronized(this) { |
| parameterAnnotations = e.getParameterAnnotations(); |
| } |
| } |
| return parameterAnnotations; |
| } |
| |
| final Annotation[] _getParameterAnnotations(int index) { |
| checkIndex(index); |
| Annotation[][] x = _getParameterAnnotations(); |
| int c = e.getParameterCount(); |
| if (c != x.length) { |
| // Seems to be a JVM bug where getParameterAnnotations() don't take mandated parameters into account. |
| Annotation[][] x2 = new Annotation[c][]; |
| int diff = c - x.length; |
| for (int i = 0; i < diff; i++) |
| x2[i] = new Annotation[0]; |
| for (int i = diff; i < c; i++) |
| x2[i] = x[i-diff]; |
| x = x2; |
| } |
| return x[index]; |
| } |
| |
| final Annotation[] _getDeclaredAnnotations() { |
| if (declaredAnnotations == null) { |
| synchronized(this) { |
| declaredAnnotations = e.getDeclaredAnnotations(); |
| } |
| } |
| return declaredAnnotations; |
| } |
| |
| //----------------------------------------------------------------------------------------------------------------- |
| // Exceptions |
| //----------------------------------------------------------------------------------------------------------------- |
| |
| /** |
| * Returns the exception types on this executable. |
| * |
| * @return The exception types on this executable. |
| */ |
| public final List<ClassInfo> getExceptionTypes() { |
| return ulist(_getExceptionTypes()); |
| } |
| |
| final ClassInfo[] _getExceptionTypes() { |
| if (exceptionInfos == null) { |
| synchronized(this) { |
| Class<?>[] exceptionTypes = e.getExceptionTypes(); |
| ClassInfo[] l = new ClassInfo[exceptionTypes.length]; |
| for (int i = 0; i < exceptionTypes.length; i++) |
| l[i] = ClassInfo.of(exceptionTypes[i]); |
| exceptionInfos = l; |
| } |
| } |
| return exceptionInfos; |
| } |
| |
| //----------------------------------------------------------------------------------------------------------------- |
| // Characteristics |
| //----------------------------------------------------------------------------------------------------------------- |
| |
| /** |
| * Returns <jk>true</jk> if all specified flags are applicable to this method. |
| * |
| * @param flags The flags to test for. |
| * @return <jk>true</jk> if all specified flags are applicable to this method. |
| */ |
| public final boolean isAll(ReflectFlags...flags) { |
| for (ReflectFlags f : flags) { |
| switch (f) { |
| case DEPRECATED: |
| if (isNotDeprecated()) |
| return false; |
| break; |
| case NOT_DEPRECATED: |
| if (isDeprecated()) |
| return false; |
| break; |
| case HAS_PARAMS: |
| if (hasNoParams()) |
| return false; |
| break; |
| case HAS_NO_PARAMS: |
| if (hasParams()) |
| return false; |
| break; |
| case PUBLIC: |
| if (isNotPublic()) |
| return false; |
| break; |
| case NOT_PUBLIC: |
| if (isPublic()) |
| return false; |
| break; |
| case PROTECTED: |
| if (isNotProtected()) |
| return false; |
| break; |
| case NOT_PROTECTED: |
| if (isProtected()) |
| return false; |
| break; |
| case STATIC: |
| if (isNotStatic()) |
| return false; |
| break; |
| case NOT_STATIC: |
| if (isStatic()) |
| return false; |
| break; |
| case ABSTRACT: |
| if (isNotAbstract()) |
| return false; |
| break; |
| case NOT_ABSTRACT: |
| if (isAbstract()) |
| return false; |
| break; |
| default: |
| throw new BasicRuntimeException("Invalid flag for executable: {0}", f); |
| } |
| } |
| return true; |
| } |
| |
| /** |
| * Returns <jk>true</jk> if all specified flags are applicable to this field. |
| * |
| * @param flags The flags to test for. |
| * @return <jk>true</jk> if all specified flags are applicable to this field. |
| */ |
| public final boolean is(ReflectFlags...flags) { |
| return isAll(flags); |
| } |
| |
| /** |
| * Returns <jk>true</jk> if all specified flags are applicable to this method. |
| * |
| * @param flags The flags to test for. |
| * @return <jk>true</jk> if all specified flags are applicable to this method. |
| */ |
| public final boolean isAny(ReflectFlags...flags) { |
| for (ReflectFlags f : flags) { |
| switch (f) { |
| case DEPRECATED: |
| if (isDeprecated()) |
| return true; |
| break; |
| case NOT_DEPRECATED: |
| if (isNotDeprecated()) |
| return true; |
| break; |
| case HAS_PARAMS: |
| if (hasParams()) |
| return true; |
| break; |
| case HAS_NO_PARAMS: |
| if (hasNoParams()) |
| return true; |
| break; |
| case PUBLIC: |
| if (isPublic()) |
| return true; |
| break; |
| case NOT_PUBLIC: |
| if (isNotPublic()) |
| return true; |
| break; |
| case PROTECTED: |
| if (isProtected()) |
| return true; |
| break; |
| case NOT_PROTECTED: |
| if (isNotProtected()) |
| return true; |
| break; |
| case STATIC: |
| if (isStatic()) |
| return true; |
| break; |
| case NOT_STATIC: |
| if (isNotStatic()) |
| return true; |
| break; |
| case ABSTRACT: |
| if (isAbstract()) |
| return true; |
| break; |
| case NOT_ABSTRACT: |
| if (isNotAbstract()) |
| return true; |
| break; |
| default: |
| throw new BasicRuntimeException("Invalid flag for executable: {0}", f); |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Returns <jk>true</jk> if this method has the specified arguments. |
| * |
| * @param args The arguments to test for. |
| * @return <jk>true</jk> if this method has this arguments in the exact order. |
| */ |
| public final boolean hasParamTypes(Class<?>...args) { |
| Class<?>[] pt = _getRawParamTypes(); |
| if (pt.length == args.length) { |
| for (int i = 0; i < pt.length; i++) |
| if (! pt[i].equals(args[i])) |
| return false; |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * Returns <jk>true</jk> if this method has the specified arguments. |
| * |
| * @param args The arguments to test for. |
| * @return <jk>true</jk> if this method has this arguments in the exact order. |
| */ |
| public final boolean hasParamTypes(ClassInfo...args) { |
| Class<?>[] pt = _getRawParamTypes(); |
| if (pt.length == args.length) { |
| for (int i = 0; i < pt.length; i++) |
| if (! pt[i].equals(args[i].inner())) |
| return false; |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * Returns <jk>true</jk> if this method has the specified argument parent classes. |
| * |
| * @param args The arguments to test for. |
| * @return <jk>true</jk> if this method has this arguments in the exact order. |
| */ |
| public final boolean hasMatchingParamTypes(Class<?>...args) { |
| ClassInfo[] pt = _getParameterTypes(); |
| if (pt.length != args.length) |
| return false; |
| for (ClassInfo element : pt) { |
| boolean matched = false; |
| for (Class<?> arg : args) |
| if (element.isParentOfFuzzyPrimitives(arg)) |
| matched = true; |
| if (! matched) |
| return false; |
| } |
| return true; |
| } |
| |
| /** |
| * Returns <jk>true</jk> if this method has the specified argument parent classes. |
| * |
| * @param args The arguments to test for. |
| * @return <jk>true</jk> if this method has this arguments in the exact order. |
| */ |
| public final boolean hasMatchingParamTypes(ClassInfo...args) { |
| ClassInfo[] pt = _getParameterTypes(); |
| if (pt.length != args.length) |
| return false; |
| for (ClassInfo element : pt) { |
| boolean matched = false; |
| for (ClassInfo arg : args) |
| if (element.isParentOfFuzzyPrimitives(arg.inner())) |
| matched = true; |
| if (! matched) |
| return false; |
| } |
| return true; |
| } |
| |
| /** |
| * Returns <jk>true</jk> if this method has at most only this arguments in any order. |
| * |
| * @param args The arguments to test for. |
| * @return <jk>true</jk> if this method has at most only this arguments in any order. |
| */ |
| public final boolean hasFuzzyParamTypes(Class<?>...args) { |
| return fuzzyArgsMatch(args) != -1; |
| } |
| |
| /** |
| * Returns how well this method matches the specified arg types. |
| * |
| * <p> |
| * The number returned is the number of method arguments that match the passed in arg types. |
| * <br>Returns <c>-1</c> if the method cannot take in one or more of the specified arguments. |
| * |
| * @param argTypes The arg types to check against. |
| * @return How many parameters match or <c>-1</c> if method cannot handle one or more of the arguments. |
| */ |
| public final int fuzzyArgsMatch(Class<?>... argTypes) { |
| int matches = 0; |
| outer: for (ClassInfo pi : getParamTypes()) { |
| for (Class<?> a : argTypes) { |
| if (pi.isParentOfFuzzyPrimitives(a)) { |
| matches++; |
| continue outer; |
| } |
| } |
| return -1; |
| } |
| return matches; |
| } |
| |
| /** |
| * Returns how well this method matches the specified arg types. |
| * |
| * <p> |
| * The number returned is the number of method arguments that match the passed in arg types. |
| * <br>Returns <c>-1</c> if the method cannot take in one or more of the specified arguments. |
| * |
| * @param argTypes The arg types to check against. |
| * @return How many parameters match or <c>-1</c> if method cannot handle one or more of the arguments. |
| */ |
| public final int fuzzyArgsMatch(Object... argTypes) { |
| int matches = 0; |
| outer: for (ClassInfo pi : getParamTypes()) { |
| for (Object a : argTypes) { |
| if (pi.canAcceptArg(a)) { |
| matches++; |
| continue outer; |
| } |
| } |
| return -1; |
| } |
| return matches; |
| } |
| |
| /** |
| * Returns <jk>true</jk> if this method has at most only this arguments in any order. |
| * |
| * @param args The arguments to test for. |
| * @return <jk>true</jk> if this method has at most only this arguments in any order. |
| */ |
| public final boolean hasFuzzyParamTypes(ClassInfo...args) { |
| return fuzzyArgsMatch(args) != -1; |
| } |
| |
| /** |
| * Returns how well this method matches the specified arg types. |
| * |
| * <p> |
| * The number returned is the number of method arguments that match the passed in arg types. |
| * <br>Returns <c>-1</c> if the method cannot take in one or more of the specified arguments. |
| * |
| * @param argTypes The arg types to check against. |
| * @return How many parameters match or <c>-1</c> if method cannot handle one or more of the arguments. |
| */ |
| public final int fuzzyArgsMatch(ClassInfo... argTypes) { |
| int matches = 0; |
| outer: for (ClassInfo pi : getParamTypes()) { |
| for (ClassInfo a : argTypes) { |
| if (pi.isParentOfFuzzyPrimitives(a)) { |
| matches++; |
| continue outer; |
| } |
| } |
| return -1; |
| } |
| return matches; |
| } |
| |
| /** |
| * Returns <jk>true</jk> if this method has the {@link Deprecated @Deprecated} annotation on it. |
| * |
| * @return <jk>true</jk> if this method has the {@link Deprecated @Deprecated} annotation on it. |
| */ |
| public final boolean isDeprecated() { |
| return e.isAnnotationPresent(Deprecated.class); |
| |
| } |
| |
| /** |
| * Returns <jk>true</jk> if this method doesn't have the {@link Deprecated @Deprecated} annotation on it. |
| * |
| * @return <jk>true</jk> if this method doesn't have the {@link Deprecated @Deprecated} annotation on it. |
| */ |
| public final boolean isNotDeprecated() { |
| return ! e.isAnnotationPresent(Deprecated.class); |
| |
| } |
| |
| /** |
| * Returns <jk>true</jk> if this method is abstract. |
| * |
| * @return <jk>true</jk> if this method is abstract. |
| */ |
| public final boolean isAbstract() { |
| return Modifier.isAbstract(e.getModifiers()); |
| } |
| |
| /** |
| * Returns <jk>true</jk> if this method is not abstract. |
| * |
| * @return <jk>true</jk> if this method is not abstract. |
| */ |
| public final boolean isNotAbstract() { |
| return ! Modifier.isAbstract(e.getModifiers()); |
| } |
| |
| /** |
| * Returns <jk>true</jk> if this method is public. |
| * |
| * @return <jk>true</jk> if this method is public. |
| */ |
| public final boolean isPublic() { |
| return Modifier.isPublic(e.getModifiers()); |
| } |
| |
| /** |
| * Returns <jk>true</jk> if this method is not public. |
| * |
| * @return <jk>true</jk> if this method is not public. |
| */ |
| public final boolean isNotPublic() { |
| return ! Modifier.isPublic(e.getModifiers()); |
| } |
| |
| /** |
| * Returns <jk>true</jk> if this method is protected. |
| * |
| * @return <jk>true</jk> if this method is protected. |
| */ |
| public final boolean isProtected() { |
| return Modifier.isProtected(e.getModifiers()); |
| } |
| |
| /** |
| * Returns <jk>true</jk> if this method is not protected. |
| * |
| * @return <jk>true</jk> if this method is not protected. |
| */ |
| public final boolean isNotProtected() { |
| return ! Modifier.isProtected(e.getModifiers()); |
| } |
| |
| /** |
| * Returns <jk>true</jk> if this method is static. |
| * |
| * @return <jk>true</jk> if this method is static. |
| */ |
| public final boolean isStatic() { |
| return Modifier.isStatic(e.getModifiers()); |
| } |
| |
| /** |
| * Returns <jk>true</jk> if this method is not static. |
| * |
| * @return <jk>true</jk> if this method is not static. |
| */ |
| public final boolean isNotStatic() { |
| return ! Modifier.isStatic(e.getModifiers()); |
| } |
| |
| //----------------------------------------------------------------------------------------------------------------- |
| // Visibility |
| //----------------------------------------------------------------------------------------------------------------- |
| |
| /** |
| * Attempts to call <code>x.setAccessible(<jk>true</jk>)</code> and quietly ignores security exceptions. |
| * |
| * @return This object. |
| */ |
| @FluentSetter |
| public ExecutableInfo accessible() { |
| setAccessible(); |
| return this; |
| } |
| |
| /** |
| * Attempts to call <code>x.setAccessible(<jk>true</jk>)</code> and quietly ignores security exceptions. |
| * |
| * @return <jk>true</jk> if call was successful. |
| */ |
| public final boolean setAccessible() { |
| try { |
| if (e != null) |
| e.setAccessible(true); |
| return true; |
| } catch (SecurityException e) { |
| return false; |
| } |
| } |
| |
| /** |
| * Identifies if the specified visibility matches this method. |
| * |
| * @param v The visibility to validate against. |
| * @return <jk>true</jk> if this visibility matches the modifier attribute of this method. |
| */ |
| public final boolean isVisible(Visibility v) { |
| return v.isVisible(e); |
| } |
| |
| //----------------------------------------------------------------------------------------------------------------- |
| // Labels |
| //----------------------------------------------------------------------------------------------------------------- |
| |
| /** |
| * Returns <jk>true</jk> if this method has this name. |
| * |
| * @param name The name to test for. |
| * @return <jk>true</jk> if this method has this name. |
| */ |
| public final boolean hasName(String name) { |
| return getSimpleName().equals(name); |
| } |
| |
| /** |
| * Returns <jk>true</jk> if this method has a name in the specified list. |
| * |
| * @param names The names to test for. |
| * @return <jk>true</jk> if this method has one of the names. |
| */ |
| public final boolean hasName(String...names) { |
| for (String n : names) |
| if (getSimpleName().equals(n)) |
| return true; |
| return false; |
| } |
| |
| /** |
| * Returns <jk>true</jk> if this method has a name in the specified set. |
| * |
| * @param names The names to test for. |
| * @return <jk>true</jk> if this method has one of the names. |
| */ |
| public final boolean hasName(Set<String> names) { |
| return names.contains(getSimpleName()); |
| } |
| |
| //----------------------------------------------------------------------------------------------------------------- |
| // Labels |
| //----------------------------------------------------------------------------------------------------------------- |
| |
| /** |
| * Returns the full name of this executable. |
| * |
| * <h5 class='section'>Examples:</h5> |
| * <ul> |
| * <li><js>"com.foo.MyClass.get(java.util.String)"</js> - Method. |
| * <li><js>"com.foo.MyClass(java.util.String)"</js> - Constructor. |
| * </ul> |
| * |
| * @return The underlying executable name. |
| */ |
| public final String getFullName() { |
| StringBuilder sb = new StringBuilder(128); |
| ClassInfo dc = declaringClass; |
| Package p = dc.getPackage(); |
| if (p != null) |
| sb.append(p.getName()).append('.'); |
| dc.appendShortName(sb); |
| if (! isConstructor) |
| sb.append('.').append(getSimpleName()); |
| sb.append('('); |
| List<ClassInfo> pt = getParamTypes(); |
| for (int i = 0; i < pt.size(); i++) { |
| if (i > 0) |
| sb.append(','); |
| pt.get(i).appendFullName(sb); |
| } |
| sb.append(')'); |
| return sb.toString(); |
| } |
| |
| /** |
| * Returns the short name of this executable. |
| * |
| * <h5 class='section'>Examples:</h5> |
| * <ul> |
| * <li><js>"MyClass.get(String)"</js> - Method. |
| * <li><js>"MyClass(String)"</js> - Constructor. |
| * </ul> |
| * |
| * @return The underlying executable name. |
| */ |
| public final String getShortName() { |
| StringBuilder sb = new StringBuilder(64); |
| sb.append(getSimpleName()).append('('); |
| Class<?>[] pt = _getRawParamTypes(); |
| for (int i = 0; i < pt.length; i++) { |
| if (i > 0) |
| sb.append(','); |
| sb.append(pt[i].getSimpleName()); |
| } |
| sb.append(')'); |
| return sb.toString(); |
| } |
| |
| /** |
| * Returns the simple name of the underlying method. |
| * |
| * @return The simple name of the underlying method; |
| */ |
| public final String getSimpleName() { |
| return isConstructor ? e.getDeclaringClass().getSimpleName() : e.getName(); |
| } |
| |
| @Override |
| public String toString() { |
| return getShortName(); |
| } |
| |
| // <FluentSetters> |
| |
| // </FluentSetters> |
| } |