001package Torello.JavaDoc.Messager;
002
003import static Torello.Java.C.*;
004import static Torello.JavaDoc.Messager.Where_Am_I.LABEL_COLOR;
005
006import Torello.Java.UnreachableError;
007import Torello.JavaDoc.Declaration;
008
009/**
010 * This is an internally used class that handles the Text-Generation for the Error-Message Headers.
011 * <BR /><BR /><EMBED CLASS='external-html' DATA-FILE-ID=PRINT_HEADING>
012 */
013public class PrintHeading
014{
015    // ********************************************************************************************
016    // ********************************************************************************************
017    // Constructor & Field
018    // ********************************************************************************************
019    // ********************************************************************************************
020
021
022    private final PrintRecord printRecord;
023
024    PrintHeading(final PrintRecord printRecord)
025    { this.printRecord = printRecord; }
026
027
028    // ********************************************************************************************
029    // ********************************************************************************************
030    // This class *ONLY* public (well, actually, "Package-Private") method
031    // ********************************************************************************************
032    // ********************************************************************************************
033
034
035    void printHeadingIfNecessary(final Where_Am_I WHERE_AM_I)
036    {
037        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
038        // Print the Heading - File-Name & "Maybe" the Refl-Name
039        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
040
041        final boolean printedTheHeadingMomentsAgo;
042
043        if (this.printRecord.modeFileAndProc())
044            printedTheHeadingMomentsAgo = this.printFileHeadingIfNecessary();
045
046        else if (this.printRecord.modeFileProcAndDecl())
047            printedTheHeadingMomentsAgo = this.printDeclarationHeadingIfNecessary();
048
049        else throw new UnreachableError();
050
051        final boolean mustPrintProcessorName =
052                printedTheHeadingMomentsAgo
053            ||  this.printRecord.whereAmIChanged(WHERE_AM_I);
054
055
056        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
057        // Print the Processor and / or the Sub-Processor (Where_Am_I)
058        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
059
060        final int indentation = this.printRecord.getIndentation();
061
062        // POINT-OF-INTEREST: This is the only line **anywhere** inside this entire giant project
063        // that invokes 'messagerString'
064        // 
065        // FINALLY: NOTE THERE IS A '-4' == PROC-HEADING is "-4" !!!
066
067        if (mustPrintProcessorName) this.printRecord.sb
068            .append(WHERE_AM_I.messagerString(indentation - 4))
069            .append('\n');
070
071        this.printRecord.setPreviouseWhereAmI(WHERE_AM_I);
072    }
073
074
075    // ********************************************************************************************
076    // ********************************************************************************************
077    // TWO PRIVATE METHODS
078    // ********************************************************************************************
079    // ********************************************************************************************
080
081
082    // RETURNS: TRUE or FALSE dependant on whether the File-Name was printed
083    private boolean printFileHeadingIfNecessary()
084    {
085        if (this.printRecord.alreadyPrintedFileName())
086
087            // FALSE  ==>  The file heading was **NOT** printed!
088            return false;
089
090        this.printRecord.printingFileNameRightNow();
091
092
093        // There is at least one location where the "setCurrentFileName" sets a Directory
094        // The text that this messager prints when the 'Messager.setCurrentFileName' ends with 
095        // the System File-Separator is slightly different than it is for a file.
096
097        final String fileOrDir  = this.printRecord.isFileOrDir();
098        final String i          = this.printRecord.fodIndentation();
099
100        this.printRecord.sb.append(
101            this.printRecord.VERBOSITY_LEVEL_NEW_LINE +
102            LABEL_COLOR + " Processing" + fileOrDir + RESET + ' ' +
103            '[' + BYELLOW + this.printRecord.getFileName() + RESET + "]\n" +
104            ((this.printRecord.getFileNameKind() != null)
105                ? (i + this.printRecord.getFileNameKind() + '\n')
106                : "") + 
107            '\n'
108        );
109
110        // TRUE  ==>  The file heading was just printed!
111        return true;
112    }
113
114    // RETURNS: TRUE or FALSE dependant on whether the Detail-Information was printed
115    private boolean printDeclarationHeadingIfNecessary()
116    {
117        printFileHeadingIfNecessary();
118
119        final Declaration declaration = this.printRecord.getDeclaration();
120
121        if (this.printRecord.alreadyPrintedDecl())
122
123            // FALSE  ==>  The detail heading was **NOT** printed!
124            return false;
125
126        this.printRecord.printingFirstDeclRightNow();
127
128        if (this.printRecord.topDescriptionAsDecl()) this.printRecord.sb.append(
129            "    " + LABEL_COLOR + " Processing " + RESET +
130            " [" + BCYAN + "Main CIET/Type Description, at top" + RESET + "]\n" + 
131            '\n'
132        );
133
134
135        else
136        {
137            // This check was added when the class "Location" was built.  It is very much unknown
138            // how important this null-check is.  Remember that an 'UnreachableError' is always
139            // better than a null-pointer exception.
140
141            if (    (declaration == null)
142                ||  (declaration.location == null)
143            )
144                throw new UnreachableError();
145
146
147            final String ln1 = (declaration.location.signatureStartLine != -1)
148                ? (
149                    BCYAN + "Signature Line" + RESET +
150                    ": [" + BGREEN + declaration.location
151                        .signatureStartLine +
152                    RESET + "]"
153                )
154                : null;
155
156            final String ln2 = (declaration.location.jdcStartLine != -1)
157                ? (
158                    BCYAN + "JavaDoc Start Line" + RESET +
159                    ": [" + BGREEN + declaration.location.jdcStartLine +
160                    RESET + "]"
161                )
162                : null;
163
164
165            final String line;
166
167            if (ln1 != null)        line = ln1 + ((ln2 != null) ? (", " + ln2) : "");
168            else if (ln2 != null)   line = ln2;
169            else                    line = "";
170
171
172            this.printRecord.sb.append(
173                "    " + LABEL_COLOR + " Processing " + RESET + ' ' +
174                    BCYAN + declaration.entity.toString() + RESET +
175                    " Details Section " +
176                "for " + declaration.entity.toString() +
177                " [" + BRED + declaration.name + RESET + "], " +
178                line + '\n' +
179                '\n'
180            );
181        }
182
183        // TRUE  ==>  The Detail-Heading Message was printed
184        return true;
185    }
186
187}