All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.avaje.jsonb.generator.JsonPrism Maven / Gradle / Ivy

package io.avaje.jsonb.generator;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Map;
import javax.annotation.processing.Generated;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.VariableElement;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.type.TypeMirror;
import java.util.HashMap;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.ElementFilter;

/** A Prism representing a {@link io.avaje.jsonb.Json @Json} annotation. */ 
@Generated("avaje-prism-generator")
final class JsonPrism {
  /** store prism value of naming */
  private final String _naming;

  /** store prism value of typeProperty */
  private final String _typeProperty;

  /** store prism value of caseInsensitiveKeys */
  private final Boolean _caseInsensitiveKeys;

  public static final String PRISM_TYPE = "io.avaje.jsonb.Json";

  /**
   * An instance of the Values inner class whose
   * methods return the AnnotationValues used to build this prism. 
   * Primarily intended to support using Messager.
   */
  final Values values;

  /** Returns true if the mirror is an instance of {@link io.avaje.jsonb.Json @Json} is present on the element, else false.
   *
   * @param mirror mirror. 
   * @return true if prism is present. 
   */
  static boolean isInstance(AnnotationMirror mirror) {
    return getInstance(mirror) != null;
  }

  /** Returns true if {@link io.avaje.jsonb.Json @Json} is present on the element, else false.
   *
   * @param element element. 
   * @return true if annotation is present on the element. 
   */
  static boolean isPresent(Element element) {
    return getInstanceOn(element) != null;
  }

  /** Return a prism representing the {@link io.avaje.jsonb.Json @Json} annotation present on the given element. 
   * similar to {@code element.getAnnotation(Json.class)} except that 
   * an instance of this class rather than an instance of {@link io.avaje.jsonb.Json @Json}
   * is returned.
   *
   * @param element element. 
   * @return prism on element or null if no annotation is found. 
   */
  static JsonPrism getInstanceOn(Element element) {
    final var mirror = getMirror(element);
    if (mirror == null) return null;
    return getInstance(mirror);
  }

  /** Return a Optional representing a nullable {@link io.avaje.jsonb.Json @Json} annotation on the given element. 
   * similar to {@code element.getAnnotation(io.avaje.jsonb.Json.class)} except that 
   * an Optional of this class rather than an instance of {@link io.avaje.jsonb.Json}
   * is returned.
   *
   * @param element element. 
   * @return prism optional for element. 
   */
  static Optional getOptionalOn(Element element) {
    final var mirror = getMirror(element);
    if (mirror == null) return Optional.empty();
    return getOptional(mirror);
  }

  /** Return a prism of the {@link io.avaje.jsonb.Json @Json} annotation from an annotation mirror. 
   *
   * @param mirror mirror. 
   * @return prism for mirror or null if mirror is an incorrect type. 
   */
  static JsonPrism getInstance(AnnotationMirror mirror) {
    if (mirror == null || !PRISM_TYPE.equals(mirror.getAnnotationType().toString())) return null;

    return new JsonPrism(mirror);
  }

  /** Return an Optional representing a nullable {@link JsonPrism @JsonPrism} from an annotation mirror. 
   * similar to {@code e.getAnnotation(io.avaje.jsonb.Json.class)} except that 
   * an Optional of this class rather than an instance of {@link io.avaje.jsonb.Json @Json}
   * is returned.
   *
   * @param mirror mirror. 
   * @return prism optional for mirror. 
   */
  static Optional getOptional(AnnotationMirror mirror) {
    if (mirror == null || !PRISM_TYPE.equals(mirror.getAnnotationType().toString())) return Optional.empty();

    return Optional.of(new JsonPrism(mirror));
  }

  private JsonPrism(AnnotationMirror mirror) {
    for (final ExecutableElement key : mirror.getElementValues().keySet()) {
      memberValues.put(key.getSimpleName().toString(), mirror.getElementValues().get(key));
    }
    for (final ExecutableElement member : ElementFilter.methodsIn(mirror.getAnnotationType().asElement().getEnclosedElements())) {
      defaults.put(member.getSimpleName().toString(), member.getDefaultValue());
    }
    VariableElement namingMirror = getValue("naming", VariableElement.class);
    valid = valid && namingMirror != null;
    _naming = namingMirror == null ? null : namingMirror.getSimpleName().toString();
    _typeProperty = getValue("typeProperty", String.class);
    _caseInsensitiveKeys = getValue("caseInsensitiveKeys", Boolean.class);
    this.values = new Values(memberValues);
    this.mirror = mirror;
    this.isValid = valid;
  }

  /** 
   * Returns a String representing the value of the {@code io.avaje.jsonb.Json.Naming naming()} member of the Annotation.
   * @see io.avaje.jsonb.Json#naming()
   */ 
  public String naming() { return _naming; }

  /** 
   * Returns a String representing the value of the {@code java.lang.String typeProperty()} member of the Annotation.
   * @see io.avaje.jsonb.Json#typeProperty()
   */ 
  public String typeProperty() { return _typeProperty; }

  /** 
   * Returns a Boolean representing the value of the {@code boolean caseInsensitiveKeys()} member of the Annotation.
   * @see io.avaje.jsonb.Json#caseInsensitiveKeys()
   */ 
  public Boolean caseInsensitiveKeys() { return _caseInsensitiveKeys; }

  /**
   * Determine whether the underlying AnnotationMirror has no errors.
   * True if the underlying AnnotationMirror has no errors.
   * When true is returned, none of the methods will return null.
   * When false is returned, a least one member will either return null, or another
   * prism that is not valid.
   */
   final boolean isValid;
    
  /**
   * The underlying AnnotationMirror of the annotation
   * represented by this Prism. 
   * Primarily intended to support using Messager.
   */
   final AnnotationMirror mirror;
  /**
   * A class whose members correspond to those of {@link io.avaje.jsonb.Json @Json} 
   * but which each return the AnnotationValue corresponding to
   * that member in the model of the annotations. Returns null for
   * defaulted members. Used for Messager, so default values are not useful.
   */
  static final class Values {
    private final Map values;

    private Values(Map values) {
      this.values = values;
    }    
    /** Return the AnnotationValue corresponding to the naming() 
     * member of the annotation, or null when the default value is implied.
     */
    AnnotationValue naming(){ return values.get("naming");}
    /** Return the AnnotationValue corresponding to the typeProperty() 
     * member of the annotation, or null when the default value is implied.
     */
    AnnotationValue typeProperty(){ return values.get("typeProperty");}
    /** Return the AnnotationValue corresponding to the caseInsensitiveKeys() 
     * member of the annotation, or null when the default value is implied.
     */
    AnnotationValue caseInsensitiveKeys(){ return values.get("caseInsensitiveKeys");}
  }

  private final Map defaults = new HashMap(10);
  private final Map memberValues = new HashMap(10);
  private boolean valid = true;

  private  T getValue(String name, Class clazz) {
    final T result = JsonPrism.getValue(memberValues, defaults, name, clazz);
    if (result == null) valid = false;
    return result;
  }

  private static AnnotationMirror getMirror(Element target) {
    for (final var m : target.getAnnotationMirrors()) {
      final CharSequence mfqn = ((TypeElement) m.getAnnotationType().asElement()).getQualifiedName();
      if (PRISM_TYPE.contentEquals(mfqn)) return m;
    }
    return null;
  }

  private static  T getValue(Map memberValues, Map defaults, String name, Class clazz) {
    AnnotationValue av = memberValues.get(name);
    if (av == null) av = defaults.get(name);
    if (av == null) {
      return null;
    }
    if (clazz.isInstance(av.getValue())) return clazz.cast(av.getValue());
    return null;
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy