Created
May 14, 2019 14:57
-
-
Save agentgt/a3c8dc50ce992ee375d9e5a358172417 to your computer and use it in GitHub Desktop.
Example of Hickory generating a prism for JPA column
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.Map; | |
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 net.java.dev.hickory.prism.internal.*; | |
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 an {@code @javax.persistence.Column} annotation. | |
*/ | |
public class ColumnPrism { | |
/** store prism value of columnDefinition */ | |
private String _columnDefinition; | |
/** store prism value of insertable */ | |
private Boolean _insertable; | |
/** store prism value of length */ | |
private Integer _length; | |
/** store prism value of name */ | |
private String _name; | |
/** store prism value of nullable */ | |
private Boolean _nullable; | |
/** store prism value of precision */ | |
private Integer _precision; | |
/** store prism value of scale */ | |
private Integer _scale; | |
/** store prism value of table */ | |
private String _table; | |
/** store prism value of unique */ | |
private Boolean _unique; | |
/** store prism value of updatable */ | |
private Boolean _updatable; | |
/** | |
* 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 @javax.persistence.Column} annotation on 'e'. | |
* similar to {@code e.getAnnotation(javax.persistence.Column.class)} except that | |
* an instance of this class rather than an instance of {@code javax.persistence.Column} | |
* is returned. | |
*/ | |
public static ColumnPrism getInstanceOn(Element e) { | |
AnnotationMirror m = getMirror("javax.persistence.Column",e); | |
if(m == null) return null; | |
return getInstance(m); | |
} | |
/** Return a prism of the {@code @javax.persistence.Column} annotation whose mirror is mirror. | |
*/ | |
public static ColumnPrism getInstance(AnnotationMirror mirror) { | |
return new ColumnPrism(mirror); | |
} | |
private ColumnPrism(AnnotationMirror mirror) { | |
for(ExecutableElement key : mirror.getElementValues().keySet()) { | |
memberValues.put(key.getSimpleName().toString(),mirror.getElementValues().get(key)); | |
} | |
for(ExecutableElement member : ElementFilter.methodsIn(mirror.getAnnotationType().asElement().getEnclosedElements())) { | |
defaults.put(member.getSimpleName().toString(),member.getDefaultValue()); | |
} | |
_columnDefinition = getValue("columnDefinition",String.class); | |
_insertable = getValue("insertable",Boolean.class); | |
_length = getValue("length",Integer.class); | |
_name = getValue("name",String.class); | |
_nullable = getValue("nullable",Boolean.class); | |
_precision = getValue("precision",Integer.class); | |
_scale = getValue("scale",Integer.class); | |
_table = getValue("table",String.class); | |
_unique = getValue("unique",Boolean.class); | |
_updatable = getValue("updatable",Boolean.class); | |
this.values = new Values(memberValues); | |
this.mirror = mirror; | |
this.isValid = valid; | |
} | |
/** | |
* Returns a String representing the value of the {@code java.lang.String public abstract java.lang.String columnDefinition() } member of the Annotation. | |
* @see javax.persistence.Column#columnDefinition() | |
*/ | |
public String columnDefinition() { return _columnDefinition; } | |
/** | |
* Returns a Boolean representing the value of the {@code boolean public abstract boolean insertable() } member of the Annotation. | |
* @see javax.persistence.Column#insertable() | |
*/ | |
public Boolean insertable() { return _insertable; } | |
/** | |
* Returns a Integer representing the value of the {@code int public abstract int length() } member of the Annotation. | |
* @see javax.persistence.Column#length() | |
*/ | |
public Integer length() { return _length; } | |
/** | |
* Returns a String representing the value of the {@code java.lang.String public abstract java.lang.String name() } member of the Annotation. | |
* @see javax.persistence.Column#name() | |
*/ | |
public String name() { return _name; } | |
/** | |
* Returns a Boolean representing the value of the {@code boolean public abstract boolean nullable() } member of the Annotation. | |
* @see javax.persistence.Column#nullable() | |
*/ | |
public Boolean nullable() { return _nullable; } | |
/** | |
* Returns a Integer representing the value of the {@code int public abstract int precision() } member of the Annotation. | |
* @see javax.persistence.Column#precision() | |
*/ | |
public Integer precision() { return _precision; } | |
/** | |
* Returns a Integer representing the value of the {@code int public abstract int scale() } member of the Annotation. | |
* @see javax.persistence.Column#scale() | |
*/ | |
public Integer scale() { return _scale; } | |
/** | |
* Returns a String representing the value of the {@code java.lang.String public abstract java.lang.String table() } member of the Annotation. | |
* @see javax.persistence.Column#table() | |
*/ | |
public String table() { return _table; } | |
/** | |
* Returns a Boolean representing the value of the {@code boolean public abstract boolean unique() } member of the Annotation. | |
* @see javax.persistence.Column#unique() | |
*/ | |
public Boolean unique() { return _unique; } | |
/** | |
* Returns a Boolean representing the value of the {@code boolean public abstract boolean updatable() } member of the Annotation. | |
* @see javax.persistence.Column#updatable() | |
*/ | |
public Boolean updatable() { return _updatable; } | |
/** | |
* 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 javax.persistence.Column | |
* 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<String,AnnotationValue> values; | |
private Values(Map<String,AnnotationValue> values) { | |
this.values = values; | |
} | |
/** Return the AnnotationValue corresponding to the columnDefinition() | |
* member of the annotation, or null when the default value is implied. | |
*/ | |
public AnnotationValue columnDefinition(){ return values.get("columnDefinition");} | |
/** Return the AnnotationValue corresponding to the insertable() | |
* member of the annotation, or null when the default value is implied. | |
*/ | |
public AnnotationValue insertable(){ return values.get("insertable");} | |
/** Return the AnnotationValue corresponding to the length() | |
* member of the annotation, or null when the default value is implied. | |
*/ | |
public AnnotationValue length(){ return values.get("length");} | |
/** Return the AnnotationValue corresponding to the name() | |
* member of the annotation, or null when the default value is implied. | |
*/ | |
public AnnotationValue name(){ return values.get("name");} | |
/** Return the AnnotationValue corresponding to the nullable() | |
* member of the annotation, or null when the default value is implied. | |
*/ | |
public AnnotationValue nullable(){ return values.get("nullable");} | |
/** Return the AnnotationValue corresponding to the precision() | |
* member of the annotation, or null when the default value is implied. | |
*/ | |
public AnnotationValue precision(){ return values.get("precision");} | |
/** Return the AnnotationValue corresponding to the scale() | |
* member of the annotation, or null when the default value is implied. | |
*/ | |
public AnnotationValue scale(){ return values.get("scale");} | |
/** Return the AnnotationValue corresponding to the table() | |
* member of the annotation, or null when the default value is implied. | |
*/ | |
public AnnotationValue table(){ return values.get("table");} | |
/** Return the AnnotationValue corresponding to the unique() | |
* member of the annotation, or null when the default value is implied. | |
*/ | |
public AnnotationValue unique(){ return values.get("unique");} | |
/** Return the AnnotationValue corresponding to the updatable() | |
* member of the annotation, or null when the default value is implied. | |
*/ | |
public AnnotationValue updatable(){ return values.get("updatable");} | |
} | |
private Map<String,AnnotationValue> defaults = new HashMap<String,AnnotationValue>(10); | |
private Map<String,AnnotationValue> memberValues = new HashMap<String,AnnotationValue>(10); | |
private boolean valid = true; | |
private <T> T getValue(String name, Class<T> clazz) { | |
T result = ColumnPrism.getValue(memberValues,defaults,name,clazz); | |
if(result == null) valid = false; | |
return result; | |
} | |
private <T> List<T> getArrayValues(String name, final Class<T> clazz) { | |
List<T> result = ColumnPrism.getArrayValues(memberValues,defaults,name,clazz); | |
if(result == null) valid = false; | |
return result; | |
} | |
private static 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 <T> T getValue(Map<String,AnnotationValue> memberValues, Map<String,AnnotationValue> defaults, String name, Class<T> 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> List<T> getArrayValues(Map<String,AnnotationValue> memberValues, Map<String,AnnotationValue> defaults, String name, final Class<T> clazz) { | |
AnnotationValue av = memberValues.get(name); | |
if(av == null) av = defaults.get(name); | |
if(av == null) { | |
return null; | |
} | |
if(av.getValue() instanceof List) { | |
List<T> result = new ArrayList<T>(); | |
for(AnnotationValue v : getValueAsList(av)) { | |
if(clazz.isInstance(v.getValue())) { | |
result.add(clazz.cast(v.getValue())); | |
} else{ | |
return null; | |
} | |
} | |
return result; | |
} else { | |
return null; | |
} | |
} | |
@SuppressWarnings("unchecked") | |
private static List<AnnotationValue> getValueAsList(AnnotationValue av) { | |
return (List<AnnotationValue>)av.getValue(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hickory's doc:
https://www.mvndoc.com/c/com.jolira/hickory/index.html