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.Annotations.TypeAnnotations.Mirror.TypeAnnotationMirrors;
015import Torello.JDUInternal.Parse.HTML.Other.CallableSignature;
016
017import Torello.Java.ReadOnly.ReadOnlyList;
018import Torello.Java.ReadOnly.ReadOnlyArrayList;
019
020/**
021 * Parent-class of {@link JavaDocHTMLFile} and the source-code parsing classes.
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    private static final ReadOnlyList<String> EMPTY_RO_LIST = ReadOnlyList.of();
030
031
032    // ********************************************************************************************
033    // ********************************************************************************************
034    // Constructor
035    // ********************************************************************************************
036    // ********************************************************************************************
037
038
039    // This constructor is an "almost" zero-work constructor.  It merely accepts many parameters
040    // and then initializes this class fields with those parameter values.
041    // Subclasses should use this constructor to initialize these fields.
042    //
043    // The follopwing two classes inherit this class:
044    //
045    //  Torello.JavaDoc.JavaDocHTMLFile
046    //  Torello.JDUInternal.Parse.Java.JSCF.JavaSourceCodeFile
047
048    protected ParsedFile(
049            final String fileName,
050
051            final String                simpleNameWithContainersAndGenerics,
052            final String                packageName,
053            final CIET                  ciet,
054            final ReadOnlyList<String>  genericParameters,
055            final String                fullNameNoGenerics,
056            final String                typeNameJOW,
057
058            final int startLineNumber,
059            final int endLineNumber,
060            final int jdStartLineNumber,
061            final int jdEndLineNumber,
062            final int typeLineCount,
063            final int typeSizeChars,
064
065            final String javaSrcFileAsStr,
066
067            final ReadOnlyList<Method>          methods,
068            final ReadOnlyList<Field>           fields,
069            final ReadOnlyList<Constructor>     constructors,
070            final ReadOnlyList<EnumConstant>    enumConstants,
071            final ReadOnlyList<AnnotationElem>  annotationElems,
072            final ReadOnlyList<NestedType>      nestedTypes
073        )
074    {
075        this.fileName                               = fileName;
076        this.simpleNameWithContainersAndGenerics    = simpleNameWithContainersAndGenerics;
077        this.packageName                            = packageName;
078        this.ciet                                   = ciet;
079        this.genericParameters                      = genericParameters;
080        this.fullNameNoGenerics                     = fullNameNoGenerics;
081
082        this.simpleNameWithPossibleContainers =
083            simpleNameWithContainersAndGenerics.replaceFirst("<.*>", "");
084
085        this.isInner =
086            this.simpleNameWithPossibleContainers.indexOf(".") != -1;
087
088        this.typeNameJOW    = typeNameJOW;
089        this.isGeneric      = genericParameters.size() > 0;
090
091        this.startLineNumber    = startLineNumber;
092        this.endLineNumber      = endLineNumber;
093        this.jdStartLineNumber  = jdStartLineNumber;
094        this.jdEndLineNumber    = jdEndLineNumber;
095        this.typeLineCount      = typeLineCount;
096        this.typeSizeChars      = typeSizeChars;
097
098        this.javaSrcFileAsStr   = javaSrcFileAsStr;
099
100        this.methods            = methods;
101        this.fields             = fields;
102        this.constructors       = constructors;
103        this.annotationElems    = annotationElems;
104        this.enumConstants      = enumConstants;
105        this.nestedTypes        = nestedTypes;
106
107        // To get the container classes, just split on the period.
108        String[] classes = this.simpleNameWithPossibleContainers.split(".");
109
110        // This removes the very-last element resulting from the split.
111        this.containerClasses = (classes.length > 1)
112            ? new ReadOnlyArrayList<>(classes)
113            : EMPTY_RO_LIST;
114    }
115
116
117    // ********************************************************************************************
118    // ********************************************************************************************
119    // Annotation-Mirror class
120    // ********************************************************************************************
121    // ********************************************************************************************
122
123
124    // @StaticFunctional and @JDHeaderBackgroundImg - saves all the info from those Annotations
125    // EXPORT_PORTAL method: Used by MainFilesProcessor.PART_TWO_Do_The_Rest
126    // This is not a 'public' field, because the information it contains is **ONLY** the info that
127    // was collected from those two annotations - NOT ALL ANNOTATIONS!
128    //
129    // That information is mostly totally useless to the end user.
130
131    /**
132     * Stores information provided by the JavaDoc Upgrader Annotations.  Note, this Annotation
133     * Mirror does not contain information about any / all annotations used inside of Java Source
134     * Code Files, but rather only the ones created by this API.
135     *
136     * <BR /><BR />These include <B STYLE='color: blue'>{@code @StaticFunctional}</B> and also
137     * <B STYLE='color: blue'>{@code @JDHeaderBackgroundImg}</B>
138     */
139    protected TypeAnnotationMirrors typeAnnotationMirrors = null;
140
141
142    // ********************************************************************************************
143    // ********************************************************************************************
144    // Main String-Data Stuff
145    // ********************************************************************************************
146    // ********************************************************************************************
147
148
149    /**
150     * This field simply contains the entire contents of the {@code '.java'} Source-Code File from
151     * whence this {@code ParsedFile} instance originated.
152     * 
153     * <BR /><BR />Note that for in for the sub-class {@link JavaDocHTMLFile}, when the HTML file
154     * which was parsed represents an inner-class / nested-type, this field will still contain the
155     * entire contents of the top-level enclosing java type (as a {@code String}) in this field.
156     * 
157     * <BR /><BR />For instance, if a {@link JavaDocHTMLFile} (which inherits this class,
158     * {@code ParsedFile}) instance had been generated for the Java-HTML inner-class
159     * {@code Torello.HTML.Attributes.Filter}, which happens to be a nested type of class
160     * {@code Torello.HTML.Attributes}, this field would contain the text-characters of the
161     * Source-File {@code Torello/HTML/Attributes.java} in {@code String}-format (as character
162     * data).
163     */
164    public final String javaSrcFileAsStr;
165
166    /** Contains the file-name from which this instance was derived */
167    public final String fileName;
168
169    /**
170     * Holds the name of a Class / CIET / Type.  A {@code 'ParsedFile'} represents a class,
171     * interface, or enumerated-type.  This name stored in this field <B>IS NOT</B> the
172     * fully-qualified (Package-Name information included) name.  The Java-Package in which this
173     * Class or Type resides isn't incorporated into the name stored in this field.
174     * 
175     * <BR /><BR />This {@code String}-Field <B><I>will have any &amp; all Generic Type Parameters
176     * appended to its name</I></B> - if this CIET represents a generic with such Type-Parameters.
177     * 
178     * <BR /><BR />If this {@code CIET}/Type represents a Nested-Class / Inner-Type, <I>the names 
179     * of the containing {@code CIET} / Types are included</I> in this {@code String}-Field.
180     * 
181     * <BR /><BR /><TABLE CLASS=JDBriefTable>
182     * <TR>
183     *      <TH>Output Value</TH>
184     *      <TH>Input {@code CIET} / Type</TH>
185     *      </TR>
186     * <TR>
187     *      <TD>{@code "Integer"}</TD>
188     *      <TD>interface {@code java.lang.Integer}</TD>
189     *      </TR>
190     * <TR>
191     *      <TD>{@code "Vector<E>"}</TD>
192     *      <TD>class {@code java.util.Vector<E>}</TD>
193     *      </TR>
194     * <TR>
195     *      <TD>{@code "Base.Decoder"}</TD>
196     *      <TD>class {@code java.util.Base64.Decoder}</TD>
197     *      </TR>
198     * <TR>
199     *      <TD>{@code "Map.Entry<K, V>"}</TD>
200     *      <TD>interface {@code java.util.Map.Entry<K, V>}</TD>
201     *      </TR>
202     * </TABLE>
203     */
204    public final String simpleNameWithContainersAndGenerics;
205
206    /**
207     * This {@code String}-Field holds the <I>fully qualified {@code CIET} name</I> - which simply
208     * means that any Java-Package information that is available shall be included in the name that
209     * is stored in this field.  By implication, if the Package-Name is stored, then this
210     * {@code String}-Field must also hold any Container-Class names for this CIET/Type - in cases 
211     * where this type is, indeed, a nested or inner type.
212     * 
213     * <BR /><BR />If this {@code CIET}-Type happens to be a Java Generic with Generic Type
214     * Parameters (the {@code 'E'} in type {@code java.util.Vector<E>}, this information <B>WILL
215     * NOT</B> include that text stored within this {@code String}-Field. 
216     * 
217     * <BR /><TABLE CLASS=JDBriefTable>
218     * <TR>
219     *      <TH>Output Value</TH>
220     *      <TH>Input {@code CIET} / Type</TH>
221     *      </TR>
222     * <TR>
223     *      <TD>{@code "java.lang.Integer"}</TD>
224     *      <TD>interface {@code java.lang.Integer}</TD>
225     *      </TR>
226     * <TR>
227     *      <TD>{@code "java.util.Vector"}</TD>
228     *      <TD>class {@code java.util.Vector<E>}</TD>
229     *      </TR>
230     * <TR>
231     *      <TD>{@code "java.util.Base64.Decoder"}</TD>
232     *      <TD>class {@code java.util.Base64.Decoder}</TD>
233     *      </TR>
234     * <TR>
235     *      <TD>{@code "java.util.Map.Entry"}</TD>
236     *      <TD>interface {@code java.util.Map.Entry<K, V>}</TD>
237     *      </TR>
238     * </TABLE>
239     */
240    public final String fullNameNoGenerics;
241
242    /**
243     * This the same as the {@link #simpleNameWithContainersAndGenerics} field, but leaves off
244     * the Generic Type-Parameter {@code String's}.  If this class is representing a {@code CIET}
245     * Type that happens to be a Nested-Type / Inner-Class, then the containing {@code CIET}
246     * name(s) <B>ARE</B> included in this {@code String}-Field.
247     * 
248     * <BR /><TABLE CLASS=JDBriefTable>
249     * <TR>
250     *      <TH>Output Value</TH>
251     *      <TH>Input {@code CIET} / Type</TH>
252     *      </TR>
253     * <TR>
254     *      <TD>{@code "Integer"}</TD>
255     *      <TD>interface {@code java.lang.Integer}</TD>
256     *      </TR>
257     * <TR>
258     *      <TD>{@code "Vector"}</TD>
259     *      <TD>class {@code java.util.Vector<E>}</TD>
260     *      </TR>
261     * <TR>
262     *      <TD>{@code "Base64.Decoder"}</TD>
263     *      <TD>class {@code java.util.Base64.Decoder}</TD>
264     *      </TR>
265     * <TR>
266     *      <TD>{@code "Map.Entry"}</TD>
267     *      <TD>interface {@code java.util.Map.Entry<K, V>}</TD>
268     *      </TR>
269     * </TABLE>
270     */
271    public final String simpleNameWithPossibleContainers;
272
273    /**
274     * <B CLASS=JDDescLabel>JOW: Just One Word</B>
275     * 
276     * <BR />The Java-Doc Upgrader utilizes a few naming conventions, one of which is that any 
277     * time the acronym {@code 'JOW'} is used, it is intending to provide a name to a Java-Type.
278     * Since there isn't an exact consensus on what information should be included in a Type-Name,
279     * the {@code 'JOW'} Acronym simply implies that the <B STYLE='color: red;'><I>simplest name 
280     * possible</I></B> (a single word name) is being stored in this field.
281     * 
282     * <BR /><BR />If this name is representing a {@code CIET}-Type that happens to be a
283     * Java-Generic, and having Generic-Type Parameters, such {@code String}-Text <B>WILL NOT</B>
284     * be included in this {@code String}-Field.
285     * 
286     * <BR /><BR />If this name is representing a {@code CIET}-Type that happens to be a
287     * Nested-Type / Inner-Class, then the containing {@code CIET} name(s)
288     * <B>ARE NOT</B> included in this {@code String}-Field.
289     * 
290     * <BR /><BR />Package-Name information will also not be stored in this field.
291     * 
292     * <BR /><TABLE CLASS=JDBriefTable>
293     * <TR>
294     *      <TH>Output Value</TH>
295     *      <TH>Input {@code CIET} / Type</TH>
296     *      </TR>
297     * <TR>
298     *      <TD>{@code "Integer"}</TD>
299     *      <TD>interface {@code java.lang.Integer}</TD>
300     *      </TR>
301     * <TR>
302     *      <TD>{@code "Vector"}</TD>
303     *      <TD>class {@code java.util.Vector<E>}</TD>
304     *      </TR>
305     * <TR>
306     *      <TD>{@code "Decoder"}</TD>
307     *      <TD>class {@code java.util.Base64.Decoder}</TD>
308     *      </TR>
309     * <TR>
310     *      <TD>{@code "Entry"}</TD>
311     *      <TD>interface {@code java.util.Map.Entry<K, V>}</TD>
312     *      </TR>
313     * </TABLE>
314     */
315    public final String typeNameJOW;
316
317    /**
318     * Holds the package-name.  If this {@code ParsedFile} were for class {@code java.lang.String}
319     * the {@code 'packageName'} would be {@code 'java.lang'}.
320     */
321    public final String packageName;
322
323
324    // ********************************************************************************************
325    // ********************************************************************************************
326    // The Additional Stuff
327    // ********************************************************************************************
328    // ********************************************************************************************
329
330
331    /**
332     * The acronym 'CIET' simply means "Class, Interface or Enumerated-Type.  This public field
333     * identifies whether this {@code ParsedFile} is for a class, an interface or an enumerated-type.
334     */
335    public final CIET ciet;
336
337    /**
338     * This identifies inner classes and interfaces.
339     * 
340     * <BR /><TABLE CLASS=JDBriefTable>
341     * <TR> <TH>{@code 'isInner'} Field Value</TH>
342     *      <TH>Input {@code CIET}</TH>
343     *      </TR>
344     * <TR> <TD>{@code false}</TD>
345     *      <TD>interface {@code java.lang.Integer}</TD>
346     *      </TR>
347     * <TR> <TD>{@code false}</TD>
348     *      <TD>class {@code java.util.Vector<E>}</TD>
349     *      </TR>
350     * <TR> <TD>{@code true}</TD>
351     *      <TD>class {@code java.util.Base64.Decoder}</TD>
352     *      </TR>
353     * <TR> <TD>{@code true}</TD>
354     *      <TD>interface {@code java.util.Map.Entry<K, V>}</TD>
355     *      </TR>
356     * </TABLE>
357     */
358    public final boolean isInner;
359
360    /**
361     * This identifies inner classes and interfaces.  For any class that is not an inner class,
362     * this will be a zero-length {@code String[]} array.
363     * 
364     * <BR /><TABLE CLASS=JDBriefTable>
365     * <TR> <TH>{@code 'containerClasses'} Value</TH>
366     *      <TH>Input {@code CIET}</TH>
367     *      </TR>
368     * <TR> <TD><CODE>&lt;EMPTY-LIST&gt;</CODE></TD>
369     *      <TD>interface {@code java.lang.Integer}</TD>
370     *      </TR>
371     * <TR> <TD><CODE>&lt;EMPTY-LIST&gt;</CODE></TD>
372     *      <TD>class {@code java.util.Vector<E>}</TD>
373     *      </TR>
374     * <TR> <TD><CODE></CODE>&lcub; "Base64" &rcub;</TD>
375     *      <TD>class {@code java.util.Base64.Decoder}</TD>
376     *      </TR>
377     * <TR> <TD><CODE></CODE>&lcub; "Map" &rcub;</TD>
378     *      <TD>interface {@code java.util.Map.Entry<K, V>}</TD>
379     *      </TR>
380     * </TABLE>
381     */
382    public final ReadOnlyList<String> containerClasses;
383
384
385    /**
386     * This field will be {@code TRUE} anytime the {@link #genericParameters} field has
387     * any elements.
388     */
389    public final boolean isGeneric;
390
391    /**
392     * If this represents a Java <B>Generic Class or Interface</B>, with generic type information,
393     * the generic type parameters shall be saved here.
394     */
395    public final ReadOnlyList<String> genericParameters;
396
397
398    /**
399     * The line-number in the source-code file where this class definition actually begins.
400     * 
401     * <BR /><BR />Note that if this instance of {@code ParsedFile} is representing a Nessted-Type
402     * / Inner-Class, then this field will contain the line-number where that inner-type's
403     * definition begins inside the Enclosing-Class' {@code '.java'} file.
404     */
405    public final int startLineNumber;
406
407    /**
408     * The line-number in the source-code file where this class definition ends.  Often this will
409     * just be the line-number of the last line in the {@code '.java'} file.
410     * 
411     * <BR /><BR />If this is a Nested-Type, this field will contain the line-number where the
412     * definition of the Nested-type ends.
413     */
414    public final int endLineNumber;
415
416    /**
417     * The starting line-number of the JavaDoc Comment at the top of the class.  If this class
418     * does not have a Java-Doc Comment, this field will contain {@code -1}.
419     */
420    public final int jdStartLineNumber;
421
422    /**
423     * The endiing line-number of the JavaDoc Comment at the top of the class.  If this class does
424     * not have a Java-Doc Comment, this field will contain {@code -1}.
425     */
426    public final int jdEndLineNumber;
427
428    /**
429     * The number of lines of Source-Code inside this {@code '.java'} File.  If this instance of
430     * {@code ParsedFile} represents an Inner-Type (Nested-Class), then this field will contain 
431     * a value that corresponds only to the number of lines used by the Nested-Type within the
432     * context of the entire Enclosing-Class {@code '.java'} file.
433     */
434    public final int typeLineCount;
435
436    /**
437     * The number of characters / bytes of Source-Code inside this {@code '.java'} File.  If this
438     * instance of {@code ParsedFile} represents an Inner-Type (Nested-Class), then this field will
439     * contain a value that corresponds only to the number of characters / bytes used by the
440     * Nested-Type within the context of the entire Enclosing-Class {@code '.java'} file.
441     */
442    public final int typeSizeChars;
443
444
445    // ********************************************************************************************
446    // ********************************************************************************************
447    // Members
448    // ********************************************************************************************
449    // ********************************************************************************************
450
451
452    /**
453     * This is the list of {@link Method} instances identified by the parser for this
454     * {@code ParsedFile}
455     */
456    public final ReadOnlyList<Method> methods;
457
458    /**
459     * This is the list of {@link Constructor} instances identified by the parser for this
460     * {@code ParsedFile}
461     */
462    public final ReadOnlyList<Constructor> constructors;
463
464
465    /**
466     * This is the list of {@link Field} instances identified by the parser for this
467     * {@code ParsedFile}
468     */
469    public final ReadOnlyList<Field> fields;
470
471    /**
472     * This is the list of {@link AnnotationElem} instances identified by the parser for this
473     * {@code ParsedFile}
474     * <EMBED CLASS=defs DATA-DECL=AnnotationElem DATA-VEC=annotationElems DATA-KIND=annotation>
475     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_NOT_POSSIBLE>
476     */
477    public final ReadOnlyList<AnnotationElem> annotationElems;
478
479    /**
480     * This is the list of {@link EnumConstant} instances identified by the parser for this
481     * {@code ParsedFile}
482     * <EMBED CLASS=defs DATA-DECL=EnumConstant DATA-VEC=enumConstants DATA-KIND=enum>
483     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_NOT_POSSIBLE>
484     * @see #enumConstants
485     */
486    public final ReadOnlyList<EnumConstant> enumConstants;
487
488    /**
489     * This is the list of {@link NestedType} instances identified by the parser for this
490     * {@code ParsedFile}
491     */
492    public final ReadOnlyList<NestedType> nestedTypes;
493
494
495    // ********************************************************************************************
496    // ********************************************************************************************
497    // FIND.
498    // ********************************************************************************************
499    // ********************************************************************************************
500
501
502    /**
503     * Finds a Method having the characteristics specified by parameter {@code 'cSig'}.
504     * 
505     * @param cSig An internally generated representation of a Java-Method extrapolated from the
506     * information available on a Java-Doc HTML Detail Section
507     * 
508     * @return A method that matches the requested Method-Signature
509     */
510    public Method findMethod(CallableSignature cSig)
511    {
512        for (Method method : methods)
513
514            if (    method.name.equals(cSig.name)
515                &&  method.returnTypeJOW.equals(cSig.returnTypeJOW)
516                &&  method.nearlyEqualsCallableSig(cSig)
517            )
518                return method;
519
520        return null;
521    }
522
523    /**
524     * Finds a Constructor having the characteristics specified by parameter {@code 'cSig'}.
525     * 
526     * @param cSig An internally generated representation of a Java-Constructor extrapolated from
527     * the information available on a Java-Doc HTML Detail Section
528     * 
529     * @return A Constructor that matches the requested Constructor-Signature
530     */
531    public Constructor findConstructor(CallableSignature cSig)
532    {
533        for (Constructor ctor : constructors) if (ctor.nearlyEqualsCallableSig(cSig)) return ctor;
534        return null;
535    }
536
537    /**
538     * Returns all internally-stored {@code Method} instances whose {@code Method#name} field
539     * matches {@code 'name'}
540     * 
541     * @param methodName The name of the {@code Method}
542     * 
543     * @return An instance of {@code Stream<Method>}of all {@code Method's} named {@code 'name'}
544     * 
545     * @see #methods
546     * @see Method#name
547     */
548    public Stream<Method> findMethods(String methodName)
549    {
550        Stream.Builder<Method> b = Stream.builder();
551        for (Method method : methods) if (method.name.equals(methodName)) b.accept(method);
552        return b.build();
553    }
554
555    /**
556     * Returns all internally-stored {@code Constructor} instances for instances whose accepted
557     * parameters-list has a length equal to {@code numParameters}.
558     * 
559     * @param numParameters The number of parameters accepted by the {@code Constructor} being
560     * searched.
561     * 
562     * @return An instance of {@code Stream<Constructor>} containing all {@code Constructor's}
563     * whose number of parameterss equals {@code 'numParameters'}
564     * 
565     * @see #constructors
566     * @see Constructor#numParameters()
567     */
568    public Stream<Constructor> findConstructors(int numParameters)
569    {
570        Stream.Builder<Constructor> b = Stream.builder();
571
572        for (Constructor constructor : constructors)
573            if (constructor.numParameters() == numParameters)
574                b.accept(constructor);
575
576        return b.build();
577    }
578
579    /**
580     * <EMBED CLASS=defs DATA-DECL=Field>
581     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_FIND_N_DESC>
582     * @param name The name of the {@code Field}
583     * @return <EMBED CLASS='external-html' DATA-FILE-ID=PF_FIND_N_RET>
584     * @see Declaration#name
585     * @see #fields
586     */
587    public Field findField(String name)
588    {
589        for (Field field : fields) if (field.name.equals(name)) return field;
590        return null;
591    }
592
593    /**
594     * <EMBED CLASS=defs DATA-DECL=AnnotationElem DATA-KIND=annotation>
595     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_FIND_N_DESC>
596     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_NOT_POSSIBLE>
597     * @param name The name of the {@code AnnotationElem}
598     * @return <EMBED CLASS='external-html' DATA-FILE-ID=PF_FIND_N_RET>
599     * @see Declaration#name
600     * @see #annotationElems
601     */
602    public AnnotationElem findAnnotationElem(String name)
603    {
604        for (AnnotationElem ae : annotationElems) if (ae.name.equals(name)) return ae;
605        return null;
606    }
607
608    /**
609     * <EMBED CLASS=defs DATA-DECL=EnumConstant DATA-KIND=enum>
610     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_FIND_N_DESC>
611     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_NOT_POSSIBLE>
612     * @param name The name of the {@code EnumConstant}
613     * @return <EMBED CLASS='external-html' DATA-FILE-ID=PF_FIND_N_RET>
614     * @see Declaration#name
615     * @see #enumConstants
616     */
617    public EnumConstant findEnumConstant(String name)
618    {
619        for (EnumConstant ec : enumConstants) if (ec.name.equals(name)) return ec;
620        return null;
621    }
622
623    /**
624     * <EMBED CLASS=defs DATA-DECL=NestedType>
625     * <EMBED CLASS='external-html' DATA-FILE-ID=PF_FIND_N_DESC>
626     * @param name The name of the {@code NestedType}
627     * @return <EMBED CLASS='external-html' DATA-FILE-ID=PF_FIND_N_RET>
628     * @see Declaration#name
629     * @see #nestedTypes
630     */
631    public NestedType findNestedType(String name)
632    {
633        for (NestedType nt : nestedTypes) if (nt.name.equals(name)) return nt;
634        return null;
635    }
636
637
638    // ********************************************************************************************
639    // ********************************************************************************************
640    // toString()
641    // ********************************************************************************************
642    // ********************************************************************************************
643
644
645    /**
646     * Turns a {@code ParsedFile} result object, {@code 'this'}, into a {@code String}.  Passes
647     * {@code '0'} to the standard flags-print method.
648     */
649    public String toString() { return toString(0); }
650
651    /**
652     * Turns a {@code ParsedFile} result object, {@code 'this'}, into a {@code java.lang.String}.
653     * 
654     * <BR /><BR />This will check for the {@code 'UNIX_COLORS'} flag in {@code class PF}.  If this
655     * flag is  identified, then a few unix color codes are added to the output.
656     * 
657     * <BR /><BR /><B><SPAN STYLE="color: red;">IMPORTANT NOTE:</B></SPAN> The value of this flag
658     * will be propagated to the individual {@code toString(int flag)} methods in each of the 
659     * {@code Method, Field, Constructor} etc... - {@code toString(flag)} methods.
660     * 
661     * @return This returns a {@code String} that obeys the flag-requests by parameter flag.
662     * @see Method#toString(int)
663     * @see Constructor#toString(int)
664     * @see Field#toString(int)
665     */
666    public String toString(int flags)
667    {
668        StringBuilder   sb  = new StringBuilder();
669        boolean         c   = (flags & PF.UNIX_COLORS) > 0;
670
671        StringBuilder typeParamsSB = new StringBuilder();
672        for (String p : genericParameters) typeParamsSB.append(p + ", ");
673
674        String typeParamsStr = (typeParamsSB.length() > 0)
675            ? typeParamsSB.subSequence(0, typeParamsSB.length() - 1).toString()
676            : "-";
677
678        StringBuilder containerClassesSB = new StringBuilder();
679        for (String p : containerClasses) containerClassesSB.append(p + ", ");
680
681        String containerClassesStr = (containerClassesSB.length() > 0)
682            ? containerClassesSB.subSequence(0, containerClassesSB.length() - 1).toString()
683            : "-";
684    
685        sb.append(
686            "******************************************************************\n" +
687            "Fields in this 'ParsedFile' instance:\n"                              +
688            "******************************************************************\n" +
689            "fileName:                             " + fileName + '\n' +
690            "simpleNameWithContainersAndGenerics:  " + simpleNameWithContainersAndGenerics + '\n' +
691            "CIET:                                 " + ciet + '\n' +
692            "packageName:                          " + packageName + '\n' +
693            "simpleNameWithPossibleContainers:     " + simpleNameWithPossibleContainers + '\n' +
694            "fullNameNoGenerics:                   " + fullNameNoGenerics + '\n' +
695            "isGeneric:                            " + isGeneric + '\n' +
696            "Type Parameters:                      " + typeParamsStr + '\n' +
697            "isInner:                              " + isInner + '\n' +
698            "Container Classes:                    " + containerClassesStr + "\n" +
699            "\n" +
700            "fields.size():                        " + fields.size() + '\n' +
701            "methods.size():                       " + methods.size() + '\n' +
702            "constructors.size():                  " + constructors.size() + '\n' +
703            "annotationElems.size():               " + annotationElems.size() + '\n' +
704            "enumConstants.size():                 " + enumConstants.size() + '\n' +
705            "nestedTypes.size():                   " + nestedTypes.size() + "\n\n"
706        );
707
708        if (methods.size() > 0)
709        {
710            sb.append(  "******************************************************************\n" + 
711                        (c ? BRED : "") + "Methods:\n" + (c ? RESET : "") +
712                        "******************************************************************\n"  );
713
714            for (Method m : methods) sb.append(m.toString(flags) + "\n\n");
715        }
716
717        if (constructors.size() > 0)
718        {
719            sb.append(  "******************************************************************\n" + 
720                        (c ? BRED : "") + "Constructors:\n" + (c ? RESET : "") +
721                        "******************************************************************\n"  );
722
723            for (Constructor cs : constructors)  sb.append(cs.toString(flags) + "\n\n");
724        }
725
726        if (fields.size() > 0)
727        {
728            sb.append(  "******************************************************************\n" + 
729                        (c ? BRED : "") + "Fields:\n" + (c ? RESET : "") +
730                        "******************************************************************\n"  );
731
732            for (Field f : fields) sb.append(f.toString(flags) + "\n\n");
733        }
734
735        if (annotationElems.size() > 0)
736        {
737            sb.append(  "******************************************************************\n" + 
738                        (c ? BRED : "") + "Annotation-Elements:\n" + (c ? RESET : "") +
739                        "******************************************************************\n"  );
740
741            for (AnnotationElem ae : annotationElems) sb.append(ae.toString(flags) + "\n\n");
742        }
743
744        if (enumConstants.size() > 0)
745        {
746            sb.append(  "******************************************************************\n" + 
747                        (c ? BRED : "") + "Enumerated Constants:\n" + (c ? RESET : "") +
748                        "******************************************************************\n"  );
749
750            for (EnumConstant ec : enumConstants) sb.append(ec.toString(flags) + "\n\n");
751        }
752
753        if (nestedTypes.size() > 0)
754        {
755            sb.append(  "******************************************************************\n" + 
756                        (c ? BRED : "") + "Nested Types:\n" + (c ? RESET : "") +
757                        "******************************************************************\n"  );
758
759            for (NestedType nt : nestedTypes) sb.append(nt.toString(flags) + "\n\n");
760        }
761
762        return sb.toString();
763    }
764
765    /**
766     * Provides a Quick Summary for this file.
767     * 
768     * @return The summary as a {@code java.lang.String}.  Nothing is actually printed by this
769     * method.
770     */
771    public String quickSummary()
772    {
773        String typeParams = (genericParameters.size() == 0)
774            ? ""
775            : ("Generic Type-Parameters: " + 
776                StrCSV.toCSV(this.genericParameters, true, true, null) + '\n');
777
778        String ae = (annotationElems.size() == 0)
779            ? ""
780            : (", [" + BBLUE + StringParse.zeroPad(annotationElems.size()) + RESET +
781                "] Annotation-Elements");
782
783        String ec = (enumConstants.size() == 0)
784            ? ""
785            : (", [" + BBLUE + StringParse.zeroPad(enumConstants.size()) + RESET +
786                "] Enum-Constants");
787
788        String nt = (nestedTypes.size() == 0)
789            ? ""
790            : (", [" + BBLUE + StringParse.zeroPad(nestedTypes.size()) + RESET +
791                "] Nested-Types");
792    
793        return
794            "Name w/ Containers & Generics [" + BYELLOW + simpleNameWithContainersAndGenerics + RESET + "]\n" + 
795            "Name w/ Any Containers        [" + BYELLOW + simpleNameWithPossibleContainers + RESET + "]\n" +
796            "Name w/ Package-Info          [" + BYELLOW + fullNameNoGenerics + RESET + "]\n" +
797            "Package [" + BYELLOW + packageName + RESET + "]\n" +
798            "CIET    [" + BYELLOW + ciet        + RESET + "]\n" +
799            typeParams +
800            '[' + BBLUE + StringParse.zeroPad(fields.size())          + RESET + "] Fields, " +
801            '[' + BBLUE + StringParse.zeroPad(constructors.size())    + RESET + "] Constructors, " +
802            '[' + BBLUE + StringParse.zeroPad(methods.size())         + RESET + "] Methods" +
803            ae + ec + nt + '\n';
804    }
805
806    /**
807     * Provides a Vertical-List Abbreviated Summary for this file.
808     * 
809     * @param lineWidth The number of characters wide the member-summary lines should be.
810     * @return The summary as a {@code java.lang.String}.  Nothing is actually printed by this
811     * method.
812     */
813    public String abbreviatedSummary(int lineWidth)
814    {
815        String typeParams = (genericParameters.size() == 0)
816            ? ""
817            : ("Generic Type-Parameters: " + 
818                StrCSV.toCSV(this.genericParameters, true, true, null) + '\n');
819
820        String m = (methods.size() == 0)
821            ? "Methods: *NONE*\n"
822            : ("Methods:" + StrPrint.printListAbbrev
823                (methods, lineWidth, 4, false, true, true) + '\n');
824
825        String f = (fields.size() == 0)
826            ? "Fields: *NONE*\n"
827            : ("Fields:" + StrPrint.printListAbbrev
828                (fields, lineWidth, 4, false, true, true) + '\n');
829
830        String c = (constructors.size() == 0)
831            ? "Constructors: *NONE*\n"
832            : ("Constructors:" + StrPrint.printListAbbrev
833                (constructors, lineWidth, 4, false, true, true) + '\n');
834    
835        String ec = (enumConstants.size() == 0)
836            ? ""
837            : ("Enum-Constants:" + StrPrint.printListAbbrev
838                (enumConstants, lineWidth, 4, false, true, true) + '\n');
839    
840        String ae = (annotationElems.size() == 0)
841            ? ""
842            : ("Annotation-Elements:" + StrPrint.printListAbbrev
843                (annotationElems, lineWidth, 4, false, true, true) + '\n');
844
845        String nt = (nestedTypes.size() == 0)
846            ? ""
847            : ('[' + BBLUE + StringParse.zeroPad(nestedTypes.size()) + RESET +
848                "] Nested-Types");
849    
850        return
851            "Name w/ Containers & Generics " +
852                '[' + BYELLOW + simpleNameWithContainersAndGenerics + RESET + "]\n" +
853
854            "Name w/ Any Containers        " +
855                '[' + BYELLOW + simpleNameWithPossibleContainers + RESET + "]\n" +
856
857            "Package-Name Qualified        " +
858                '[' + BYELLOW + fullNameNoGenerics + RESET + "]\n" +
859
860            "Package [" + BYELLOW + packageName           + RESET + "]\n" +
861            "CIET    [" + BYELLOW + ciet                  + RESET + "]\n" +
862
863            typeParams +
864            m + f + c + ec + ae + nt + '\n';
865    }
866}