/** * Matches any Java bean setter method which takes an argument the given type. * * @param type The required setter type. * @param <T> The type of the matched object. * @return A matcher that matches a setter method with the specified argument type. */ public static <T extends MethodDescription> ElementMatcher.Junction<T> isSetter(TypeDescription type) { return isSetter(is(type)); }
/** * Matches any Java bean setter method which takes an argument the given type. * * @param type The required setter type. * @param <T> The type of the matched object. * @return A matcher that matches any setter method. */ public static <T extends MethodDescription> ElementMatcher.Junction<T> isSetter(Class<?> type) { return isSetter(TypeDescription.ForLoadedType.of(type)); }
/** * An element matcher that matches any setter for the given property. When given an empty string, any setter named {@code set} * is matched despite that such a setter is not fulfilling the Java bean naming conventions. * * @param property The property to match a setter for. * @param <T> The type of the matched object. * @return A matcher that matches any setter method for the supplied property. */ public static <T extends MethodDescription> ElementMatcher.Junction<T> isSetter(String property) { return isSetter().and(property.length() == 0 ? named("set") : named("set" + Character.toUpperCase(property.charAt(0)) + property.substring(1))); }
/** * Matches any Java bean setter method which takes an argument that matches the supplied matcher. * * @param matcher A matcher to be allied to a setter method's argument type. * @param <T> The type of the matched object. * @return A matcher that matches a setter method with an argument type that matches the supplied matcher. */ public static <T extends MethodDescription> ElementMatcher.Junction<T> isGenericSetter(ElementMatcher<? super TypeDescription.Generic> matcher) { return isSetter().and(takesGenericArguments(new CollectionOneToOneMatcher<TypeDescription.Generic>(Collections.singletonList(matcher)))); }
/** * 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(Map.class))) .and(ElementMatchers.isGetter() .or(ElementMatchers.isSetter())) .and(ElementMatchers.isPublic() .or(ElementMatchers.isProtected()))
.and(ElementMatchers.isGetter().or(ElementMatchers.isSetter()) .or(ElementMatchers.named("isPhantom")) .or(ElementMatchers.named("delete")))) .and(ElementMatchers.not(ElementMatchers.isDeclaredBy(Map.class))) .and(ElementMatchers.isGetter() .or(ElementMatchers.isSetter())) .and(ElementMatchers.isPublic() .or(ElementMatchers.isProtected()))
.and(ElementMatchers.isGetter().or(ElementMatchers.isSetter()) .or(ElementMatchers.named("isPhantom")) .or(ElementMatchers.named("delete")))) .and(ElementMatchers.not(ElementMatchers.isDeclaredBy(Map.class))) .and(ElementMatchers.isGetter() .or(ElementMatchers.isSetter())) .and(ElementMatchers.isPublic() .or(ElementMatchers.isProtected()))