001package Torello.JavaDoc; 002 003 004// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 005// Standard-Java Imports 006// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 007 008import java.io.IOException; 009import java.util.Optional; 010import java.util.function.Consumer; 011 012 013// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 014// Java-HTML Imports 015// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 016 017import Torello.Java.*; 018 019import static Torello.Java.C.*; 020import static Torello.JavaDoc.PF.*; 021 022 023// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 024// The new Source-Code Parser: com.sun.source.* 025// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 026 027import com.sun.source.tree.MethodTree; 028import com.sun.source.tree.Tree; 029 030/** 031 * <B STYLE='color:darkred;'>Reflection Class:</B> 032 * 033 * Holds all information extracted from <CODE>'.java'</CODE> Annotation 034 * (<CODE>@interface</CODE>) Source-Files about all Elements identified in that file. 035 * 036 * <EMBED CLASS='external-html' DATA-FILE-ID=JPB_GET_INST> 037 * <EMBED CLASS='external-html' DATA-FILE-ID=JPB_AELEM> 038 * <EMBED CLASS='external-html' DATA-FILE-ID=JPB_DIAGRAM> 039 * <EMBED CLASS='external-html' DATA-FILE-ID=JPB_AELEM_NOTE> 040 */ 041@JDHeaderBackgroundImg(EmbedTagFileID={"REFLECTION_EXTENSION"}) 042public class AnnotationElem 043 extends Declaration 044 implements java.io.Serializable, Comparable<AnnotationElem>, Cloneable 045{ 046 /** <EMBED CLASS='external-html' DATA-FILE-ID=SVUID> */ 047 public static final long serialVersionUID = 1; 048 049 @Override 050 String codeHiLiteString() { return this.signature; } 051 052 053 // ******************************************************************************************** 054 // ******************************************************************************************** 055 // Public Fields: The Type, and the (optional) Default-Value 056 // ******************************************************************************************** 057 // ******************************************************************************************** 058 059 060 /** 061 * An Annotation-Element may only assume one of several types, as per the Java Sun / Oracle 062 * Documentation. The type must be one of the following, or a compile-time error occurs: 063 * 064 * <BR /><BR /><UL CLASS=JDUL> 065 * <LI>a primitive type</LI> 066 * <LI>String</LI> 067 * <LI>Class or an invocation of Class</LI> 068 * <LI>An enum type</LI> 069 * <LI>An annotation type</LI> 070 * <LI>An (1 dimensional) array type whose component type is one of the preceding types</LI> 071 * </UL> 072 */ 073 public final String type; 074 075 /** 076 * <BR /><BR /><B STYLE='color:red;'>JOW: Just One Word</B> 077 * 078 * <BR /><BR />The <B STYLE='color:red'>Just One Word</B> convention in the upgrader tool 079 * elminates package-name information from type-{@code String's}. 080 */ 081 public final String typeJOW; 082 083 /** 084 * The default value assigned to this element. 085 * This may be null if there is no assigned default value. 086 */ 087 public final String defaultValue; 088 089 090 // ******************************************************************************************** 091 // ******************************************************************************************** 092 // AST Reference-Hook 093 // ******************************************************************************************** 094 // ******************************************************************************************** 095 096 097 /** 098 * <EMBED CLASS='external-html' DATA-FILE-ID=SSTB_HOOK_FIELD> 099 * 100 * If a user decides to make use of the native Sun/Oracle {@code MethodTree} instance that was 101 * used to build this {@code Constructor} instance, it may be retrieved from this 102 * {@code transient} field. 103 * 104 * <BR /><BR /><B>NOTE:</B> The package {@code com.sun.source.tree} "reuses" or "overloads" the 105 * {@code MethodTree} object such that it may represent either a Method, or an Annotation 106 * Element (or even a Constructor). 107 * 108 * <BR /><BR />Since Java Annotations do not actually have methods or constructors, when a 109 * {@code MethodTree} instance is one of the Members of a Class-Tree, it should always be 110 * treated as an Annotation-Element (rather than a method or constructor), 111 */ 112 public final transient MethodTree methodTree; 113 114 115 // ******************************************************************************************** 116 // ******************************************************************************************** 117 // Constructor - com.sun.source.tree 118 // ******************************************************************************************** 119 // ******************************************************************************************** 120 121 122 /** 123 * <EMBED CLASS="defs" DATA-KIND=AnnotationElem DATA-ENTITY=MethodTree> 124 * <EMBED CLASS='external-html' DATA-FILE-ID=RC_DESCRIPTION> 125 * @param mt <EMBED CLASS='external-html' DATA-FILE-ID=RC_PARAM_TREE> 126 * @param util <EMBED CLASS='external-html' DATA-FILE-ID=RC_PARAM_UTIL> 127 */ 128 public AnnotationElem(MethodTree mt, TreeUtils util) 129 { 130 super( 131 util, // TreeUtils instance (contains all the parser and stuff) 132 mt, // 'Tree' instance 133 mt.getModifiers(), // ModifiersTree: Annotations on the Element & key-words 134 mt.getName().toString(), // Name Element 135 Entity.ANNOTATION_ELEM, // Entity 136 mt.getDefaultValue() // Treat the "default-value" as the "body" 137 ); 138 139 Tree defaultValue = mt.getDefaultValue(); 140 141 this.type = mt.getReturnType().toString(); 142 this.typeJOW = StrSource.typeToJavaIdentifier(this.type); 143 this.defaultValue = (defaultValue != null) ? defaultValue.toString().trim() : null; 144 145 // Reference Hook: This was built using the com.sun.source.tree.MethodTree class 146 this.methodTree = mt; 147 } 148 149 150 // ******************************************************************************************** 151 // ******************************************************************************************** 152 // Used Internally by 'SignatureParse' 153 // ******************************************************************************************** 154 // ******************************************************************************************** 155 156 157 // Ensures that the Version with longer type-information strings is used. Java Doc often uses 158 // longer type strings 159 160 public AnnotationElem(AnnotationElem aeFromSourceParser, String jdTypeStr) 161 { 162 super(aeFromSourceParser); 163 164 // 'AnnotationElem' specific fields. Copied from Google: 165 // 166 // Allowed member types (for Annotation-Members / Annotation-Elements) are the following: 167 // primitive types, String, Class, enumerated types, annotation types, and arrays of any 168 // of the above types (but not an array of arrays). 169 // 170 // This does mean that the "type" of an Annotation-Elem (sort-of) cannot be abbreviated or 171 // extended. There is no sense in explaining that 'String' is a 'java.lang.String' 172 173 this.type = jdTypeStr; 174 this.typeJOW = aeFromSourceParser.typeJOW; 175 this.defaultValue = aeFromSourceParser.defaultValue; 176 this.methodTree = aeFromSourceParser.methodTree; 177 } 178 179 180 // ******************************************************************************************** 181 // ******************************************************************************************** 182 // toString(...) 183 // ******************************************************************************************** 184 // ******************************************************************************************** 185 186 187 /** 188 * Generates a {@code String} of this {@code Annotation Element}, with all information included. 189 * 190 * @return A printable string of this {@code AnnotationElem}. 191 * 192 * @see StrCSV#toCSV(String[], boolean, boolean, Integer) 193 * @see #toString(int) 194 */ 195 public String toString() 196 { 197 String def = (defaultValue != null) 198 ? ("Default: [" + StrPrint.abbrevEndRDSF(defaultValue, MAX_STR_LEN, true) + 199 "]\n") 200 : ""; 201 202 return 203 "Name: [" + name + "]\n" + 204 "Declaration: [" + StrPrint.abbrevEndRDSF(signature, MAX_STR_LEN, true) + "]\n" + 205 "Type: [" + typeJOW + "]\n" + 206 "Modifiers: [" + StrCSV.toCSV(modifiers, true, true, null) + "]\n" + 207 def + 208 209 // This will **NEVER** be null - unless 'this' instance was built from an HTML File, 210 // rather than a source-code file. Instances like that are only used temporarily, and 211 // are garbage collected instantly. Do this check anyway (just in case). 212 213 "Location: " + ((this.location == null) 214 ? "null" 215 : ('[' + this.location.quickSummary() + ']')); 216 } 217 218 /** 219 * Generates a {@code String} of this {@code Annotation Element}, with all information 220 * included. This will also included any content requested by the {@code 'flags'} parameter. 221 * For this class ({@code class AnnotationElem}), the only additional information printed by 222 * this {@code 'toString'} method is the Java-Doc Comment {@code String}. 223 * 224 * <BR /><BR />This {@code String} may also have UNIX color codes added. 225 * 226 * @param flags These are the {@code toString(...)} flags from class {@code PF} 227 * ("Print Flags"). View available flags listed in class {@link PF}. 228 * 229 * @return A printable {@code String} of this {@code AnnotationElem}. 230 * 231 * @see PF 232 * @see StrCSV#toCSV(String[], boolean, boolean, Integer) 233 * @see #toString() 234 */ 235 public String toString(int flags) 236 { 237 boolean color = (flags & UNIX_COLORS) > 0; 238 239 return 240 printedName("Element", 14, color) + 241 printedDeclaration(14, color) + 242 "Type-JOW: [" + typeJOW + "]\n" + 243 printedModifiers(14) + 244 printedLocation(14, color, (flags & BRIEF_LOCATION) > 0) + 245 246 // The previous method does not add a '\n' end to the end of the returned string 247 // These are both optional, they add a '\n' AT THE BEGINNING if one of them is included 248 249 printedDefault(color) + 250 printedComments(14, color, (flags & JAVADOC_COMMENTS) > 0); 251 } 252 253 private String printedDefault(boolean color) 254 { 255 // They need to abbreviate, seems extremely "unlikely" - but just in case... 256 return (defaultValue == null) 257 ? "" 258 : "\nDefault: [" + (color ? BGREEN : "") + 259 StrPrint.abbrevEndRDSF(defaultValue, MAX_STR_LEN, true) + 260 (color ? RESET : "") + "]"; 261 } 262 263 264 // ******************************************************************************************** 265 // ******************************************************************************************** 266 // CompareTo & Equals Stuff 267 // ******************************************************************************************** 268 // ******************************************************************************************** 269 270 271 /** 272 * Java's {@code interface Comparable<T>} requirements. This does a very simple comparison 273 * using the two elements' {@code 'name'} field. 274 * 275 * @param ae Any other {@code AnnotationElem} to be compared to {@code 'this' AnnotationElem} 276 * 277 * @return An integer that fulfills Java's 278 * {@code interface Comparable<AnnotationElem> public boolean compareTo(AnnotationElem ae)} 279 * method requirements. 280 */ 281 public int compareTo(AnnotationElem ae) 282 { return (this == ae) ? 0 : this.name.compareTo(ae.name); } 283 284 /** 285 * This <I>should be called an "atypical version" of </I> the usual {@code equals(Object 286 * other)} method. This version of equals merely compares the name of the element defined. 287 * The presumption here is that the definition of an 'element' only has meaning - <I>at all</I> 288 * - inside the context of an {@code Annotation} where that element has been defined. Since 289 * inside any {@code '.java'} {@code Annotation}, there may only be one element with a given 290 * name, this method shall return {@code TRUE} whenever the element being compared also has the 291 * same name. 292 * 293 * @param other This may be any other {@code Annotation-Element}. It is <I><B>strongly 294 * suggested</B></I> that {@code 'other'} be an {@code element} defined in the same 295 * {@code '.java'} source-code file as {@code 'this'} element. 296 * 297 * @return This method returns {@code TRUE} when {@code 'this'} instance of 298 * {@code AnnotationElem} has the same {@code 'name'} as the name of input-parameter 299 * {@code 'other'} 300 */ 301 public boolean equals(AnnotationElem other) 302 { return this.name.equals(other.name); } 303}