1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
package Torello.Java.Build;

import Torello.JavaDoc.PackageSummaryHTML;

import Torello.Java.Additional.BiAppendable;

import Torello.Java.FileNode;
import Torello.Java.FileTransfer;
import Torello.Java.Shell;
import Torello.Java.OSResponse;
import Torello.Java.StrPrint;

import Torello.Java.ReadOnly.ReadOnlyList;
import Torello.Java.ReadOnly.ROArrayListBuilder;

import static Torello.Java.C.*;

import java.io.IOException;
import java.io.File;

/**
 * This is the second Build-Stage, and it runs the Standard Java-Doc Tool - using {@code 'javadoc'}
 * and {@link Shell Torello.Java.Shell}.  This class also relies heavily on the Java-HTML Tools
 * {@link FileNode} and {@link FileTransfer}.
 * 
 * <EMBED CLASS='external-html' DATA-FILE-ID=S02_JAVADOC>
 */
@Torello.JavaDoc.StaticFunctional
public class S02_JavaDoc
{
    // Completely irrelevant, and the 'private' modifier keeps it off of JavaDoc
    private S02_JavaDoc() { }


    // ********************************************************************************************
    // ********************************************************************************************
    // Private-Constant
    // ********************************************************************************************
    // ********************************************************************************************


    private static final ReadOnlyList<String> commandSwitches(Builder builder)
    {
        ROArrayListBuilder<String> roalb = new ROArrayListBuilder<>();

        roalb.add("-d");                roalb.add("javadoc");
        roalb.add("-docfilessubdirs");
        roalb.add("-linksource");
        roalb.add("-charset");          roalb.add("UTF-8");
        roalb.add("-docencoding");      roalb.add("UTF-8");
        roalb.add("-encoding");         roalb.add("UTF-8");
        roalb.add("-sourcetab");        roalb.add("4");
        roalb.add("-splitindex");
        roalb.add("-notree");
        roalb.add("-classpath");        roalb.add(builder.CLASS_PATH_STR);

        if ((builder.JAVADOC_VER <= 11) && (! builder.NO_JAVADOC_FRAMES_SWITCH))
            roalb.add("--frames");

        roalb.add("--allow-script-in-comments");  

        if ((builder.JAVADOC_VER == 11) || (builder.JAVADOC_VER == 14))
            roalb.add("--no-module-directories");

        // The <EMBED> tags and <BR />'s break starting in javdoc version 14.
        // For now this says "17" because Google Cloud Server only provides java Version 11 & 17
        // Java 14 is completely missing, so I don't actually now if this is needed for 14!

        if (builder.JAVADOC_VER == 17) roalb.add("-Xdoclint:html");

        // "WebSockets" have @since tags... before "The Refl" was fully working, this was needed
        // "-nosince"
    
        // needed for the search bar !
        // "-overview", "Torello/Build/OverviewSummary.html"

        // This isn't used in Java-HTML, as of January 2024.  However, if there ever arises a need
        // to quickly add / append command-line switches to the `javadoc` command, it is handled
        // right here.

        if ((builder.extraSwitchesJAVADOC != null) && (builder.extraSwitchesJAVADOC.size() > 0))
            for (String switchStr : builder.extraSwitchesJAVADOC)
                roalb.add(switchStr);

        return roalb.build();
    };


    // ********************************************************************************************
    // ********************************************************************************************
    // This Class Main Method: Run Java-Doc
    // ********************************************************************************************
    // ********************************************************************************************


    public static void javaDoc(Builder builder) throws IOException
    {
        builder.timers.startStage02();

        Printing.startStep(2);

        // Used for the log
        final StringBuilder logOnly = new StringBuilder();

        // Prints to both the log and System.out
        final Appendable logAndScreen = new BiAppendable(logOnly, System.out);


        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
        // First deletes the current 'javadoc/' dir if there happens to be one already
        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

        logAndScreen.append
            ("Deleting current directory contents: " + builder.LOCAL_JAVADOC_DIR + "\n\n");

        // Printing Out the Complete List of every file that is deleted by this command seems
        // a little bit excessive.  PRIMARILY - BECAUSE - The text-output that is produced by
        // 'deleteFilesRecursive' contains the class 'C' UNIX-Colors,  it would be better to just
        // shunt the output completely.  Remember that the output of the 'javadoc' Stage (This
        // Stage / Stage-02) is saved to a text-log file.

        if (new File(builder.LOCAL_JAVADOC_DIR).exists())
            FileTransfer.deleteFilesRecursive
                (FileNode.createRoot(builder.LOCAL_JAVADOC_DIR).loadTree(), null, null, logOnly);


        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
        // Build & Print the javadoc Command / Arguments
        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

        logOnly.append("\nPackages Included in this Builder:\n\n");
        for (BuildPackage bp : builder.packageList) logOnly.append(bp.fullName + '\n');

        ReadOnlyList<BuildPackage> packagesToJavaDoc = Packages.packagesToJavaDoc(builder);

        logOnly.append("\nPackages to be Documented by 'javadoc':\n\n");
        for (BuildPackage bp : builder.packageList) logOnly.append(bp.fullName + '\n');

        // Do this first, it has a little text output that looks better at the top
        ReadOnlyList<String> filesToJavaDoc = Files.filesToJavaDoc
            (packagesToJavaDoc, logAndScreen);

        logAndScreen.append(
            BGREEN + "INVOKING: " + RESET +
            BYELLOW + builder.JAVADOC_BIN + RESET + "\n"
        );

        ROArrayListBuilder<String> roalb = new ROArrayListBuilder<>();

        // First append the command switches
        for (String arg : commandSwitches(builder))
        {
            logAndScreen.append((arg.startsWith("-") ? "\n    " : " ") + arg);
            roalb.add(arg);
        }

        logAndScreen.append('\n');
        final int NUM_SWITCHES = roalb.size();

        logAndScreen.append("\n");

        /* Screen Only */ System.out.println(
            "    [Files List Ommited, Total Number of Files to Document: " +
            BRED + filesToJavaDoc.size() + RESET + "]\n"
        );

        // Now append the names of the actual Java Files, themselves
        for (String fileName : filesToJavaDoc)
        {
            roalb.add(fileName);
            logOnly.append("    " + fileName + '\n');
        }

        ReadOnlyList<String> javaDocCommand = roalb.build();


        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
        // RUN JAVA-DOC
        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

        final String[] tempCmdArr = javaDocCommand.toArray(new String[0]);

        int counter = 0;
        for (String arg : tempCmdArr)
            logOnly.append(arg + ((++counter > NUM_SWITCHES) ? "\n" : ""));

        OSResponse osr = new Shell(null, null).COMMAND(builder.JAVADOC_BIN, tempCmdArr);

        // CHECK FOR ERRORS - Other than the Uses-Frames Warning-Message
        if (osr.errorOutput.length() > 0)
        {
            System.err.println
                (BRED + "\nTEXT PRINTED TO STANDARD ERROR:\n" + RESET + osr.errorOutput);

            if (! StrPrint.lastNLines(osr.errorOutput, 7)
                    .equals(PackageSummaryHTML.JD_FRAMES_WARNING_MESSAGE)) 
                Util.ERROR_EXIT("javadoc");
            else
                // sb.append("NOTE: Frames Warning Ignored.\n");
                logAndScreen.append("NOTE: Frames Warning Ignored.\n");
        }


        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
        // Write the log data to the log files
        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

        builder.logs.write_S02_LOGS(logOnly.toString(), osr.standardOutput, osr.errorOutput);
        builder.timers.endStage02();
    }
}