/** * Create an {@code AliasDescriptor} <em>from</em> the declaration * of {@code @AliasFor} on the supplied annotation attribute and * validate the configuration of {@code @AliasFor}. * @param attribute the annotation attribute that is annotated with * {@code @AliasFor} * @return an alias descriptor, or {@code null} if the attribute * is not annotated with {@code @AliasFor} * @see #validateAgainst */ @Nullable public static AliasDescriptor from(Method attribute) { AliasDescriptor descriptor = aliasDescriptorCache.get(attribute); if (descriptor != null) { return descriptor; } AliasFor aliasFor = attribute.getAnnotation(AliasFor.class); if (aliasFor == null) { return null; } descriptor = new AliasDescriptor(attribute, aliasFor); descriptor.validate(); aliasDescriptorCache.put(attribute, descriptor); return descriptor; }
/** * Get the name of the overridden attribute configured via * {@link AliasFor @AliasFor} for the supplied annotation {@code attribute}. * @param attribute the attribute from which to retrieve the override * (never {@code null}) * @param metaAnnotationType the type of meta-annotation in which the * overridden attribute is allowed to be declared * @return the name of the overridden attribute, or {@code null} if not * found or not applicable for the specified meta-annotation type * @throws IllegalArgumentException if the supplied attribute method is * {@code null} or not from an annotation, or if the supplied meta-annotation * type is {@code null} or {@link Annotation} * @throws AnnotationConfigurationException if invalid configuration of * {@code @AliasFor} is detected * @since 4.2 */ @Nullable static String getAttributeOverrideName(Method attribute, @Nullable Class<? extends Annotation> metaAnnotationType) { AliasDescriptor descriptor = AliasDescriptor.from(attribute); return (descriptor != null && metaAnnotationType != null ? descriptor.getAttributeOverrideName(metaAnnotationType) : null); }
String mirrorAliasedAttributeName = getAliasedAttributeName(mirrorAliasFor, this.aliasedAttribute); if (!this.sourceAttributeName.equals(mirrorAliasedAttributeName)) { String msg = String.format("Attribute '%s' in annotation [%s] must be declared as an @AliasFor [%s], not [%s].", validateDefaultValueConfiguration(this.aliasedAttribute);
String mirrorAliasedAttributeName = getAliasedAttributeName(mirrorAliasFor, this.aliasedAttribute); if (!this.sourceAttributeName.equals(mirrorAliasedAttributeName)) { String msg = String.format("Attribute '%s' in annotation [%s] must be declared as an @AliasFor [%s], not [%s].", validateDefaultValueConfiguration(this.aliasedAttribute);
String mirrorAliasedAttributeName = getAliasedAttributeName(mirrorAliasFor, this.aliasedAttribute); if (!this.sourceAttributeName.equals(mirrorAliasedAttributeName)) { String msg = String.format("Attribute '%s' in annotation [%s] must be declared as an @AliasFor [%s], not [%s].", validateDefaultValueConfiguration(this.aliasedAttribute);
@SuppressWarnings("unchecked") private AliasDescriptor(Method sourceAttribute, AliasFor aliasFor) { Class<?> declaringClass = sourceAttribute.getDeclaringClass(); this.sourceAttribute = sourceAttribute; this.sourceAnnotationType = (Class<? extends Annotation>) declaringClass; this.sourceAttributeName = sourceAttribute.getName(); this.aliasedAnnotationType = (Annotation.class == aliasFor.annotation() ? this.sourceAnnotationType : aliasFor.annotation()); this.aliasedAttributeName = getAliasedAttributeName(aliasFor, sourceAttribute); if (this.aliasedAnnotationType == this.sourceAnnotationType && this.aliasedAttributeName.equals(this.sourceAttributeName)) { String msg = String.format("@AliasFor declaration on attribute '%s' in annotation [%s] points to " + "itself. Specify 'annotation' to point to a same-named attribute on a meta-annotation.", sourceAttribute.getName(), declaringClass.getName()); throw new AnnotationConfigurationException(msg); } try { this.aliasedAttribute = this.aliasedAnnotationType.getDeclaredMethod(this.aliasedAttributeName); } catch (NoSuchMethodException ex) { String msg = String.format( "Attribute '%s' in annotation [%s] is declared as an @AliasFor nonexistent attribute '%s' in annotation [%s].", this.sourceAttributeName, this.sourceAnnotationType.getName(), this.aliasedAttributeName, this.aliasedAnnotationType.getName()); throw new AnnotationConfigurationException(msg, ex); } this.isAliasPair = (this.sourceAnnotationType == this.aliasedAnnotationType); }
@SuppressWarnings("unchecked") private AliasDescriptor(Method sourceAttribute, AliasFor aliasFor) { Class<?> declaringClass = sourceAttribute.getDeclaringClass(); this.sourceAttribute = sourceAttribute; this.sourceAnnotationType = (Class<? extends Annotation>) declaringClass; this.sourceAttributeName = sourceAttribute.getName(); this.aliasedAnnotationType = (Annotation.class == aliasFor.annotation() ? this.sourceAnnotationType : aliasFor.annotation()); this.aliasedAttributeName = getAliasedAttributeName(aliasFor, sourceAttribute); if (this.aliasedAnnotationType == this.sourceAnnotationType && this.aliasedAttributeName.equals(this.sourceAttributeName)) { String msg = String.format("@AliasFor declaration on attribute '%s' in annotation [%s] points to " + "itself. Specify 'annotation' to point to a same-named attribute on a meta-annotation.", sourceAttribute.getName(), declaringClass.getName()); throw new AnnotationConfigurationException(msg); } try { this.aliasedAttribute = this.aliasedAnnotationType.getDeclaredMethod(this.aliasedAttributeName); } catch (NoSuchMethodException ex) { String msg = String.format( "Attribute '%s' in annotation [%s] is declared as an @AliasFor nonexistent attribute '%s' in annotation [%s].", this.sourceAttributeName, this.sourceAnnotationType.getName(), this.aliasedAttributeName, this.aliasedAnnotationType.getName()); throw new AnnotationConfigurationException(msg, ex); } this.isAliasPair = (this.sourceAnnotationType == this.aliasedAnnotationType); }
/** * Create an {@code AliasDescriptor} <em>from</em> the declaration * of {@code @AliasFor} on the supplied annotation attribute and * validate the configuration of {@code @AliasFor}. * @param attribute the annotation attribute that is annotated with * {@code @AliasFor} * @return an alias descriptor, or {@code null} if the attribute * is not annotated with {@code @AliasFor} * @see #validateAgainst */ @Nullable public static AliasDescriptor from(Method attribute) { AliasDescriptor descriptor = aliasDescriptorCache.get(attribute); if (descriptor != null) { return descriptor; } AliasFor aliasFor = attribute.getAnnotation(AliasFor.class); if (aliasFor == null) { return null; } descriptor = new AliasDescriptor(attribute, aliasFor); descriptor.validate(); aliasDescriptorCache.put(attribute, descriptor); return descriptor; }
/** * Get the name of the overridden attribute configured via * {@link AliasFor @AliasFor} for the supplied annotation {@code attribute}. * @param attribute the attribute from which to retrieve the override * (never {@code null}) * @param metaAnnotationType the type of meta-annotation in which the * overridden attribute is allowed to be declared * @return the name of the overridden attribute, or {@code null} if not * found or not applicable for the specified meta-annotation type * @throws IllegalArgumentException if the supplied attribute method is * {@code null} or not from an annotation, or if the supplied meta-annotation * type is {@code null} or {@link Annotation} * @throws AnnotationConfigurationException if invalid configuration of * {@code @AliasFor} is detected * @since 4.2 */ @Nullable static String getAttributeOverrideName(Method attribute, @Nullable Class<? extends Annotation> metaAnnotationType) { AliasDescriptor descriptor = AliasDescriptor.from(attribute); return (descriptor != null && metaAnnotationType != null ? descriptor.getAttributeOverrideName(metaAnnotationType) : null); }
/** * Create an {@code AliasDescriptor} <em>from</em> the declaration * of {@code @AliasFor} on the supplied annotation attribute and * validate the configuration of {@code @AliasFor}. * @param attribute the annotation attribute that is annotated with * {@code @AliasFor} * @return an alias descriptor, or {@code null} if the attribute * is not annotated with {@code @AliasFor} * @see #validateAgainst */ @Nullable public static AliasDescriptor from(Method attribute) { AliasDescriptor descriptor = aliasDescriptorCache.get(attribute); if (descriptor != null) { return descriptor; } AliasFor aliasFor = attribute.getAnnotation(AliasFor.class); if (aliasFor == null) { return null; } descriptor = new AliasDescriptor(attribute, aliasFor); descriptor.validate(); aliasDescriptorCache.put(attribute, descriptor); return descriptor; }
/** * Create an {@code AliasDescriptor} <em>from</em> the declaration * of {@code @AliasFor} on the supplied annotation attribute and * validate the configuration of {@code @AliasFor}. * @param attribute the annotation attribute that is annotated with * {@code @AliasFor} * @return an alias descriptor, or {@code null} if the attribute * is not annotated with {@code @AliasFor} * @see #validateAgainst */ @Nullable public static AliasDescriptor from(Method attribute) { AliasDescriptor descriptor = aliasDescriptorCache.get(attribute); if (descriptor != null) { return descriptor; } AliasFor aliasFor = attribute.getAnnotation(AliasFor.class); if (aliasFor == null) { return null; } descriptor = new AliasDescriptor(attribute, aliasFor); descriptor.validate(); aliasDescriptorCache.put(attribute, descriptor); return descriptor; }
/** * Determine if this descriptor and the supplied descriptor both * effectively represent aliases for the same attribute in the same * target annotation, either explicitly or implicitly. * <p>This method searches the attribute override hierarchy, beginning * with this descriptor, in order to detect implicit and transitively * implicit aliases. * @return {@code true} if this descriptor and the supplied descriptor * effectively alias the same annotation attribute * @see #isOverrideFor */ private boolean isAliasFor(AliasDescriptor otherDescriptor) { for (AliasDescriptor lhs = this; lhs != null; lhs = lhs.getAttributeOverrideDescriptor()) { for (AliasDescriptor rhs = otherDescriptor; rhs != null; rhs = rhs.getAttributeOverrideDescriptor()) { if (lhs.aliasedAttribute.equals(rhs.aliasedAttribute)) { return true; } } } return false; }
/** * Get the name of the overridden attribute configured via * {@link AliasFor @AliasFor} for the supplied annotation {@code attribute}. * @param attribute the attribute from which to retrieve the override * (never {@code null}) * @param metaAnnotationType the type of meta-annotation in which the * overridden attribute is allowed to be declared * @return the name of the overridden attribute, or {@code null} if not * found or not applicable for the specified meta-annotation type * @throws IllegalArgumentException if the supplied attribute method is * {@code null} or not from an annotation, or if the supplied meta-annotation * type is {@code null} or {@link Annotation} * @throws AnnotationConfigurationException if invalid configuration of * {@code @AliasFor} is detected * @since 4.2 */ @Nullable static String getAttributeOverrideName(Method attribute, @Nullable Class<? extends Annotation> metaAnnotationType) { AliasDescriptor descriptor = AliasDescriptor.from(attribute); return (descriptor != null && metaAnnotationType != null ? descriptor.getAttributeOverrideName(metaAnnotationType) : null); }
/** * Get the name of the overridden attribute configured via * {@link AliasFor @AliasFor} for the supplied annotation {@code attribute}. * @param attribute the attribute from which to retrieve the override * (never {@code null}) * @param metaAnnotationType the type of meta-annotation in which the * overridden attribute is allowed to be declared * @return the name of the overridden attribute, or {@code null} if not * found or not applicable for the specified meta-annotation type * @throws IllegalArgumentException if the supplied attribute method is * {@code null} or not from an annotation, or if the supplied meta-annotation * type is {@code null} or {@link Annotation} * @throws AnnotationConfigurationException if invalid configuration of * {@code @AliasFor} is detected * @since 4.2 */ @Nullable static String getAttributeOverrideName(Method attribute, @Nullable Class<? extends Annotation> metaAnnotationType) { AliasDescriptor descriptor = AliasDescriptor.from(attribute); return (descriptor != null && metaAnnotationType != null ? descriptor.getAttributeOverrideName(metaAnnotationType) : null); }
/** * Determine if this descriptor and the supplied descriptor both * effectively represent aliases for the same attribute in the same * target annotation, either explicitly or implicitly. * <p>This method searches the attribute override hierarchy, beginning * with this descriptor, in order to detect implicit and transitively * implicit aliases. * @return {@code true} if this descriptor and the supplied descriptor * effectively alias the same annotation attribute * @see #isOverrideFor */ private boolean isAliasFor(AliasDescriptor otherDescriptor) { for (AliasDescriptor lhs = this; lhs != null; lhs = lhs.getAttributeOverrideDescriptor()) { for (AliasDescriptor rhs = otherDescriptor; rhs != null; rhs = rhs.getAttributeOverrideDescriptor()) { if (lhs.aliasedAttribute.equals(rhs.aliasedAttribute)) { return true; } } } return false; }
/** * Determine if this descriptor and the supplied descriptor both * effectively represent aliases for the same attribute in the same * target annotation, either explicitly or implicitly. * <p>This method searches the attribute override hierarchy, beginning * with this descriptor, in order to detect implicit and transitively * implicit aliases. * @return {@code true} if this descriptor and the supplied descriptor * effectively alias the same annotation attribute * @see #isOverrideFor */ private boolean isAliasFor(AliasDescriptor otherDescriptor) { for (AliasDescriptor lhs = this; lhs != null; lhs = lhs.getAttributeOverrideDescriptor()) { for (AliasDescriptor rhs = otherDescriptor; rhs != null; rhs = rhs.getAttributeOverrideDescriptor()) { if (lhs.aliasedAttribute.equals(rhs.aliasedAttribute)) { return true; } } } return false; }
/** * Get the names of the aliased attributes configured via * {@link AliasFor @AliasFor} for the supplied annotation {@code attribute}. * @param attribute the attribute to find aliases for * @return the names of the aliased attributes (never {@code null}, though * potentially <em>empty</em>) * @throws IllegalArgumentException if the supplied attribute method is * {@code null} or not from an annotation * @throws AnnotationConfigurationException if invalid configuration of * {@code @AliasFor} is detected * @since 4.2 * @see #getAttributeOverrideName(Method, Class) */ static List<String> getAttributeAliasNames(Method attribute) { AliasDescriptor descriptor = AliasDescriptor.from(attribute); return (descriptor != null ? descriptor.getAttributeAliasNames() : Collections.<String> emptyList()); }
public List<String> getAttributeAliasNames() { // Explicit alias pair? if (this.isAliasPair) { return Collections.singletonList(this.aliasedAttributeName); } // Else: search for implicit aliases List<String> aliases = new ArrayList<>(); for (AliasDescriptor otherDescriptor : getOtherDescriptors()) { if (this.isAliasFor(otherDescriptor)) { this.validateAgainst(otherDescriptor); aliases.add(otherDescriptor.sourceAttributeName); } } return aliases; }
/** * Get the names of the aliased attributes configured via * {@link AliasFor @AliasFor} for the supplied annotation {@code attribute}. * @param attribute the attribute to find aliases for * @return the names of the aliased attributes (never {@code null}, though * potentially <em>empty</em>) * @throws IllegalArgumentException if the supplied attribute method is * {@code null} or not from an annotation * @throws AnnotationConfigurationException if invalid configuration of * {@code @AliasFor} is detected * @since 4.2 * @see #getAttributeOverrideName(Method, Class) */ static List<String> getAttributeAliasNames(Method attribute) { AliasDescriptor descriptor = AliasDescriptor.from(attribute); return (descriptor != null ? descriptor.getAttributeAliasNames() : Collections.emptyList()); }
public List<String> getAttributeAliasNames() { // Explicit alias pair? if (this.isAliasPair) { return Collections.singletonList(this.aliasedAttributeName); } // Else: search for implicit aliases List<String> aliases = new ArrayList<>(); for (AliasDescriptor otherDescriptor : getOtherDescriptors()) { if (this.isAliasFor(otherDescriptor)) { this.validateAgainst(otherDescriptor); aliases.add(otherDescriptor.sourceAttributeName); } } return aliases; }