001package Torello.JavaDoc; 002 003 004// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 005// Standard-Java Imports 006// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 007 008import java.io.IOException; 009import java.util.List; 010import java.util.function.Consumer; 011 012 013// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 014// Java-HTML Imports 015// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 016 017import Torello.Java.*; 018 019import static Torello.JavaDoc.PF.*; 020 021import Torello.Java.ReadOnly.ReadOnlyList; 022import Torello.Java.ReadOnly.ReadOnlyArrayList; 023import Torello.Java.ReadOnly.ROArrayListBuilder; 024 025 026// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 027// JDUInternal 028// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 029 030import Torello.JDUInternal.Annotations.EntityAnnotations.EntityAnnotationData; 031 032 033// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 034// The new Source-Code Parser: com.sun.source.* 035// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 036 037import com.sun.source.tree.VariableTree; 038import com.sun.source.tree.ExpressionTree; 039import com.sun.source.tree.NewClassTree; 040 041 042/** 043 * <B CLASS=JDDescLabel>Reflection Class:</B> 044 * 045 * <BR />Holds all information extracted from <CODE>'.java' enum</CODE> Source-Files about 046 * Enumerated-Constants's identified in that {@code 'enum'} file. 047 * 048 * <EMBED CLASS='external-html' DATA-FILE-ID=JPB_GET_INST> 049 * <EMBED CLASS='external-html' DATA-FILE-ID=JPB_ENUM_CONST> 050 */ 051@JDHeaderBackgroundImg(EmbedTagFileID={"REFLECTION_EXTENSION"}) 052public class EnumConstant 053 extends Declaration 054 implements java.io.Serializable, Comparable<EnumConstant>, Cloneable 055{ 056 /** <EMBED CLASS='external-html' DATA-FILE-ID=SVUID> */ 057 public static final long serialVersionUID = 1; 058 059 @Override 060 String codeHiLiteString() { return this.signature; } 061 062 063 // ******************************************************************************************** 064 // ******************************************************************************************** 065 // Public Fields: Param-Expressions 066 // ******************************************************************************************** 067 // ******************************************************************************************** 068 069 070 /** 071 * The parameters passed to the constructor that constructed the enumerated-constant instance. 072 * 073 * <BR /><BR />Many (or most) {@code enum's} do not actually use a constructor for their 074 * constants. Using a constructor is an extra-feature that allows additional information / 075 * data to be ascribed to the constant. 076 * 077 * <BR /><BR />If no constructor has been used to buid an Enumerated Constant, then there 078 * (obviously) wouldn't be any expressions passed to a constructor for that constant. In such 079 * cases, this field will contain a non-null, empty, {@code ReadOnlyList<String>}. 080 */ 081 public final ReadOnlyList<String> paramExpressions; 082 083 084 // ******************************************************************************************** 085 // ******************************************************************************************** 086 // Reference-Hook: com.sun.source.tree 087 // ******************************************************************************************** 088 // ******************************************************************************************** 089 090 091 /** 092 * <EMBED CLASS='external-html' DATA-FILE-ID=SSTB_HOOK_FIELD> 093 * 094 * If a user decides to make use of the native Oracle {@code VariableTree} instance that 095 * was used to build this {@code EnumConstant} instance, it may be retrieved from this 096 * {@code transient} field. 097 * 098 * <BR /><BR /><B CLASS=JDDescLabel>{@code MethodTree} Note:</B> 099 * 100 * <BR />The package {@code com.sun.source.tree} "reuses" or "overloads" the 101 * {@code VariableTree} class in that it may represent either a Field, or an 102 * Enumerated-Constant. 103 */ 104 public final transient VariableTree variableTree; 105 106 107 // ******************************************************************************************** 108 // ******************************************************************************************** 109 // Constructor - com.sun.source.tree 110 // ******************************************************************************************** 111 // ******************************************************************************************** 112 113 114 // public, but internally-used-ONLY Constructor 115 public EnumConstant( 116 final VariableTree vt, 117 final EntityAnnotationData ead, 118 final TreeUtils util 119 ) 120 { 121 super( 122 ead, // Stuff for building EntityAnnotationMirrors 123 util, // TreeUtils instance (contains all the parser and stuff) 124 vt, // 'Tree' instance 125 null, // ModifiersTree: Annotations on the Field & key-words 126 // 127 // TO-DO: ******** RESEARCH THIS, MAYBE FIX THIS ******** 128 // HERE - THE PRESUMPTION IS THAT AN ANNOTATION MAY NOT BE 129 // PLACED ON AN ENUM-CONSTANT - AND THEREFORE, NEITHER THE 130 // MODIFIERS NOR THE ANNOTATIONS ARE RELEVANT!! 131 // ******************************************************* 132 133 vt.getName().toString(), // Name of the Field 134 // vt.toString().trim(), // Signature 135 Entity.ENUM_CONSTANT, // Entity 136 null // Pass 'null' to the 'body' tree-node 137 ); 138 139 // List<? extends ExpressionTree> args = ... 140 @SuppressWarnings("unchecked") 141 List<ExpressionTree> args = 142 (List<ExpressionTree>) ((NewClassTree) vt.getInitializer()).getArguments(); 143 144 if ((args == null) || (args.size() == 0)) 145 this.paramExpressions = EMPTY_READONLY_LIST; 146 147 else this.paramExpressions = new ReadOnlyArrayList<String> 148 (args, (ExpressionTree et) -> et.toString().trim(), args.size()); 149 150 // Reference Hooks: This was built using the com.sun.source.tree.VariableTree class, so 151 // there simply isn't a com.github.javaparser.ast.body.EnumConstantDeclaration (so it is 152 // set to null) 153 154 this.variableTree = vt; 155 } 156 157 158 // ******************************************************************************************** 159 // ******************************************************************************************** 160 // toString() 161 // ******************************************************************************************** 162 // ******************************************************************************************** 163 164 165 /** 166 * Generates a {@code String} of this {@code Enum Constant}, with all information included. 167 * @return A printable {@code String} of this {@code EnumConstant}. 168 * @see #toString(int) 169 */ 170 public String toString() 171 { 172 return 173 "Name: [" + name + "]\n" + 174 "Declaration: [" + StrPrint.abbrevEndRDSF(signature, MAX_STR_LEN, true) + "]\n" + 175 176 // This will **NEVER** be null - unless 'this' instance was built from an HTML File, 177 // rather than a source-code file. Instances like that are only used temporarily, and 178 // are garbage collected instantly. Do this check anyway (just in case). 179 180 "Location: " + ((this.location == null) 181 ? "null" 182 : ('[' + this.location.quickSummary() + ']')); 183 } 184 185 /** 186 * <EMBED CLASS='external-html' DATA-FILE-ID=TO_STR_PF> 187 * 188 * <BR /><BR />There is additional information printed by this {@code 'toString'} method 189 * (versus the zero-argument, standard, Java {@code 'toString'}). This method will print any 190 * available Java-Doc Comment's that were placed on this {@code EnumConstant}. 191 * 192 * <BR /><BR />This {@code 'toString'} also allows for adding UNIX-Terminal color codes. 193 * 194 * @param flags These are defined in the {@link PF Print-Flags} class 195 * @return A printable {@code String} of this {@code EnumConstant}. 196 * @see PF 197 * @see #toString() 198 */ 199 public String toString(int flags) 200 { 201 boolean color = (flags & UNIX_COLORS) > 0; 202 203 return 204 printedName("Enum-Const", 17, color) + 205 printedDeclaration(17, color) + 206 printedParamExpressions(17) + 207 printedLocation(17, color, (flags & BRIEF_LOCATION) > 0) + 208 209 // The previous method does not add a '\n' end to the end of the returned string 210 // This is optional, it adds a '\n' AT THE BEGINNING if it is included 211 212 printedComments(17, color, (flags & JAVADOC_COMMENTS) > 0); 213 } 214 215 private String printedParamExpressions(int LEN) 216 { 217 if ((paramExpressions == null) || (paramExpressions.size() == 0)) 218 return ""; 219 220 return StringParse.rightSpacePad("Initializer:", LEN) + 221 "[" + StrCSV.toCSV(paramExpressions, false, false, null) + "]\n"; 222 } 223 224 225 // ******************************************************************************************** 226 // ******************************************************************************************** 227 // CompareTo & Equals 228 // ******************************************************************************************** 229 // ******************************************************************************************** 230 231 232 /** 233 * Java's {@code interface Comparable<T>} requirements. This does a very simple comparison 234 * using the two constants' {@link #name} field. 235 * 236 * @param ec Any other {@code EnumConstant} to be compared to {@code 'this' EnumConstant} 237 * 238 * @return An integer that fulfills Java's {@code Comparable<EnumConstant>} interface 239 * requirements. 240 */ 241 public int compareTo(EnumConstant ec) 242 { return (this == ec) ? 0 : this.name.compareTo(ec.name); } 243 244 /** 245 * This <I>should be called an "atypical version" of </I> the usual {@code equals(Object 246 * other)} method. This version of equals merely compares the name of the constant defined. 247 * The presumption here is that the definition of an 'constant' only has meaning - <I>at 248 * all</I> - inside the context of an {@code enum} where that constant has been defined. Since 249 * inside any {@code '.java'} {@code enum}, there may only be one element with a given name, 250 * this method shall return {@code TRUE} whenever the constant being compared also has the same 251 * name. 252 * 253 * @param other This may be any other {@code EnumConstant}. It is <I><B>strongly 254 * suggested</B></I> that {@code 'other'} be a {@code constant} defined in the same 255 * {@code '.java'} source-code file as {@code 'this'} constant. 256 * 257 * @return This method returns {@code TRUE} when {@code 'this'} instance of 258 * {@code EnumConstant} has the same {@code 'name'} as the name of input-parameter 259 * {@code 'other'} 260 */ 261 public boolean equals(EnumConstant other) 262 { return this.name.equals(other.name); } 263 264 265 // ******************************************************************************************** 266 // ******************************************************************************************** 267 // A.I. Token-Stream Generator-Method 268 // ******************************************************************************************** 269 // ******************************************************************************************** 270 271 272 public ReadOnlyList<ReadOnlyList<String>> getTokenStreams() 273 { 274 final ROArrayListBuilder<ReadOnlyList<String>> tokens = new ROArrayListBuilder<>(); 275 ROArrayListBuilder<String> b = new ROArrayListBuilder<>(); 276 277 tokens.add(ReadOnlyList.of("SECTION", "entity", "enum-constant")); 278 tokens.add(ReadOnlyList.of("SECTION", "name", this.name)); 279 280 if ((this.paramExpressions != null) && (! this.paramExpressions.isEmpty())) 281 { 282 b = new ROArrayListBuilder<>(); 283 b.add("SECTION"); 284 b.add("constructor-params"); 285 for (String param : this.paramExpressions) b.add(param); 286 tokens.add(b.build()); 287 } 288 289 if ((this.annotations != null) && (! this.annotations.isEmpty())) 290 { 291 b = new ROArrayListBuilder<>(); 292 b.add("SECTION"); 293 b.add("annotations"); 294 for (String a : this.annotations) b.add(a); 295 tokens.add(b.build()); 296 } 297 298 return tokens.build(); 299 } 300 301}