001package Torello.Java.Build;
002
003import Torello.JavaDoc.PackageSummaryHTML;
004
005import Torello.Java.Additional.BiAppendable;
006
007import Torello.Java.FileNode;
008import Torello.Java.FileTransfer;
009import Torello.Java.Shell;
010import Torello.Java.OSResponse;
011import Torello.Java.StrPrint;
012
013import Torello.Java.ReadOnly.ReadOnlyList;
014import Torello.Java.ReadOnly.ROArrayListBuilder;
015
016import static Torello.Java.C.*;
017
018import java.io.IOException;
019import java.io.File;
020
021/**
022 * This is the second Build-Stage, and it runs the Standard Java-Doc Tool - using {@code 'javadoc'}
023 * and {@link Shell Torello.Java.Shell}.  This class also relies heavily on the Java-HTML Tools
024 * {@link FileNode} and {@link FileTransfer}.
025 * 
026 * <EMBED CLASS='external-html' DATA-FILE-ID=S02_JAVADOC>
027 */
028@Torello.JavaDoc.StaticFunctional
029public class S02_JavaDoc
030{
031    // Completely irrelevant, and the 'private' modifier keeps it off of JavaDoc
032    private S02_JavaDoc() { }
033
034
035    // ********************************************************************************************
036    // ********************************************************************************************
037    // Private-Constant
038    // ********************************************************************************************
039    // ********************************************************************************************
040
041
042    private static final ReadOnlyList<String> commandSwitches(Builder builder)
043    {
044        ROArrayListBuilder<String> roalb = new ROArrayListBuilder<>();
045
046        roalb.add("-d");                roalb.add("javadoc");
047        roalb.add("-docfilessubdirs");
048        roalb.add("-linksource");
049        roalb.add("-charset");          roalb.add("UTF-8");
050        roalb.add("-docencoding");      roalb.add("UTF-8");
051        roalb.add("-encoding");         roalb.add("UTF-8");
052        roalb.add("-sourcetab");        roalb.add("4");
053        roalb.add("-splitindex");
054        roalb.add("-notree");
055        roalb.add("-classpath");        roalb.add(builder.CLASS_PATH_STR);
056
057        if ((builder.JAVADOC_VER <= 11) && (! builder.NO_JAVADOC_FRAMES_SWITCH))
058            roalb.add("--frames");
059
060        roalb.add("--allow-script-in-comments");  
061
062        if ((builder.JAVADOC_VER == 11) || (builder.JAVADOC_VER == 14))
063            roalb.add("--no-module-directories");
064
065        // The <EMBED> tags and <BR />'s break starting in javdoc version 14.
066        // For now this says "17" because Google Cloud Server only provides java Version 11 & 17
067        // Java 14 is completely missing, so I don't actually now if this is needed for 14!
068
069        if (builder.JAVADOC_VER == 17) roalb.add("-Xdoclint:html");
070
071        // "WebSockets" have @since tags... before "The Refl" was fully working, this was needed
072        // "-nosince"
073    
074        // needed for the search bar !
075        // "-overview", "Torello/Build/OverviewSummary.html"
076
077        // This isn't used in Java-HTML, as of January 2024.  However, if there ever arises a need
078        // to quickly add / append command-line switches to the `javadoc` command, it is handled
079        // right here.
080
081        if ((builder.extraSwitchesJAVADOC != null) && (builder.extraSwitchesJAVADOC.size() > 0))
082            for (String switchStr : builder.extraSwitchesJAVADOC)
083                roalb.add(switchStr);
084
085        return roalb.build();
086    };
087
088
089    // ********************************************************************************************
090    // ********************************************************************************************
091    // This Class Main Method: Run Java-Doc
092    // ********************************************************************************************
093    // ********************************************************************************************
094
095
096    public static void javaDoc(Builder builder) throws IOException
097    {
098        builder.timers.startStage02();
099
100        Printing.startStep(2);
101
102        // Used for the log
103        final StringBuilder logOnly = new StringBuilder();
104
105        // Prints to both the log and System.out
106        final Appendable logAndScreen = new BiAppendable(logOnly, System.out);
107
108
109        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
110        // First deletes the current 'javadoc/' dir if there happens to be one already
111        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
112
113        logAndScreen.append
114            ("Deleting current directory contents: " + builder.LOCAL_JAVADOC_DIR + "\n\n");
115
116        // Printing Out the Complete List of every file that is deleted by this command seems
117        // a little bit excessive.  PRIMARILY - BECAUSE - The text-output that is produced by
118        // 'deleteFilesRecursive' contains the class 'C' UNIX-Colors,  it would be better to just
119        // shunt the output completely.  Remember that the output of the 'javadoc' Stage (This
120        // Stage / Stage-02) is saved to a text-log file.
121
122        if (new File(builder.LOCAL_JAVADOC_DIR).exists())
123            FileTransfer.deleteFilesRecursive
124                (FileNode.createRoot(builder.LOCAL_JAVADOC_DIR).loadTree(), null, null, logOnly);
125
126
127        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
128        // Build & Print the javadoc Command / Arguments
129        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
130
131        logOnly.append("\nPackages Included in this Builder:\n\n");
132        for (BuildPackage bp : builder.packageList) logOnly.append(bp.fullName + '\n');
133
134        ReadOnlyList<BuildPackage> packagesToJavaDoc = Packages.packagesToJavaDoc(builder);
135
136        logOnly.append("\nPackages to be Documented by 'javadoc':\n\n");
137        for (BuildPackage bp : builder.packageList) logOnly.append(bp.fullName + '\n');
138
139        // Do this first, it has a little text output that looks better at the top
140        ReadOnlyList<String> filesToJavaDoc = Files.filesToJavaDoc
141            (packagesToJavaDoc, logAndScreen);
142
143        logAndScreen.append(
144            BGREEN + "INVOKING: " + RESET +
145            BYELLOW + builder.JAVADOC_BIN + RESET + "\n"
146        );
147
148        ROArrayListBuilder<String> roalb = new ROArrayListBuilder<>();
149
150        // First append the command switches
151        for (String arg : commandSwitches(builder))
152        {
153            logAndScreen.append((arg.startsWith("-") ? "\n    " : " ") + arg);
154            roalb.add(arg);
155        }
156
157        logAndScreen.append('\n');
158        final int NUM_SWITCHES = roalb.size();
159
160        logAndScreen.append("\n");
161
162        /* Screen Only */ System.out.println(
163            "    [Files List Ommited, Total Number of Files to Document: " +
164            BRED + filesToJavaDoc.size() + RESET + "]\n"
165        );
166
167        // Now append the names of the actual Java Files, themselves
168        for (String fileName : filesToJavaDoc)
169        {
170            roalb.add(fileName);
171            logOnly.append("    " + fileName + '\n');
172        }
173
174        ReadOnlyList<String> javaDocCommand = roalb.build();
175
176
177        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
178        // RUN JAVA-DOC
179        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
180
181        final String[] tempCmdArr = javaDocCommand.toArray(new String[0]);
182
183        int counter = 0;
184        for (String arg : tempCmdArr)
185            logOnly.append(arg + ((++counter > NUM_SWITCHES) ? "\n" : ""));
186
187        OSResponse osr = new Shell(null, null).COMMAND(builder.JAVADOC_BIN, tempCmdArr);
188
189        // CHECK FOR ERRORS - Other than the Uses-Frames Warning-Message
190        if (osr.errorOutput.length() > 0)
191        {
192            System.err.println
193                (BRED + "\nTEXT PRINTED TO STANDARD ERROR:\n" + RESET + osr.errorOutput);
194
195            if (! StrPrint.lastNLines(osr.errorOutput, 7)
196                    .equals(PackageSummaryHTML.JD_FRAMES_WARNING_MESSAGE)) 
197                Util.ERROR_EXIT("javadoc");
198            else
199                // sb.append("NOTE: Frames Warning Ignored.\n");
200                logAndScreen.append("NOTE: Frames Warning Ignored.\n");
201        }
202
203
204        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
205        // Write the log data to the log files
206        // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
207
208        builder.logs.write_S02_LOGS(logOnly.toString(), osr.standardOutput, osr.errorOutput);
209        builder.timers.endStage02();
210    }
211}