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

io.jstach.rainbowgum.apt.prism.KeyParameterPrism Maven / Gradle / Ivy

package io.jstach.rainbowgum.apt.prism;

import java.util.Map;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.ElementFilter;

import org.eclipse.jdt.annotation.Nullable;

/**
 * A Prism representing an {@code @io.jstach.rainbowgum.annotation.LogConfigurable.KeyParameter} annotation. 
 */ 
public class KeyParameterPrism {
    /** store prism value of value */
    private @Nullable String _value;

    /**
     * Qualified class name of annotation.
     */
    public static final String PRISM_ANNOTATION_TYPE = "io.jstach.rainbowgum.annotation.LogConfigurable.KeyParameter";

    /**
     * An instance of the Values inner class whose
     * methods return the AnnotationValues used to build this prism. 
     * Primarily intended to support using Messager.
     */
    public final Values values;
    /**
     * Return a prism representing the {@code @io.jstach.rainbowgum.annotation.LogConfigurable.KeyParameter} annotation on 'e'. 
     * similar to {@code e.getAnnotation(io.jstach.rainbowgum.annotation.LogConfigurable.KeyParameter.class)} except that 
     * an instance of this class rather than an instance of {@code io.jstach.rainbowgum.annotation.LogConfigurable.KeyParameter}
     * is returned.
     * @param e element. 
     * @return prism for element. 
     */
    public static @Nullable KeyParameterPrism getInstanceOn(Element e) {
        AnnotationMirror m = getMirror(PRISM_ANNOTATION_TYPE, e);
        if(m == null) return null;
        return getInstance(m);
   }

    /**
     * Return a prism of the {@code @io.jstach.rainbowgum.annotation.LogConfigurable.KeyParameter} annotation whose mirror is mirror. 
     * @param mirror mirror. 
     * @return prism for mirror 
     */

    public static KeyParameterPrism getInstance(AnnotationMirror mirror) {
        String mirrorType = mirror.getAnnotationType().toString();
        if(!PRISM_ANNOTATION_TYPE.equals(mirrorType)) {
             throw new java.lang.IllegalArgumentException("expected: " + PRISM_ANNOTATION_TYPE + " got: " + mirrorType);
        }
        return new KeyParameterPrism(mirror);
    }

    private KeyParameterPrism(AnnotationMirror mirror) {
        for(var e : mirror.getElementValues().entrySet()) {
            memberValues.put(e.getKey().getSimpleName().toString(), e.getValue());
        }
        for(ExecutableElement member : ElementFilter.methodsIn(mirror.getAnnotationType().asElement().getEnclosedElements())) {
            var defaultValue = member.getDefaultValue();
            if (defaultValue == null) continue;
            defaults.put(member.getSimpleName().toString(), defaultValue);
        }
        _value = getValue("value",String.class);
        this.values = new Values(memberValues);
        this.mirror = mirror;
        this.isValid = valid;
    }

    /**
     * Returns a String representing the value of the {@code java.lang.String value()} member of the Annotation.
     * @return prism value.
     * @see io.jstach.rainbowgum.annotation.LogConfigurable.KeyParameter#value()
     */ 
    public String value() { return requireMember(_value); }

    /**
     * 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.
     */
    public final boolean isValid;
    
    /**
     * The underlying AnnotationMirror of the annotation
     * represented by this Prism. 
     * Primarily intended to support using Messager.
     */
    public final AnnotationMirror mirror;
    /**
     * A class whose members corespond to those of io.jstach.rainbowgum.annotation.LogConfigurable.KeyParameter
     * 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.
     */
    public static class Values {
       private Map values;
       private Values(Map values) {
           this.values = values;
       }    
       /**
        * Return the AnnotationValue corresponding to the value() 
        * member of the annotation, or null when the default value is implied.
        * @return annotation value.
        */
       public @Nullable AnnotationValue value(){ return values.get("value");}
    }
    private Map defaults = new java.util.HashMap<>();
    private Map memberValues = new java.util.HashMap<>();
    private boolean valid = true;

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

    private static @Nullable AnnotationMirror getMirror(String fqn, Element target) {
        for (AnnotationMirror m :target.getAnnotationMirrors()) {
            CharSequence mfqn = ((TypeElement)m.getAnnotationType().asElement()).getQualifiedName();
            if(fqn.contentEquals(mfqn)) return m;
        }
        return null;
    }
    private static  @Nullable 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;
    }
    private static  T requireMember(@Nullable T t) {
        if (t == null) {
            throw new java.util.NoSuchElementException("prism is invalid");
        }
        return t;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy