001package Torello.JavaDoc; 002 003 004// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 005// Standard-Java Imports 006// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 007 008import java.io.IOException; 009import java.sql.CallableStatement; 010import java.util.Optional; 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.ROArrayListBuilder; 023 024 025// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 026// JDUInternal 027// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 028 029import Torello.JDUInternal.Annotations.EntityAnnotations.EntityAnnotationData; 030import Torello.JDUInternal.Parse.HTML.Signature.D1_CallableSignature; 031 032 033// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 034// The new Source-Code Parser: com.sun.source.* 035// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 036 037import com.sun.source.tree.MethodTree; 038 039 040/** 041 * <B CLASS=JDDescLabel>Reflection Class:</B> 042 * 043 * <BR />Holds all information extracted from <CODE>'.java'</CODE> Source-Files about 044 * Constructor's identified in that file. 045 * 046 * <EMBED CLASS='external-html' DATA-FILE-ID=JPB_GET_INST> 047 * <EMBED CLASS='external-html' DATA-FILE-ID=JPB_CONSTRUCTOR> 048 * <!-- EMBED CLASS='external-html' DATA-FILE-ID=JPB_DIAGRAM --> 049 */ 050@JDHeaderBackgroundImg(EmbedTagFileID={"REFLECTION_EXTENSION"}) 051public class Constructor extends Callable 052 implements java.io.Serializable, Comparable<Constructor>, Cloneable 053{ 054 /** <EMBED CLASS='external-html' DATA-FILE-ID=SVUID> */ 055 public static final long serialVersionUID = 1; 056 057 058 // ******************************************************************************************** 059 // ******************************************************************************************** 060 // Reference-Hook: com.sun.source.tree 061 // ******************************************************************************************** 062 // ******************************************************************************************** 063 064 065 /** 066 * <EMBED CLASS='external-html' DATA-FILE-ID=SSTB_HOOK_FIELD> 067 * 068 * If a user decides to make use of the native Sun/Oracle {@code MethodTree} instance that was 069 * used to build this {@code Constructor} instance, it may be retrieved from this 070 * {@code transient} field. 071 * 072 * <BR /><BR /><B CLASS=JDDescLabel>{@code MethodTree} Note:</B> 073 * 074 * <BR />The package {@code com.sun.source.tree} "reuses" or "overloads" the {@code MethodTree} 075 * class. {@code com.sun.source.tree.MethodTree} can actually represent either a Method, or a 076 * Constructor. 077 * 078 * <BR /><BR />When a {@code MethodTree} instance is actually representing a constructor, the 079 * name that it uses for the instance will be Java-String {@code '<init>'}, rather than an 080 * actual Method-Name. 081 */ 082 public final transient MethodTree methodTree; 083 084 085 // ******************************************************************************************** 086 // ******************************************************************************************** 087 // Constructor - com.sun.source.tree 088 // ******************************************************************************************** 089 // ******************************************************************************************** 090 091 092 /** 093 * <EMBED CLASS="defs" DATA-KIND=Constructor DATA-ENTITY=MethodTree> 094 * <EMBED CLASS='external-html' DATA-FILE-ID=RC_DESCRIPTION> 095 * @param mt <EMBED CLASS='external-html' DATA-FILE-ID=RC_PARAM_TREE> 096 * @param util <EMBED CLASS='external-html' DATA-FILE-ID=RC_PARAM_UTIL> 097 * 098 * @param constructorName The name of the type (which is also the name of the constructor) has 099 * to be passed here, in order for this constructor to work. 100 */ 101 public Constructor( 102 final MethodTree mt, 103 final EntityAnnotationData ead, 104 final TreeUtils util, 105 final String constructorName 106 ) 107 { 108 super(mt, constructorName, Entity.CONSTRUCTOR, ead, util); 109 110 // Only the 2 reference hooks are needed here 111 this.methodTree = mt; 112 } 113 114 115 // ******************************************************************************************** 116 // ******************************************************************************************** 117 // Constructor: Used Internally by SignatureParse 118 // ******************************************************************************************** 119 // ******************************************************************************************** 120 121 122 // Ensures that the Version with longer type-information strings is used. 123 // Java Doc often uses longer type strings than is available from the source-code parse 124 // Remember, JavaParser Symbol-Solver doesn't work well, and the Sun/Oracle Parser doesn't have 125 // a linker at all. 126 127 public Constructor(final D1_CallableSignature cSig, final Constructor cFromSourceParser) 128 { 129 // Does the same thing as the loop statement below, but for the "parameterTypes" 130 super(cSig, cFromSourceParser); 131 132 this.methodTree = cFromSourceParser.methodTree; 133 } 134 135 // This is only used to construct a constructor for SYNTHETIC-CONSTRUCTORS. At the present 136 // moment, that means this is only used when there is a Zero-Argument Constructor that the user 137 // did not actually type into his code, but rather is being auto-added by javac. 138 139 public Constructor(final D1_CallableSignature cSig) 140 { 141 super(cSig, Entity.CONSTRUCTOR); 142 143 this.methodTree = null; 144 } 145 146 147 // ******************************************************************************************** 148 // ******************************************************************************************** 149 // toString() 150 // ******************************************************************************************** 151 // ******************************************************************************************** 152 153 154 /** 155 * Generates a string of this constructor, with most information included. 156 * 157 * <BR /><BR /><B CLASS=JDDescLabel>Reduced Information:</B> 158 * 159 * <BR />This {@code 'toString'} will not return every piece of information contained by this 160 * class. For example, both the constructor body, and any possible JavaDoc Comments are not 161 * included. For a more enhanced {@code toString()} method version, invoke the 162 * {@link #toString(int) toString(PrintFlags)} method which accepts {@link PF Print-Flags}. 163 * 164 * @return A printable string of this field. 165 * @see PF 166 * @see #toString(int) 167 */ 168 public String toString() 169 { 170 return 171 "Name: [" + name + "]\n" + 172 "Signature: [" + StrPrint.abbrevEndRDSF(signature, MAX_STR_LEN, true) + "]\n" + 173 "Modifiers: [" + StrCSV.toCSV(modifiers, true, true, null) + "]\n" + 174 printedParameterNamesTS() + 175 printedParameterTypesTS() + 176 printedExceptionsTS() + 177 178 // This will **NEVER** be null - unless 'this' instance was built from an HTML File, 179 // rather than a source-code file. Instances like that are only used temporarily, and 180 // are garbage collected instantly. Do this check anyway (just in case). 181 182 "Location: " + ((this.location == null) 183 ? "null" 184 : ('[' + this.location.quickSummary() + ']')); 185 } 186 187 /** 188 * <EMBED CLASS='external-html' DATA-FILE-ID=TO_STR_PF> 189 * @param flags These are defined in the {@link PF Print-Flags} class 190 * @return A printable {@code String} of this {@code Constructor}. 191 * @see #toString() 192 * @see PF 193 */ 194 public String toString(int flags) 195 { 196 boolean color = (flags & UNIX_COLORS) > 0; 197 198 return 199 printedName("Constructor", 20, color) + 200 printedSignature(20, color) + 201 printedModifiers(20) + 202 printedParamNames() + 203 printedParamTypes(jowFlags(flags)) + 204 printedExceptions() + 205 printedLocation(20, color, (flags & BRIEF_LOCATION) > 0) + 206 207 // The previous method does not add a '\n' end to the end of the returned string 208 // These are both optional, they add a '\n' AT THE BEGINNING if one of them is included 209 210 printedComments(20, color, (flags & JAVADOC_COMMENTS) > 0) + 211 printedCallableBody(flags); 212 } 213 214 215 // ******************************************************************************************** 216 // ******************************************************************************************** 217 // CompareTo and Equals 218 // ******************************************************************************************** 219 // ******************************************************************************************** 220 221 222 /** 223 * Java's {@code interface Comparable<T>} requirements. This looks at the number of 224 * parameters, and parameter types in making a sort-decision. 225 * 226 * @param c Any other {@code Constructor} to be compared to {@code 'this' Constructor} 227 * 228 * @return An integer that fulfills Java's {@code Comparable<Constructor>} interface 229 * requirements. 230 */ 231 public int compareTo(Constructor c) 232 { 233 if (this == c) return 0; 234 235 int ret = this.numParameters() - c.numParameters(); 236 if (ret != 0) return ret; 237 238 if (this.parameterTypesJOW != null) 239 240 for (int i=0; i < this.parameterTypesJOW.size(); i++) 241 { 242 ret = this.parameterTypesJOW.get(i).compareTo(c.parameterTypesJOW.get(i)); 243 if (ret != 0) return ret; 244 } 245 246 return 0; 247 } 248 249 /** 250 * This <I>should be called an "atypical version" of</I> the usual 251 * {@code equals(Object other)} constructor. This version of equals merely compares the name 252 * and parameters-list of the constructor. The presumption here is that the definition of a 253 * 'constructor' only has meaning - <I>at all</I> - inside the context of a {@code class} or 254 * {@code enumerated-type} where that constructor is defined. Since inside any {@code '.java'} 255 * source-code file, there may only be one constructor with a given parameter-list, this shall 256 * return {@code TRUE} whenever the constructor being compared has the same parameter types as 257 * {@code 'this'} does. 258 * 259 * @param other This may be any other constructor. It is <I><B>strongly suggested</B></I> that 260 * this be a constructor defined in the same {@code '.java'} source-code file as 'this' 261 * constructor. 262 * 263 * @return This method returns {@code TRUE} when 'this' instance of Constructor has the same 264 * parameter-list as {@code 'other'}. 265 */ 266 public boolean equals(Constructor other) 267 { 268 // If the number of parameters in the 'other' instance of Constructor differ from the 269 // number of parameters in 'this' Constructor, then return FALSE immediately. It cannot be 270 // a match 271 272 if (this.numParameters() != other.numParameters()) return false; 273 274 // If there are no parameters (for either of them), then return true immediately 275 if (this.numParameters() == 0) return true; 276 277 // If any of the parameter-names are different, break immediately and return false; 278 for (int i=0; i < this.parameterNames.size(); i++) 279 if (! this.parameterNames.get(i).equals(other.parameterNames.get(i))) 280 return false; 281 282 283 // If the parameter-types listed by the javadoc '.html' file differ from parameter-types 284 // listed in the original '.java' source-code file, then break immediately. 285 // 286 // NOTE: The "package-information" for the FULL CLASS OR INTERFACE NAME is not always 287 // available. 288 289 for (int i=0; i < this.parameterTypes.size(); i++) 290 if (! this.parameterTypesJOW.get(i).equals(other.parameterTypesJOW.get(i))) 291 return false; 292 293 // ALL TESTS PASSED 294 return true; 295 } 296 297 298 // ******************************************************************************************** 299 // ******************************************************************************************** 300 // A.I. Token-Stream Generator-Method 301 // ******************************************************************************************** 302 // ******************************************************************************************** 303 304 305 public ReadOnlyList<ReadOnlyList<String>> getTokenStreams() 306 { 307 final ROArrayListBuilder<ReadOnlyList<String>> tokens = new ROArrayListBuilder<>(); 308 ROArrayListBuilder<String> b = new ROArrayListBuilder<>(); 309 310 tokens.add(ReadOnlyList.of("SECTION", "entity", "constructor")); 311 tokens.add(ReadOnlyList.of("SECTION", "signature", this.signature)); 312 313 if ((this.parameterNames != null) && (this.parameterNames.size() > 0)) 314 { 315 b.add("SECTION"); 316 b.add("parameters"); 317 for (int i = 0; i < this.parameterNames.size(); i++) 318 b.add(this.parameterTypesJOW.get(i) + " " + this.parameterNames.get(i)); 319 tokens.add(b.build()); 320 } 321 322 if ((this.modifiers != null) && (modifiers.size() > 0)) 323 { 324 b = new ROArrayListBuilder<>(); 325 b.add("SECTION"); 326 b.add("modifiers"); 327 for (String m : this.modifiers) b.add(m); 328 tokens.add(b.build()); 329 } 330 331 if ((this.exceptions != null) && (this.exceptions.size() > 0)) 332 { 333 b = new ROArrayListBuilder<>(); 334 b.add("SECTION"); 335 b.add("throws"); 336 for (String exn : this.exceptions) b.add(exn); 337 tokens.add(b.build()); 338 } 339 340 if ((this.annotations != null) && (annotations.size() > 0)) 341 { 342 b = new ROArrayListBuilder<>(); 343 b.add("SECTION"); 344 b.add("annotations"); 345 for (String a : this.annotations) b.add(a); 346 tokens.add(b.build()); 347 } 348 349 return tokens.build(); 350 } 351 352}