Home | History | Annotate | Download | only in field
      1 package annotations.field;
      2 
      3 /*>>>
      4 import org.checkerframework.checker.nullness.qual.*;
      5 */
      6 
      7 import java.util.HashMap;
      8 import java.util.Map;
      9 
     10 import com.google.common.escape.CharEscaperBuilder;
     11 import com.google.common.escape.Escaper;
     12 
     13 /**
     14  * A <code>BasicAFT</code> represents a primitive or {@link String} annotation
     15  * field type. Get one using {@link #forType(Class)}.
     16  */
     17 // should be an enum except they can't be generic and can't extend a class
     18 public final class BasicAFT extends ScalarAFT {
     19     static final Escaper charEscaper =
     20         new CharEscaperBuilder()
     21             .addEscape('\b', "\\b")
     22             .addEscape('\f', "\\f")
     23             .addEscape('\n', "\\n")
     24             .addEscape('\r', "\\r")
     25             .addEscape('\t', "\\t")
     26             .addEscape('\"', "\\\"")
     27             .addEscape('\\', "\\\\")
     28             .addEscape('\'', "\\'")
     29             .toEscaper();
     30 
     31     /**
     32      * The Java type backing this annotation field type.
     33      */
     34     public final Class<?> type;
     35 
     36     private BasicAFT(Class<?> type) {
     37         this.type = type;
     38     }
     39 
     40     /**
     41      * Returns the <code>BasicAFT</code> for <code>type</code>, which
     42      * should be primitive (e.g., int.class) or String.  Returns null if
     43      * <code>type</code> is not appropriate for a basic annotation field
     44      * type.
     45      */
     46     public static BasicAFT forType(Class<?> type) {
     47         return bafts.get(type);
     48     }
     49 
     50     /**
     51      * Maps from {@link #type} to <code>BasicAFT</code>.
     52      * Contains every BasicAFT.
     53      */
     54     // Disgusting reason for being public; need to fix.
     55     public static final Map<Class<?>, BasicAFT> bafts;
     56 
     57     static {
     58         Map<Class<?>, BasicAFT> tempBafts =
     59             new HashMap<Class<?>, BasicAFT>(9);
     60         tempBafts.put(byte.class, new BasicAFT(byte.class));
     61         tempBafts.put(short.class, new BasicAFT(short.class));
     62         tempBafts.put(int.class, new BasicAFT(int.class));
     63         tempBafts.put(long.class, new BasicAFT(long.class));
     64         tempBafts.put(float.class, new BasicAFT(float.class));
     65         tempBafts.put(double.class, new BasicAFT(double.class));
     66         tempBafts.put(char.class, new BasicAFT(char.class));
     67         tempBafts.put(boolean.class, new BasicAFT(boolean.class));
     68         tempBafts.put(String.class, new BasicAFT(String.class));
     69         // bafts = Collections2.<Class<?>, BasicAFT>unmodifiableKeyedSet(tempBafts);
     70         // bafts = bafts2;
     71         bafts = tempBafts;
     72     }
     73 
     74     /**
     75      * {@inheritDoc}
     76      */
     77     @Override
     78     public boolean isValidValue(Object o) {
     79         return (   (type == byte.class && o instanceof Byte)
     80                 || (type == short.class && o instanceof Short)
     81                 || (type == int.class && o instanceof Integer)
     82                 || (type == long.class && o instanceof Long)
     83                 || (type == float.class && o instanceof Float)
     84                 || (type == double.class && o instanceof Double)
     85                 || (type == char.class && o instanceof Character)
     86                 || (type == boolean.class && o instanceof Boolean)
     87                 || (type == String.class && o instanceof String));
     88     }
     89 
     90     /**
     91      * {@inheritDoc}
     92      */
     93     @Override
     94     public String toString() {
     95         if (type == String.class) {
     96             return "String";
     97         } else {
     98             return type.getName();
     99         }
    100     }
    101 
    102     /**
    103      * {@inheritDoc}
    104      */
    105     @Override
    106     public String format(Object o) {
    107       return type != String.class ? o.toString()
    108           : "\"" + charEscaper.escape((String) o) + "\"";
    109     }
    110 
    111     @Override
    112     public <R, T> R accept(AFTVisitor<R, T> v, T arg) {
    113         return v.visitBasicAFT(this, arg);
    114     }
    115 }
    116