001package com.mrivanplays.annotationconfig.core;
002
003import java.lang.annotation.Annotation;
004
005/** Represents an annotation type, holding utility methods for the held raw annotation type. */
006public final class AnnotationType {
007
008  public static final AnnotationType COMMENT = new AnnotationType(Comment.class);
009  public static final AnnotationType COMMENTS = new AnnotationType(Comments.class);
010  public static final AnnotationType TYPE_RESOLVER = new AnnotationType(TypeResolver.class);
011  public static final AnnotationType KEY = new AnnotationType(Key.class);
012  public static final AnnotationType CONFIG_OBJECT = new AnnotationType(ConfigObject.class);
013
014  /**
015   * Returns whether or not the annotation type specified is custom.
016   *
017   * @param type the type you want to check if its custom
018   * @return boolean value, representing the outcome of the check.
019   */
020  public static boolean isCustom(AnnotationType type) {
021    return !COMMENT.is(type)
022        && !COMMENTS.is(type)
023        && !TYPE_RESOLVER.is(type)
024        && !KEY.is(type)
025        && !CONFIG_OBJECT.is(type);
026  }
027
028  /**
029   * Tries to match the annotation raw type to the built in annotation types.
030   *
031   * <p>If you're searching for a way to also match custom annotation types, use {@link
032   * #match(Class, CustomAnnotationRegistry)}
033   *
034   * @param anno annotation raw type
035   * @return matched annotation type, or null
036   */
037  public static AnnotationType match(Class<? extends Annotation> anno) {
038    return COMMENT.is(anno)
039        ? COMMENT
040        : COMMENTS.is(anno)
041            ? COMMENTS
042            : KEY.is(anno)
043                ? KEY
044                : TYPE_RESOLVER.is(anno)
045                    ? TYPE_RESOLVER
046                    : CONFIG_OBJECT.is(anno) ? CONFIG_OBJECT : null;
047  }
048
049  /**
050   * Tries to match the annotation raw type to the annotation types in the {@link
051   * CustomAnnotationRegistry} and the built in annotation types.
052   *
053   * @param anno annotation raw type
054   * @param annoRegistry searched registry
055   * @return matched annotation type, or null
056   */
057  public static AnnotationType match(
058      Class<? extends Annotation> anno, CustomAnnotationRegistry annoRegistry) {
059    if (annoRegistry == null || annoRegistry.registry().isEmpty()) {
060      return match(anno);
061    }
062    for (AnnotationType type : annoRegistry.registry().keySet()) {
063      if (type.is(anno)) {
064        return type;
065      }
066    }
067
068    return match(anno);
069  }
070
071  private final Class<? extends Annotation> rawType;
072
073  public AnnotationType(Class<? extends Annotation> rawType) {
074    this.rawType = rawType;
075  }
076
077  /**
078   * Returns the raw type held by this annotation type.
079   *
080   * @return raw type
081   */
082  public Class<? extends Annotation> getRawType() {
083    return rawType;
084  }
085
086  /**
087   * Returns whether or not the specified raw annotation type exactly matches the held raw
088   * annotation type in this instance.
089   *
090   * @param anno raw annotation type
091   * @return boolean value, representing the outcome of this check
092   */
093  public boolean is(Class<? extends Annotation> anno) {
094    return anno.getSimpleName().equalsIgnoreCase(rawType.getSimpleName());
095  }
096
097  /**
098   * @param type annotation type
099   * @return boolean value, representing the outcome of this check
100   * @see #is(Class)
101   */
102  public boolean is(AnnotationType type) {
103    return is(type.rawType);
104  }
105
106  @Override
107  public String toString() {
108    return "AnnotationType{" + "rawType=" + rawType.getSimpleName() + '}';
109  }
110}