001package Torello.JavaDoc;
002
003import java.io.IOException;
004import java.util.Vector;
005import java.util.Iterator;
006import java.util.function.Consumer;
007import java.util.stream.Stream;
008
009import Torello.Java.*;
010import static Torello.Java.C.*;
011
012import Torello.Java.Additional.Ret6;
013
014import Torello.JDUInternal.DataClasses.MainLoopData.AnnotationsMirror;
015import Torello.JDUInternal.DataClasses.MainLoopData.CallableSignature;
016
017import Torello.Java.ReadOnly.ReadOnlyList;
018
019/**
020 * Parent-class of {@link JavaDocHTMLFile} and the source-code parsing classes.
021 * 
022 * <EMBED CLASS='external-html' DATA-FILE-ID=PARSEDFILE>
023 */
024public abstract class ParsedFile implements java.io.Serializable
025{
026    /** <EMBED CLASS='external-html' DATA-FILE-ID=SVUID> */
027    public static final long serialVersionUID = 1;
028
029
030    // ********************************************************************************************
031    // ********************************************************************************************
032    // Annotation-Mirror class
033    // ********************************************************************************************
034    // ********************************************************************************************
035
036
037    // @StaticFunctional and @JDHeaderBackgroundImg - saves all the info from those Annotations
038    // EXPORT_PORTAL method: Used by MainFilesProcessor.PART_TWO_Do_The_Rest
039    // This is not a 'public' field, because the information it contains is **ONLY** the info that
040    // was collected from those two annotations - NOT ALL ANNOTATIONS!
041    //
042    // That information is mostly totally useless to the end user.
043
044    /**
045     * Stores information provided by the JavaDoc Upgrader Annotations.  Note, this Annotation
046     * Mirror does not contain information about any / all annotations used inside of Java Source
047     * Code Files, but rather only the ones created by this API.
048     *
049     * <BR /><BR />These include <B STYLE='color: blue'>{@code @StaticFunctional}</B> and also
050     * <B STYLE='color: blue'>{@code @JDHeaderBackgroundImg}</B>
051     */
052    protected AnnotationsMirror annotationsMirror = null;
053
054
055    // ********************************************************************************************
056    // ********************************************************************************************
057    // Main String-Data Stuff
058    // ********************************************************************************************
059    // ********************************************************************************************
060
061
062    /**
063     * This field simply contains the entire contents of the {@code '.java'} Source-Code File from
064     * whence this {@code ParsedFile} instance originated.
065     * 
066     * <BR /><BR />Note that for in for the sub-class {@link JavaDocHTMLFile}, when the HTML file
067     * which was parsed represents an inner-class / nested-type, this field will still contain the
068     * entire contents of the top-level enclosing java type (as a {@code String}) in this field.
069     * 
070     * <BR /><BR />For instance, if a {@link JavaDocHTMLFile} (which inherits this class,
071     * {@code ParsedFile}) instance had been generated for the Java-HTML inner-class
072     * {@code Torello.HTML.Attributes.Filter}, which happens to be a nested type of class
073     * {@code Torello.HTML.Attributes}, this field would contain the text-characters of the
074     * Source-File {@code Torello/HTML/Attributes.java} in {@code String}-format (as character
075     * data).
076     */
077    public final String javaSrcFileAsStr;
078
079    /** Contains the file-name from which this instance was derived */
080    public final String fileName;
081
082    /**
083     * Holds the name.  A {@code 'ParsedFile'} represents a class, interface, or enumerated-type.
084     * This name is <B>NOT</B> the fully-qualified (package-included) name, and it <B><I>will
085     * have any Generic Type Parameters appended</I></B>, if this CIET represents a generic that
086     * has type-parameters.
087     * 
088     * <BR /><BR />If this {@code CIET} is an inner-class, <I>the containing {@code CIET} name
089     * is included</I> in this {@code String} field.
090     * 
091     * <BR /><BR /><B>For Instance:</B>
092     * 
093     * <BR /><BR /><TABLE CLASS=JDBriefTable>
094     * <TR> <TH>Input {@code CIET}</TH>
095     *      <TH>{@code 'name'} Field Value</TH></TR>
096     * <TR> <TD>interface {@code java.lang.Integer}</TD>
097     *      <TD>{@code "Integer"}</TD></TR>
098     * <TR> <TD>class {@code java.util.Vector<E>}</TD>
099     *      <TD>{@code "Vector<E>"}</TD></TR>
100     * <TR> <TD>class {@code java.util.Base64.Decoder}</TD>
101     *      <TD>{@code "Base.Decoder"}</TD></TR>
102     * <TR> <TD>interface {@code java.util.Map.Entry<K, V>}</TD>
103     *      <TD>{@code "Map.Entry<K, V>"}</TD></TR>
104     * </TABLE>
105     * 
106     * @see #simpleName
107     * @see #fullyQualifiedName
108     */
109    public final String name;
110
111    /**
112     * This holds the <I>fully qualified {@code CIET} name</I> - which means that package and
113     * containing class information is included.  If thi {@code CIET} is a Java Generic that 
114     * happens to have Generic Type Parameters (the {@code 'E'} in {@code Vector<E>}, this name
115     * <B>WILL NOT</B> include that text. 
116     * 
117     * <BR /><BR /><B>For Instance:</B>
118     * 
119     * <BR /><TABLE CLASS=JDBriefTable>
120     * <TR><TH>Input {@code CIET}</TH>
121     *      <TH>{@code 'fullyQualifiedName'} Field Value</TH></TR>
122     * <TR> <TD>interface {@code java.lang.Integer}</TD>
123     *      <TD>{@code "java.lang.Integer"}</TD></TR>
124     * <TR> <TD>class {@code java.util.Vector<E>}</TD>
125     *      <TD>{@code "java.util.Vector"}</TD></TR>
126     * <TR> <TD>class {@code java.util.Base64.Decoder}</TD>
127     *      <TD>{@code "java.util.Base64.Decoder"}</TD></TR>
128     * <TR> <TD>interface {@code java.util.Map.Entry<K, V>}</TD>
129     *      <TD>{@code "java.util.Map.Entry"}</TD></TR>
130     * </TABLE>
131     * 
132     * @see #simpleName
133     * @see #name
134     */
135    public final String fullyQualifiedName;
136
137    /**
138     * This the same as the {@link #name} parameter, but leaves off both the type-parameters, and
139     * the fully-qualified package-name {@code String's}.  If this {@code CIET} is an inner class
140     * the containing {@code CIET} name is included in this {@code String} field.
141     * See the table below, for details:
142     * 
143     * <BR /><TABLE CLASS=JDBriefTable>
144     * <TR><TH>Input {@code CIET}</TH><TH>{@code 'simpleName'} Field Value</TH></TR>
145     * <TR><TD>interface {@code java.lang.Integer}</TD><TD>{@code "Integer"}</TD></TR>
146     * <TR><TD>class {@code java.util.Vector<E>}</TD><TD>{@code "Vector"}</TD></TR>
147     * <TR><TD>class {@code java.util.Base64.Decoder}</TD><TD>{@code "Base64.Decoder"}</TD></TR>
148     * <TR><TD>interface {@code java.util.Map.Entry<K, V>}</TD><TD>{@code "Map.Entry"}</TD></TR>
149     * </TABLE>
150     * 
151     * @see #name
152     * @see #fullyQualifiedName
153     */
154    public final String simpleName;
155
156    /**
157     * Holds the package-name.  If this {@code ParsedFile} were for class {@code java.lang.String}
158     * the {@code 'packageName'} would be {@code 'java.lang'}.
159     */
160    public final String packageName;
161
162
163    // ********************************************************************************************
164    // ********************************************************************************************
165    // The Additional Stuff
166    // ********************************************************************************************
167    // ********************************************************************************************
168
169
170    /**
171     * The acronym 'CIET' simply means "Class, Interface or Enumerated-Type.  This public field
172     * identifies whether this {@code ParsedFile} is for a class, an interface or an enumerated-type.
173     */
174    public final CIET ciet;
175
176    /**
177     * This identifies inner classes and interfaces.
178     * 
179     * <BR /><TABLE CLASS=JDBriefTable>
180     * <TR> <TH>{@code 'isInner'} Field Value</TH>
181     *      <TH>Input {@code CIET}</TH>
182     *      </TR>
183     * <TR> <TD>{@code false}</TD>
184     *      <TD>interface {@code java.lang.Integer}</TD>
185     *      </TR>
186     * <TR> <TD>{@code false}</TD>
187     *      <TD>class {@code java.util.Vector<E>}</TD>
188     *      </TR>
189     * <TR> <TD>{@code true}</TD>
190     *      <TD>class {@code java.util.Base64.Decoder}</TD>
191     *      </TR>
192     * <TR> <TD>{@code true}</TD>
193     *      <TD>interface {@code java.util.Map.Entry<K, V>}</TD>
194     *      </TR>
195     * </TABLE>
196     */
197    public final boolean isInner;
198
199    /**
200     * This identifies inner classes and interfaces.  For any class that is not an inner class,
201     * this will be a zero-length {@code String[]} array.
202     * 
203     * <BR /><TABLE CLASS=JDBriefTable>
204     * <TR> <TH>{@code 'containerClasses'} Value</TH>
205     *      <TH>Input {@code CIET}</TH>
206     *      </TR>
207     * <TR> <TD><CODE></CODE>&lcub; &rcub;</TD>
208     *      <TD>interface {@code java.lang.Integer}</TD>
209     *      </TR>
210     * <TR> <TD><CODE></CODE>&lcub; &rcub;</TD>
211     *      <TD>class {@code java.util.Vector<E>}</TD>
212     *      </TR>
213     * <TR> <TD><CODE></CODE>&lcub; "Base64" &rcub;</TD>
214     *      <TD>class {@code java.util.Base64.Decoder}</TD>
215     *      </TR>
216     * <TR> <TD><CODE></CODE>&lcub; "Map" &rcub;</TD>
217     *      <TD>interface {@code java.util.Map.Entry<K, V>}</TD>
218     *      </TR>
219     * </TABLE>
220     * 
221     * @see #getContainerClasses()
222     */
223    protected final String[] containerClasses;
224
225    /**
226     * Returns the container classes (if any) for this class, interface, etc.
227     * 
228     * @return The list of container classes, from outer to inner, for this class.  If
229     * this is a normal class that is not an <B>inner class</B>, this will return an empty
230     * (zero-lengh) {@code String[]} array.
231     * 
232     * @see #containerClasses
233     */
234    public String[] getContainerClasses()
235    {
236        return (containerClasses.length > 0)
237            ? containerClasses.clone()
238            : StringParse.EMPTY_STR_ARRAY;
239    }
240
241    /**
242     * This field will be {@code TRUE} anytime the {@link #genericParameters} field has
243     * any elements.
244     */
245    public final boolean isGeneric;
246
247    /**
248     * If this represents a Java <B>Generic Class or Interface</B>, with generic type information,
249     * the generic type parameters shall be saved here.
250     * 
251     * @see #getGenericParameters()
252     */
253    protected final ReadOnlyList<String> genericParameters;
254
255    /**
256     * Returns the generic type parameters (if any) for this class or interface
257     * 
258     * @return The generic type parameters as a {@code String[]} array.  If this class is not a
259     * <B>Java Generic</B>, a zero-length {@code String[]} array will be returned.
260     * 
261     * @see #genericParameters
262     */
263    public String[] getGenericParameters()
264    { return genericParameters.toArray(new String[genericParameters.size()]); }
265
266    /**
267     * The line-number in the source-code file where this class definition actually begins.
268     * 
269     * <BR /><BR />Note that if this instance of {@code ParsedFile} is representing a Nessted-Type
270     * / Inner-Class, then this field will contain the line-number where that inner-type's
271     * definition begins inside the Enclosing-Class' {@code '.java'} file.
272     */
273    public final int startLineNumber;
274
275    /**
276     * The line-number in the source-code file where this class definition ends.  Often this will
277     * just be the line-number of the last line in the {@code '.java'} file.
278     * 
279     * <BR /><BR />If this is a Nested-Type, this field will contain the line-number where the
280     * definition of the Nested-type ends.
281     */
282    public final int endLineNumber;
283
284    /**
285     * The starting line-number of the JavaDoc Comment at the top of the class.  If this class
286     * does not have a Java-Doc Comment, this field will contain {@code -1}.
287     */
288    public final int jdStartLineNumber;
289
290    /**
291     * The endiing line-number of the JavaDoc Comment at the top of the class.  If this class does
292     * not have a Java-Doc Comment, this field will contain {@code -1}.
293     */
294    public final int jdEndLineNumber;
295
296    /**
297     * The number of lines of Source-Code inside this {@code '.java'} File.  If this instance of
298     * {@code ParsedFile} represents an Inner-Type (Nested-Class), then this field will contain 
299     * a value that corresponds only to the number of lines used by the Nested-Type within the
300     * context of the entire Enclosing-Class {@code '.java'} file.
301     */
302    public final int typeLineCount;
303
304    /**
305     * The number of characters / bytes of Source-Code inside this {@code '.java'} File.  If this
306     * instance of {@code ParsedFile} represents an Inner-Type (Nested-Class), then this field will
307     * contain a value that corresponds only to the number of characters / bytes used by the
308     * Nested-Type within the context of the entire Enclosing-Class {@code '.java'} file.
309     */
310    public final int typeSizeChars;
311
312
313    // ********************************************************************************************
314    // ********************************************************************************************
315    // Constructor
316    // ********************************************************************************************
317    // ********************************************************************************************
318
319
320    /**
321     * Subclasses of {@code 'ParsedFile'} should use this constructor to initialize these fields.
322     *
323     * <BR /><BR />Used by both {@link JavaDocHTMLFile} and {@code JavaSourceCodeFile}
324     */
325    protected ParsedFile(
326            String                  fileName,
327            String                  name,
328            String                  packageName,
329            CIET                    ciet,
330            ReadOnlyList<String>    genericParameters,
331            String                  fullyQualifiedName,
332            int                     startLineNumber,
333            int                     endLineNumber,
334            int                     jdStartLineNumber,
335            int                     jdEndLineNumber,
336            int                     typeLineCount,
337            int                     typeSizeChars,
338            String                  javaSrcFileAsStr
339        )
340    {
341        this.fileName           = fileName;
342        this.name               = name;
343        this.packageName        = packageName;
344        this.ciet               = ciet;
345        this.genericParameters  = genericParameters;
346        this.fullyQualifiedName = fullyQualifiedName;
347        this.simpleName         = this.name.replaceFirst("<.*>", "");
348        this.isInner            = this.simpleName.indexOf(".") != -1;
349        this.isGeneric          = genericParameters.size() > 0;
350        this.startLineNumber    = startLineNumber;
351        this.endLineNumber      = endLineNumber;
352        this.jdStartLineNumber  = jdStartLineNumber;
353        this.jdEndLineNumber    = jdEndLineNumber;
354        this.typeLineCount      = typeLineCount;
355        this.typeSizeChars      = typeSizeChars;
356        this.javaSrcFileAsStr   = javaSrcFileAsStr;
357
358        // To get the container classes, just split on the period.
359        String[] classes = this.simpleName.split(".");
360
361        // This removes the very-last element resulting from the split.
362        this.containerClasses = (classes.length > 1)
363            ? java.util.Arrays.copyOf(classes, classes.length - 1)
364            : StringParse.EMPTY_STR_ARRAY;
365
366        // for (String genericParameter : genericParameters)
367        //     this.genericParameters.add(genericParameter);
368    }
369
370
371    // ********************************************************************************************
372    // ********************************************************************************************
373    // DECLARED METHODS
374    // ********************************************************************************************
375    // ********************************************************************************************
376
377
378    /**
379     * <EMBED CLASS=defs DATA-DECL=Method DATA-VEC=methods>
380     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_ADD_DESC>
381     * @param m <EMBED CLASS='external-html' DATA-FILE-ID=PF_ADD_DECL>
382     * @see #methods
383     */
384    protected final void addMethod(Method m) { methods.add(m); }
385
386    /**
387     * This is the list of {@link Method} instances identified by the parser for this
388     * {@code ParsedFile}
389     */
390    protected final Vector<Method> methods = new Vector<>();
391
392    /**
393     * <EMBED CLASS=defs DATA-DECL=Method DATA-VEC=methods>
394     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_NUM_DESC>
395     * @return <EMBED CLASS='external-html' DATA-FILE-ID=PF_NUM_RET>
396     * @see #methods
397     */
398    public int numMethods() { return methods.size(); }
399
400    /**
401     * <EMBED CLASS=defs DATA-DECL=Method DATA-VEC=methods>
402     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_GET_DESC>
403     * @param i Index into the {@link #methods} {@code Vector}
404     * @return <EMBED CLASS='external-html' DATA-FILE-ID=PF_GET_RET>
405     * @see #methods
406     */
407    public Method getMethod(int i) { return methods.elementAt(i); }
408
409    /**
410     * <EMBED CLASS=defs DATA-DECL=Method DATA-VEC=methods>
411     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_GET_ALL_DESC>
412     * @return <EMBED CLASS='external-html' DATA-FILE-ID=PF_GET_ALL_RET>
413     * @see #methods
414     */
415    public Method[] getMethods() { return methods.toArray(new Method[methods.size()]); }
416
417    /**
418     * <EMBED CLASS=defs DATA-DECL=Method DATA-VEC=methods>
419     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_CONS_DESC>
420     * @param acceptMethodConsumer Any user-provided {@code Consumer}
421     * @see #methods
422     */
423    public void getMethods(Consumer<Method> acceptMethodConsumer)
424    { methods.forEach((Method method) -> acceptMethodConsumer.accept(method)); }
425
426
427    // ********************************************************************************************
428    // ********************************************************************************************
429    // DECLARED CONSTRUCTORS
430    // ********************************************************************************************
431    // ********************************************************************************************
432
433
434    /**
435     * <EMBED CLASS=defs DATA-DECL=Constructor DATA-VEC=constructors>
436     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_ADD_DESC>
437     * @param c <EMBED CLASS='external-html' DATA-FILE-ID=PF_ADD_DECL>
438     * @see #constructors
439     */
440    protected final void addConstructor(Constructor c) { constructors.add(c); }
441
442    /**
443     * This is the list of {@link Constructor} instances identified by the parser for this
444     * {@code ParsedFile}
445     */
446    protected final Vector<Constructor> constructors = new Vector<>();
447
448    /**
449     * <EMBED CLASS=defs DATA-DECL=Constructor DATA-VEC=constructors>
450     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_NUM_DESC>
451     * @return <EMBED CLASS='external-html' DATA-FILE-ID=PF_NUM_RET>
452     * @see #constructors
453     */
454    public int numConstructors() { return constructors.size(); }
455
456    /**
457     * <EMBED CLASS=defs DATA-DECL=Constructor DATA-VEC=constructors>
458     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_GET_DESC>
459     * @param i Index into the {@link #constructors} {@code Vector}
460     * @return <EMBED CLASS='external-html' DATA-FILE-ID=PF_GET_RET>
461     * @see #constructors
462     */
463    public Constructor getConstructor(int i) { return constructors.elementAt(i); }
464
465    /**
466     * <EMBED CLASS=defs DATA-DECL=Constructor DATA-VEC=constructors>
467     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_GET_ALL_DESC>
468     * @return <EMBED CLASS='external-html' DATA-FILE-ID=PF_GET_ALL_RET>
469     * @see #constructors
470     */
471    public Constructor[] getConstructors()
472    { return constructors.toArray(new Constructor[constructors.size()]); }
473
474    /**
475     * <EMBED CLASS=defs DATA-DECL=Constructor DATA-VEC=constructors>
476     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_CONS_DESC>
477     * @param acceptConstructorConsumer Any user-provided {@code Consumer}
478     * @see #constructors
479     */
480    public void getConstructors(Consumer<Constructor> acceptConstructorConsumer)
481    {
482        constructors.forEach
483            ((Constructor constructor) -> acceptConstructorConsumer.accept(constructor));
484    }
485
486
487    // ********************************************************************************************
488    // ********************************************************************************************
489    // DECLARED FIELDS
490    // ********************************************************************************************
491    // ********************************************************************************************
492
493
494    /**
495     * <EMBED CLASS=defs DATA-DECL=Field DATA-VEC=fields>
496     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_ADD_DESC>
497     * @param f <EMBED CLASS='external-html' DATA-FILE-ID=PF_ADD_DECL>
498     * @see #fields
499     */
500    protected final void addField(Field f) { fields.add(f); }
501
502    /**
503     * This is the list of {@link Field} instances identified by the parser for this
504     * {@code ParsedFile}
505     */
506    protected final Vector<Field> fields = new Vector<>();
507
508    /**
509     * <EMBED CLASS=defs DATA-DECL=Field DATA-VEC=fields>
510     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_NUM_DESC>
511     * @return <EMBED CLASS='external-html' DATA-FILE-ID=PF_NUM_RET>
512     * @see #fields
513     */
514    public int numFields() { return fields.size(); }
515
516    /**
517     * <EMBED CLASS=defs DATA-DECL=Field DATA-VEC=fields>
518     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_GET_DESC>
519     * @param i Index into the {@link #fields} {@code Vector}
520     * @return <EMBED CLASS='external-html' DATA-FILE-ID=PF_GET_RET>
521     * @see #fields
522     */
523    public Field getField(int i) { return fields.elementAt(i); }
524
525    /**
526     * <EMBED CLASS=defs DATA-DECL=Field DATA-VEC=fields>
527     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_GET_ALL_DESC>
528     * @return <EMBED CLASS='external-html' DATA-FILE-ID=PF_GET_ALL_RET>
529     * @see #fields
530     */
531    public Field[] getFields() { return fields.toArray(new Field[fields.size()]); }
532
533    /**
534     * <EMBED CLASS=defs DATA-DECL=Field DATA-VEC=fields>
535     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_CONS_DESC>
536     * @param acceptFieldConsumer Any user-provided {@code Consumer}
537     * @see #fields
538     */
539    public void getFields(Consumer<Field> acceptFieldConsumer)
540    { fields.forEach((Field field) -> acceptFieldConsumer.accept(field)); }
541
542
543    // ********************************************************************************************
544    // ********************************************************************************************
545    // DECLARED ANNOTATION ELEMENTS (only for annotations)
546    // ********************************************************************************************
547    // ********************************************************************************************
548
549
550    /**
551     * <EMBED CLASS=defs DATA-DECL=AnnotationElem DATA-VEC=annotationElems DATA-KIND=annotation>
552     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_ADD_DESC>
553     * @param ae <EMBED CLASS='external-html' DATA-FILE-ID=PF_ADD_DECL>
554     * @see #annotationElems
555     */
556    protected final void addAnnotationElem(AnnotationElem ae)
557    { annotationElems.add(ae); }
558
559    /**
560     * This is the list of {@link AnnotationElem} instances identified by the parser for this
561     * {@code ParsedFile}
562     * <EMBED CLASS=defs DATA-DECL=AnnotationElem DATA-VEC=annotationElems DATA-KIND=annotation>
563     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_NOT_POSSIBLE>
564     */
565    protected final Vector<AnnotationElem> annotationElems = new Vector<>();
566
567    /**
568     * <EMBED CLASS=defs DATA-DECL=AnnotationElem DATA-VEC=annotationElems DATA-KIND=annotation>
569     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_NUM_DESC>
570     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_NOT_POSSIBLE>
571     * @return <EMBED CLASS='external-html' DATA-FILE-ID=PF_NUM_RET>
572     * @see #annotationElems
573     * 
574     */
575    public int numAnnotationElems() { return annotationElems.size(); }
576
577    /**
578     * <EMBED CLASS=defs DATA-DECL=AnnotationElem DATA-VEC=annotationElems DATA-KIND=annotation>
579     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_GET_DESC>
580     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_NOT_POSSIBLE>
581     * @param i Index into the {@link #annotationElems} {@code Vector}
582     * @return <EMBED CLASS='external-html' DATA-FILE-ID=PF_GET_RET>
583     * @see #annotationElems
584     */
585    public AnnotationElem getAnnotationElem(int i) { return annotationElems.elementAt(i); }
586
587    /**
588     * <EMBED CLASS=defs DATA-DECL=AnnotationElem DATA-VEC=annotationElems DATA-KIND=annotation>
589     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_GET_ALL_DESC>
590     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_NOT_POSSIBLE>
591     * @return <EMBED CLASS='external-html' DATA-FILE-ID=PF_GET_ALL_RET>
592     * @see #annotationElems
593     */
594    public AnnotationElem[] getAnnotationElems()
595    { return annotationElems.toArray(new AnnotationElem[annotationElems.size()]); }
596
597    /**
598     * <EMBED CLASS=defs DATA-DECL=AnnotationElem DATA-VEC=annotationElems DATA-KIND=annotation>
599     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_CONS_DESC>
600     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_NOT_POSSIBLE>
601     * @param acceptAEConsumer Any user-provided {@code Consumer}
602     * @see #annotationElems
603     */
604    public void getAnnotationElems(Consumer<AnnotationElem> acceptAEConsumer)
605    { annotationElems.forEach((AnnotationElem elem) -> acceptAEConsumer.accept(elem)); }
606
607
608    // ********************************************************************************************
609    // ********************************************************************************************
610    // DECLARED ENUM CONSTANTS (only for 'enums')
611    // ********************************************************************************************
612    // ********************************************************************************************
613
614
615    /**
616     * <EMBED CLASS=defs DATA-DECL=EnumConstant DATA-VEC=enumConstants DATA-KIND=enum>
617     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_ADD_DESC>
618     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_NOT_POSSIBLE>
619     * @param ec <EMBED CLASS='external-html' DATA-FILE-ID=PF_ADD_DECL>
620     * @see #enumConstants
621     */
622    protected final void addEnumConstant(EnumConstant ec)
623    { enumConstants.add(ec); }
624
625    /**
626     * This is the list of {@link EnumConstant} instances identified by the parser for this
627     * {@code ParsedFile}
628     * <EMBED CLASS=defs DATA-DECL=EnumConstant DATA-VEC=enumConstants DATA-KIND=enum>
629     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_NOT_POSSIBLE>
630     * @see #enumConstants
631     */
632    protected final Vector<EnumConstant> enumConstants = new Vector<>();
633
634    /**
635     * <EMBED CLASS=defs DATA-DECL=EnumConstant DATA-VEC=enumConstants DATA-KIND=enum>
636     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_NUM_DESC>
637     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_NOT_POSSIBLE>
638     * @return <EMBED CLASS='external-html' DATA-FILE-ID=PF_NUM_RET>
639     * @see #enumConstants
640     */
641    public int numEnumConstants() { return enumConstants.size(); }
642
643    /**
644     * <EMBED CLASS=defs DATA-DECL=EnumConstant DATA-VEC=enumConstants DATA-KIND=enum>
645     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_GET_DESC>
646     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_NOT_POSSIBLE>
647     * @param i Index into the {@link #enumConstants} {@code Vector}
648     * @return <EMBED CLASS='external-html' DATA-FILE-ID=PF_GET_RET>
649     * @see #enumConstants
650     */
651    public EnumConstant getEnumConstant(int i) { return enumConstants.elementAt(i); }
652
653    /**
654     * <EMBED CLASS=defs DATA-DECL=EnumConstant DATA-VEC=enumConstants DATA-KIND=enum>
655     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_GET_ALL_DESC>
656     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_NOT_POSSIBLE>
657     * @return <EMBED CLASS='external-html' DATA-FILE-ID=PF_GET_ALL_RET>
658     * @see #enumConstants
659     */
660    public EnumConstant[] getEnumConstants()
661    { return enumConstants.toArray(new EnumConstant[enumConstants.size()]); }
662
663    /**
664     * <EMBED CLASS=defs DATA-DECL=EnumConstant DATA-VEC=enumConstants DATA-KIND=enum>
665     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_CONS_DESC>
666     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_NOT_POSSIBLE>
667     * @param acceptECConsumer Any user-provided {@code Consumer}
668     * @see #enumConstants
669     */
670    public void getEnumConstants(Consumer<EnumConstant> acceptECConsumer)
671    { enumConstants.forEach((EnumConstant elem) -> acceptECConsumer.accept(elem)); }
672
673
674    // ********************************************************************************************
675    // ********************************************************************************************
676    // DECLARED INNER-CLASSES
677    // ********************************************************************************************
678    // ********************************************************************************************
679
680
681    /**
682     * <EMBED CLASS=defs DATA-DECL=NestedType DATA-VEC=nestedTypes>
683     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_ADD_DESC>
684     * @param nt <EMBED CLASS='external-html' DATA-FILE-ID=PF_ADD_DECL>
685     * @see #nestedTypes
686     */
687    protected final void addNestedType(NestedType nt) { nestedTypes.add(nt); }
688
689    /**
690     * This is the list of {@link NestedType} instances identified by the parser for this
691     * {@code ParsedFile}
692     */
693    protected final Vector<NestedType> nestedTypes = new Vector<>();
694
695    /**
696     * <EMBED CLASS=defs DATA-DECL=NestedType DATA-VEC=nestedTypes>
697     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_NUM_DESC>
698     * @return <EMBED CLASS='external-html' DATA-FILE-ID=PF_NUM_RET>
699     * @see #nestedTypes
700     */
701    public int numNestedTypes() { return nestedTypes.size(); }
702
703    /**
704     * <EMBED CLASS=defs DATA-DECL=NestedType DATA-VEC=nestedTypes>
705     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_GET_DESC>
706     * @param i Index into the {@link #nestedTypes} {@code Vector}
707     * @return <EMBED CLASS='external-html' DATA-FILE-ID=PF_GET_RET>
708     * @see #nestedTypes
709     */
710    public NestedType getNestedType(int i) { return nestedTypes.elementAt(i); }
711
712    /**
713     * <EMBED CLASS=defs DATA-DECL=NestedType DATA-VEC=nestedTypes>
714     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_GET_ALL_DESC>
715     * @return <EMBED CLASS='external-html' DATA-FILE-ID=PF_GET_ALL_RET>
716     * @see #nestedTypes
717     */
718    public Method[] getNestedTypes() { return methods.toArray(new Method[methods.size()]); }
719
720    /**
721     * <EMBED CLASS=defs DATA-DECL=NestedType DATA-VEC=nestedTypes>
722     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_CONS_DESC>
723     * @param acceptNTConsumer Any user-provided {@code Consumer}
724     * @see #nestedTypes
725     */
726    public void getNestedTypes(Consumer<NestedType> acceptNTConsumer)
727    { nestedTypes.forEach((NestedType type) -> acceptNTConsumer.accept(type)); }
728
729
730    // ********************************************************************************************
731    // ********************************************************************************************
732    // FIND.
733    // ********************************************************************************************
734    // ********************************************************************************************
735
736
737    /**
738     * Finds a Method having the characteristics specified by parameter {@code 'cSig'}.
739     * 
740     * @param cSig An internally generated representation of a Java-Method extrapolated from the
741     * information available on a Java-Doc HTML Detail Section
742     * 
743     * @return A method that matches the requested Method-Signature
744     */
745    public Method findMethod(CallableSignature cSig)
746    {
747        for (Method method : methods)
748
749            if (    method.name.equals(cSig.name)
750                &&  method.returnTypeJOW.equals(cSig.returnTypeJOW)
751                &&  method.nearlyEqualsCallableSig(cSig)
752            )
753                return method;
754
755        return null;
756    }
757
758    /**
759     * Finds a Constructor having the characteristics specified by parameter {@code 'cSig'}.
760     * 
761     * @param cSig An internally generated representation of a Java-Constructor extrapolated from
762     * the information available on a Java-Doc HTML Detail Section
763     * 
764     * @return A Constructor that matches the requested Constructor-Signature
765     */
766    public Constructor findConstructor(CallableSignature cSig)
767    {
768        for (Constructor ctor : constructors) if (ctor.nearlyEqualsCallableSig(cSig)) return ctor;
769        return null;
770    }
771
772    /**
773     * Returns all internally-stored {@code Method} instances whose {@code Method#name} field
774     * matches {@code 'name'}
775     * 
776     * @param methodName The name of the {@code Method}
777     * 
778     * @return An instance of {@code Stream<Method>}of all {@code Method's} named {@code 'name'}
779     * 
780     * @see #methods
781     * @see Method#name
782     */
783    public Stream<Method> findMethods(String methodName)
784    {
785        Stream.Builder<Method> b = Stream.builder();
786        for (Method method : methods) if (method.name.equals(methodName)) b.accept(method);
787        return b.build();
788    }
789
790    /**
791     * Returns all internally-stored {@code Constructor} instances for instances whose accepted
792     * parameters-list has a length equal to {@code numParameters}.
793     * 
794     * @param numParameters The number of parameters accepted by the {@code Constructor} being
795     * searched.
796     * 
797     * @return An instance of {@code Stream<Constructor>} containing all {@code Constructor's}
798     * whose number of parameterss equals {@code 'numParameters'}
799     * 
800     * @see #constructors
801     * @see Constructor#numParameters()
802     */
803    public Stream<Constructor> findConstructors(int numParameters)
804    {
805        Stream.Builder<Constructor> b = Stream.builder();
806
807        for (Constructor constructor : constructors)
808            if (constructor.numParameters() == numParameters)
809                b.accept(constructor);
810
811        return b.build();
812    }
813
814    /**
815     * <EMBED CLASS=defs DATA-DECL=Field>
816     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_FIND_N_DESC>
817     * @param name The name of the {@code Field}
818     * @return <EMBED CLASS='external-html' DATA-FILE-ID=PF_FIND_N_RET>
819     * @see Declaration#name
820     * @see #fields
821     */
822    public Field findField(String name)
823    {
824        for (Field field : fields) if (field.name.equals(name)) return field;
825        return null;
826    }
827
828    /**
829     * <EMBED CLASS=defs DATA-DECL=AnnotationElem DATA-KIND=annotation>
830     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_FIND_N_DESC>
831     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_NOT_POSSIBLE>
832     * @param name The name of the {@code AnnotationElem}
833     * @return <EMBED CLASS='external-html' DATA-FILE-ID=PF_FIND_N_RET>
834     * @see Declaration#name
835     * @see #annotationElems
836     */
837    public AnnotationElem findAnnotationElem(String name)
838    {
839        for (AnnotationElem ae : annotationElems) if (ae.name.equals(name)) return ae;
840        return null;
841    }
842
843    /**
844     * <EMBED CLASS=defs DATA-DECL=EnumConstant DATA-KIND=enum>
845     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_FIND_N_DESC>
846     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_NOT_POSSIBLE>
847     * @param name The name of the {@code EnumConstant}
848     * @return <EMBED CLASS='external-html' DATA-FILE-ID=PF_FIND_N_RET>
849     * @see Declaration#name
850     * @see #enumConstants
851     */
852    public EnumConstant findEnumConstant(String name)
853    {
854        for (EnumConstant ec : enumConstants) if (ec.name.equals(name)) return ec;
855        return null;
856    }
857
858    /**
859     * <EMBED CLASS=defs DATA-DECL=NestedType>
860     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_FIND_N_DESC>
861     * @param name The name of the {@code NestedType}
862     * @return <EMBED CLASS='external-html' DATA-FILE-ID=PF_FIND_N_RET>
863     * @see Declaration#name
864     * @see #nestedTypes
865     */
866    public NestedType findNestedType(String name)
867    {
868        for (NestedType nt : nestedTypes) if (nt.name.equals(name)) return nt;
869        return null;
870    }
871
872
873    // ********************************************************************************************
874    // ********************************************************************************************
875    // toString()
876    // ********************************************************************************************
877    // ********************************************************************************************
878
879
880    /**
881     * Turns a {@code ParsedFile} result object, {@code 'this'}, into a {@code String}.  Passes
882     * {@code '0'} to the standard flags-print method.
883     */
884    public String toString() { return toString(0); }
885
886    /**
887     * Turns a {@code ParsedFile} result object, {@code 'this'}, into a {@code java.lang.String}.
888     * 
889     * <BR /><BR />This will check for the {@code 'UNIX_COLORS'} flag in {@code class PF}.  If this
890     * flag is  identified, then a few unix color codes are added to the output.
891     * 
892     * <BR /><BR /><B><SPAN STYLE="color: red;">IMPORTANT NOTE:</B></SPAN> The value of this flag
893     * will be propagated to the individual {@code toString(int flag)} methods in each of the 
894     * {@code Method, Field, Constructor} etc... - {@code toString(flag)} methods.
895     * 
896     * @return This returns a {@code String} that obeys the flag-requests by parameter flag.
897     * @see Method#toString(int)
898     * @see Constructor#toString(int)
899     * @see Field#toString(int)
900     */
901    public String toString(int flags)
902    {
903        StringBuilder   sb  = new StringBuilder();
904        boolean         c   = (flags & PF.UNIX_COLORS) > 0;
905
906        StringBuilder typeParamsSB = new StringBuilder();
907        for (String p : genericParameters) typeParamsSB.append(p + ", ");
908
909        String typeParamsStr = (typeParamsSB.length() > 0)
910            ? typeParamsSB.subSequence(0, typeParamsSB.length() - 1).toString()
911            : "-";
912
913        StringBuilder containerClassesSB = new StringBuilder();
914        for (String p : containerClasses) containerClassesSB.append(p + ", ");
915
916        String containerClassesStr = (containerClassesSB.length() > 0)
917            ? containerClassesSB.subSequence(0, containerClassesSB.length() - 1).toString()
918            : "-";
919    
920        sb.append(
921            "******************************************************************\n" +
922            "Fields in this 'ParsedFile' instance:\n"                              +
923            "******************************************************************\n" +
924            "fileName:             " + fileName + '\n' +
925            "name:                 " + name + '\n' +
926            "CIET:                 " + ciet + '\n' +
927            "packageName:          " + packageName + '\n' +
928            "simpleName:           " + simpleName + '\n' +
929            "fullyQualifedName:    " + fullyQualifiedName + '\n' +
930            "isGeneric:            " + isGeneric + '\n' +
931            "Type Parameters:      " + typeParamsStr + '\n' +
932            "isInner:              " + isInner + '\n' +
933            "Container Classes:    " + containerClassesStr + "\n\n"
934        );
935
936        if (methods.size() > 0)
937        {
938            sb.append(  "******************************************************************\n" + 
939                        (c ? BRED : "") + "Methods:\n" + (c ? RESET : "") +
940                        "******************************************************************\n"  );
941
942            for (Method m : methods) sb.append(m.toString(flags) + "\n\n");
943        }
944
945        if (constructors.size() > 0)
946        {
947            sb.append(  "******************************************************************\n" + 
948                        (c ? BRED : "") + "Constructors:\n" + (c ? RESET : "") +
949                        "******************************************************************\n"  );
950
951            for (Constructor cs : constructors)  sb.append(cs.toString(flags) + "\n\n");
952        }
953
954        if (fields.size() > 0)
955        {
956            sb.append(  "******************************************************************\n" + 
957                        (c ? BRED : "") + "Fields:\n" + (c ? RESET : "") +
958                        "******************************************************************\n"  );
959
960            for (Field f : fields) sb.append(f.toString(flags) + "\n\n");
961        }
962
963        if (annotationElems.size() > 0)
964        {
965            sb.append(  "******************************************************************\n" + 
966                        (c ? BRED : "") + "Annotation-Elements:\n" + (c ? RESET : "") +
967                        "******************************************************************\n"  );
968
969            for (AnnotationElem ae : annotationElems) sb.append(ae.toString(flags) + "\n\n");
970        }
971
972        if (enumConstants.size() > 0)
973        {
974            sb.append(  "******************************************************************\n" + 
975                        (c ? BRED : "") + "Enumerated Constants:\n" + (c ? RESET : "") +
976                        "******************************************************************\n"  );
977
978            for (EnumConstant ec : enumConstants) sb.append(ec.toString(flags) + "\n\n");
979        }
980
981        if (nestedTypes.size() > 0)
982        {
983            sb.append(  "******************************************************************\n" + 
984                        (c ? BRED : "") + "Nested Types:\n" + (c ? RESET : "") +
985                        "******************************************************************\n"  );
986
987            for (NestedType nt : nestedTypes) sb.append(nt.toString(flags) + "\n\n");
988        }
989
990        return sb.toString();
991    }
992
993    /**
994     * Provides a Quick Summary for this file.
995     * 
996     * @return The summary as a {@code java.lang.String}.  Nothing is actually printed by this
997     * method.
998     */
999    public String quickSummary()
1000    {
1001        String typeParams = (genericParameters.size() == 0)
1002            ? ""
1003            : ("Generic Type-Parameters: " + 
1004                StrCSV.toCSV(getGenericParameters(), true, true, null) + '\n');
1005
1006        String ae = (annotationElems.size() == 0)
1007            ? ""
1008            : (", [" + BBLUE + StringParse.zeroPad(annotationElems.size()) + RESET +
1009                "] Annotation-Elements");
1010
1011        String ec = (enumConstants.size() == 0)
1012            ? ""
1013            : (", [" + BBLUE + StringParse.zeroPad(enumConstants.size()) + RESET +
1014                "] Enum-Constants");
1015
1016        String nt = (nestedTypes.size() == 0)
1017            ? ""
1018            : (", [" + BBLUE + StringParse.zeroPad(nestedTypes.size()) + RESET +
1019                "] Nested-Types");
1020    
1021        return
1022            "Name ["        + BYELLOW + name                  + RESET + "], " + 
1023            "Package ["     + BYELLOW + packageName           + RESET + "], " +
1024            "CIET ["        + BYELLOW + ciet                  + RESET + "]\n" +
1025            "Qualified ["   + BYELLOW + fullyQualifiedName    + RESET + "], " +
1026            "Simple ["      + BYELLOW + simpleName            + RESET + "]\n" +
1027            typeParams +
1028            '[' + BBLUE + StringParse.zeroPad(fields.size())          + RESET + "] Fields, " +
1029            '[' + BBLUE + StringParse.zeroPad(constructors.size())    + RESET + "] Constructors, " +
1030            '[' + BBLUE + StringParse.zeroPad(methods.size())         + RESET + "] Methods" +
1031            ae + ec + nt + '\n';
1032    }
1033
1034    /**
1035     * Provides a Vertical-List Abbreviated Summary for this file.
1036     * 
1037     * @param lineWidth The number of characters wide the member-summary lines should be.
1038     * @return The summary as a {@code java.lang.String}.  Nothing is actually printed by this
1039     * method.
1040     */
1041    public String abbreviatedSummary(int lineWidth)
1042    {
1043        String typeParams = (genericParameters.size() == 0)
1044            ? ""
1045            : ("Generic Type-Parameters: " + 
1046                StrCSV.toCSV(getGenericParameters(), true, true, null) + '\n');
1047
1048        String m = (methods.size() == 0)
1049            ? "Methods: *NONE*\n"
1050            : ("Methods:" + StrPrint.printListAbbrev
1051                (methods, lineWidth, 4, false, true, true) + '\n');
1052
1053        String f = (fields.size() == 0)
1054            ? "Fields: *NONE*\n"
1055            : ("Fields:" + StrPrint.printListAbbrev
1056                (fields, lineWidth, 4, false, true, true) + '\n');
1057
1058        String c = (constructors.size() == 0)
1059            ? "Constructors: *NONE*\n"
1060            : ("Constructors:" + StrPrint.printListAbbrev
1061                (constructors, lineWidth, 4, false, true, true) + '\n');
1062    
1063        String ec = (enumConstants.size() == 0)
1064            ? ""
1065            : ("Enum-Constants:" + StrPrint.printListAbbrev
1066                (enumConstants, lineWidth, 4, false, true, true) + '\n');
1067    
1068        String ae = (annotationElems.size() == 0)
1069            ? ""
1070            : ("Annotation-Elements:" + StrPrint.printListAbbrev
1071                (annotationElems, lineWidth, 4, false, true, true) + '\n');
1072
1073        String nt = (nestedTypes.size() == 0)
1074            ? ""
1075            : ('[' + BBLUE + StringParse.zeroPad(nestedTypes.size()) + RESET +
1076                "] Nested-Types");
1077    
1078        return
1079            "Name      [" + BYELLOW + name                  + RESET + "]\n" + 
1080            "Package   [" + BYELLOW + packageName           + RESET + "]\n" +
1081            "CIET      [" + BYELLOW + ciet                  + RESET + "]\n" +
1082            "Qualified [" + BYELLOW + fullyQualifiedName    + RESET + "]\n" +
1083            "Simple    [" + BYELLOW + simpleName            + RESET + "]\n" +
1084            typeParams +
1085            m + f + c + ec + ae + nt + '\n';
1086    }
1087}