/** * Matches any Java bean getter method which returns the given type. * * @param type The required getter type. * @param <T> The type of the matched object. * @return A matcher that matches a getter method with the given type. */ public static <T extends MethodDescription> ElementMatcher.Junction<T> isGetter(Class<?> type) { return isGetter(TypeDescription.ForLoadedType.of(type)); }
/** * Matches any Java bean getter method which returns the given type. * * @param type The required getter type. * @param <T> The type of the matched object. * @return A matcher that matches a getter method with the given type. */ public static <T extends MethodDescription> ElementMatcher.Junction<T> isGetter(TypeDescription type) { return isGetter(is(type)); }
/** * Matches any Java bean getter method which returns an value with a type matches the supplied matcher. * * @param matcher A matcher to be allied to a getter method's argument type. * @param <T> The type of the matched object. * @return A matcher that matches a getter method with a return type that matches the supplied matcher. */ public static <T extends MethodDescription> ElementMatcher.Junction<T> isGenericGetter(ElementMatcher<? super TypeDescription.Generic> matcher) { return isGetter().and(returnsGeneric(matcher)); }
/** * An element matcher that matches any getter for the given property. When given an empty string, any getter named {@code get} * is matched despite that such a getter is not fulfilling the Java bean naming conventions. If a getter's type is {@code boolean} * or {@link Boolean}, {@code is} is also accepted as a prefix. * * @param property The property to match a getter for. * @param <T> The type of the matched object. * @return A matcher that matches any getter method for the supplied property. */ public static <T extends MethodDescription> ElementMatcher.Junction<T> isGetter(String property) { return isGetter().and(property.length() == 0 ? named("get").or(named("is")) : named("get" + Character.toUpperCase(property.charAt(0)) + property.substring(1)).or(named("is" + Character.toUpperCase(property.charAt(0)) + property.substring(1)))); }
/** * Resolves a field locator for a potential accessor method. * * @param fieldLocator The field locator to use. * @param methodDescription The method description that is the potential accessor. * @return A resolution for a field locator. */ private static FieldLocator.Resolution resolveAccessor(FieldLocator fieldLocator, MethodDescription methodDescription) { String fieldName; if (isSetter().matches(methodDescription)) { fieldName = methodDescription.getInternalName().substring(3); } else if (isGetter().matches(methodDescription)) { fieldName = methodDescription.getInternalName().substring(methodDescription.getInternalName().startsWith("is") ? 2 : 3); } else { return FieldLocator.Resolution.Illegal.INSTANCE; } return fieldLocator.locate(Character.toLowerCase(fieldName.charAt(0)) + fieldName.substring(1)); }
/** * Creates a binder by installing a single proxy type where annotating a parameter with {@link FieldProxy} allows * getting and setting values for a given field. * * @param typeDescription A type which declares exactly one abstract getter and an abstract setter for the {@link Object} * type. The type is allowed to be generic. * @return A binder for the {@link FieldProxy} annotation. */ public static TargetMethodAnnotationDrivenBinder.ParameterBinder<FieldProxy> install(TypeDescription typeDescription) { if (!typeDescription.isInterface()) { throw new IllegalArgumentException(typeDescription + " is not an interface"); } else if (!typeDescription.getInterfaces().isEmpty()) { throw new IllegalArgumentException(typeDescription + " must not extend other interfaces"); } else if (!typeDescription.isPublic()) { throw new IllegalArgumentException(typeDescription + " is not public"); } MethodList<MethodDescription.InDefinedShape> methodCandidates = typeDescription.getDeclaredMethods().filter(isAbstract()); if (methodCandidates.size() != 2) { throw new IllegalArgumentException(typeDescription + " does not declare exactly two non-abstract methods"); } MethodList<MethodDescription.InDefinedShape> getterCandidates = methodCandidates.filter(isGetter(Object.class)); if (getterCandidates.size() != 1) { throw new IllegalArgumentException(typeDescription + " does not declare a getter with an Object type"); } MethodList<MethodDescription.InDefinedShape> setterCandidates = methodCandidates.filter(isSetter(Object.class)); if (setterCandidates.size() != 1) { throw new IllegalArgumentException(typeDescription + " does not declare a setter with an Object type"); } return new Binder(typeDescription, getterCandidates.getOnly(), setterCandidates.getOnly()); }
.and(ElementMatchers.isGetter().or(ElementMatchers.isSetter()) .or(ElementMatchers.named("isPhantom")) .or(ElementMatchers.named("delete")))) .and(ElementMatchers.not(ElementMatchers.isDeclaredBy(ConcurrentMap.class))) .and(ElementMatchers.not(ElementMatchers.isDeclaredBy(Map.class))) .and(ElementMatchers.isGetter() .or(ElementMatchers.isSetter())) .and(ElementMatchers.isPublic()
.and(ElementMatchers.isGetter().or(ElementMatchers.isSetter()) .or(ElementMatchers.named("isPhantom")) .or(ElementMatchers.named("delete")))) .and(ElementMatchers.not(ElementMatchers.isDeclaredBy(ConcurrentMap.class))) .and(ElementMatchers.not(ElementMatchers.isDeclaredBy(Map.class))) .and(ElementMatchers.isGetter() .or(ElementMatchers.isSetter())) .and(ElementMatchers.isPublic()
.and(ElementMatchers.isGetter().or(ElementMatchers.isSetter()) .or(ElementMatchers.named("isPhantom")) .or(ElementMatchers.named("delete")))) .and(ElementMatchers.not(ElementMatchers.isDeclaredBy(ConcurrentMap.class))) .and(ElementMatchers.not(ElementMatchers.isDeclaredBy(Map.class))) .and(ElementMatchers.isGetter() .or(ElementMatchers.isSetter())) .and(ElementMatchers.isPublic()