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