001package Torello.JavaDoc;
002
003import Torello.Java.*;
004import Torello.HTML.*;
005
006import Torello.Java.Additional.RetN;
007
008import Torello.JDUInternal.MainJDU.ClassUpgradeData.*;
009
010import Torello.JDUInternal.Features.STATS.StatsInternal;
011
012import static Torello.Java.C.*;
013
014import Torello.JavaDoc.Messager.Messager;
015import Torello.JavaDoc.Messager.MsgVerbose;
016
017import Torello.JDUInternal.SimpleFeatures.LinksChecker;
018
019import Torello.JavaDoc.SyntaxHiLite.HiLiteCache;
020import Torello.HTML.Tools.Images.IF;
021
022import Torello.Java.ReadOnly.ReadOnlyMap;
023import Torello.Java.ReadOnly.ReadOnlyList;
024import Torello.Java.ReadOnly.ReadOnlyArrayList;
025
026import Torello.Java.Build.BuildPackage;
027
028import java.util.*;
029import java.io.*;
030import java.util.stream.*;
031import java.util.function.*;
032
033
034/**
035 * The primary builder and configuration class for the Java Doc Upgrade Process, having many
036 * customizations that may be requested using the customize-settings methods available here.
037 * 
038 * <EMBED CLASS='external-html' DATA-FILE-ID=UPGRADE>
039 */
040public class Upgrade
041{
042    /**
043     * Initializes the Messager immediately, even before the {@link #upgrade()} method has begun
044     * running.  This can be useful if Java-Doc Upgrader Features are to be invoked before the 
045     * actual Upgrade Process begins.
046     * 
047     * @throws InternalError This throws if either the {@code 'verbosityLevel'} or the 
048     * {@code logFile} Upgrader Configurations have been altered or re-assigned previous to this
049     * method call.
050     */
051    public void initializeMessagerUsingCurAssignments()
052    {
053        Messager.initializeThreadLocalInstance
054            (settingsBuilder.verbosityLevel, settingsBuilder.logFile);
055    }
056
057
058    // ********************************************************************************************
059    // ********************************************************************************************
060    // Public-Static Constant/Final Fields
061    // ********************************************************************************************
062    // ********************************************************************************************
063
064
065    /** The name of the favicon-file (without extension).  This filename may not be changed. */
066    public static final String FAVICON_FILE_NAME = "favicon";
067
068    /** The name of the (very brief) {@code '.js'} file. */
069    public static final String JAVA_SCRIPT_FILE_NAME = "JDU.js";
070
071
072    // ********************************************************************************************
073    // ********************************************************************************************
074    // Private Fields (all are final/Constants - except "Stats")
075    // ********************************************************************************************
076    // ********************************************************************************************
077
078
079    // These are acctually for Internal-Use, and shouldn't be public.  Unfortunately due to Java's
080    // leaving out the 'friend' key-word from C/C++, these have to be public in order to share them
081    // with the Internal-Only Packages in JavaDoc-Upgrader.
082
083    private final UpgradePredicates.Builder  predicatesBuilder  = new UpgradePredicates.Builder();
084    private final UpgradeSettings.Builder    settingsBuilder    = new UpgradeSettings.Builder();
085    private final PathsAndTypes.Builder      pathsTypesBuilder  = new PathsAndTypes.Builder();
086
087    // Used by the log-file header string below
088    private final String dateTimeStr =
089        StrPrint.dateStr('-') + " " + StrPrint.timeStr(':');
090
091    // Prepended to the log-file that may (or may not) be saved to disk, or an Appendable
092    private final String logFileHeader = 
093        "<HTML>\n<HEAD>\n" +
094        "<TITLE>Log " + dateTimeStr + "</TITLE>\n" +
095        "<STYLE type='text/css'>\n" + C.getCSSDefinitions() + "\n</STYLE>\n" +
096        "</HEAD>\n" +
097        "<BODY STYLE='margin: 1em; background: black; color: white;'>\n\n" +
098        "<H1>JavaDoc Upgrader Log</H1>\n" +
099        "<CODE>" + dateTimeStr + "</CODE>\n" +
100        "<PRE>\n\n";
101
102    // used internally
103    private static final TextNode NEWLINE = new TextNode("\n");
104
105    // NOTE: This isn't final....  It will be constructed in this class....
106    private StatsInternal stats = null;
107
108
109    // ********************************************************************************************
110    // ********************************************************************************************
111    // Building / Constructor, Running the Upgrader
112    // ********************************************************************************************
113    // ********************************************************************************************
114
115
116    /**
117     * This returns a new instance of this class.  It will have all empty and null settings, except
118     * the root-directory descriptors.  It must be initialized with the various builder methods.
119     * 
120     * <BR /><BR />
121     * This constructor must tell the Upgrader (Builder) which directory contains {@code '.java'}
122     * Source-Files, and which directory shall contain Java-Doc Generated HTML Documentation Pages.
123     * 
124     * @param rootJavaDocDirectory This is the output directory that was used for the last call to
125     * the JavaDoc Utility.  The Upgrade Logic should expect to find all class, interface and
126     * enumerated types to be hilited in this directory.  This parameter may not be null.
127     * 
128     * @param rootSourceFileDirectories This is the location where the {@code '.java'} source files
129     * for the classes, interfaces and enumerated types named by your list files are stored.  This
130     * parameter may not be null; at least one directory must be passed.  If you have multiple
131     * source-code directories, then pass all of them, and whenever a JavaDoc {@code '.html'} file
132     * is loaded from disk, all source-code directories will be searched until the source-code is
133     * found.
134     * 
135     * @throws UpgradeException This exception will throw if either of these directories cannot be
136     * found, or may not be accessed.  The {@code 'getCause()'} method of the exception will
137     * provide more details of the specific error that occurred.
138     */
139    @LinkJavaSource(handle="MainConstructor")
140    public Upgrade(final String rootJavaDocDirectory, final String... rootSourceFileDirectories)
141    { 
142        final RetN r = MainConstructor.run(rootJavaDocDirectory, rootSourceFileDirectories);
143        this.pathsTypesBuilder.rootJavaDocDirectory         = r.GET(1);
144        this.pathsTypesBuilder.rootSourceFileDirectories    = r.GET(2);
145    }
146
147    /**
148     * <EMBED CLASS='external-html' DATA-FILE-ID=U_UPGRADE>
149     * 
150     * @return This returns the statistics computed for the upgrade process.  See class
151     * {@link Stats} for more information.  A complete listing of the information contained by
152     * the tables in a {@code 'Stats'} instance may be viewed by clicking the {@code 'Stats'}
153     * link at the top-right of this page.
154     * 
155     * <BR /><BR />If the Upgrade-Process had unrecoverable errors, null is returned.
156     */
157    public Stats upgrade()
158    {
159        Objects.requireNonNull(
160            this.settingsBuilder.hiLiter,
161            "Your HiLiter has not been configured.  You must either provide your own Customer " +
162            "HiLiter with a HiLiteCache Directory, otherwise this NullPointerException shall throw."
163        );
164
165        // This has to be initialized before the Embed-Tags can be checked for errors
166        Messager.initializeThreadLocalInstance
167            (settingsBuilder.verbosityLevel, settingsBuilder.logFile);
168
169        // Now Check the Global Embed-Tags Map for Errors
170        this.stats = GlobalEmbedTags.globalMapAndStats(this.settingsBuilder);
171
172        return Torello.JDUInternal.MainJDU.API_RUN.runTheUpgrader(
173            this.predicatesBuilder.build(),
174            this.settingsBuilder.build(),
175
176            // This class cannot be built, yet, one last thing to compute!
177            this.pathsTypesBuilder,
178
179            this.stats
180        );
181    }
182
183    /**
184     * <EMBED CLASS='external-html' DATA-FILE-ID=U_MAIN>
185     * @param argv This is the argument received from the command line.
186     */
187    public static void main(String[] argv) throws Exception
188    {
189        final Upgrade upgrader = new Upgrade(argv[0], "");
190
191        if (argv.length == 1) upgrader.upgrade();
192
193        else if (argv.length == 2)
194        {
195            java.io.File f = new java.io.File(argv[1]);
196
197            if (! f.exists())
198            {
199                f.mkdirs();
200                HiLiteCache.initializeOrClear(argv[1], null);
201            }
202
203            final HiLiteCache CACHE = new HiLiteCache(argv[1]);
204            upgrader.useHiLiterCache(CACHE).upgrade();
205            CACHE.persistMasterHashToDisk();
206        }
207
208        else System.out.println("Failed, expected one or two arguments");
209    }
210
211
212    // ********************************************************************************************
213    // ********************************************************************************************
214    // Filter-Predicates
215    // ********************************************************************************************
216    // ********************************************************************************************
217
218
219    /**  Write an explanation*/
220    @SuppressWarnings("unchecked")
221    public Upgrade setRemoveAllDetailsFilter(Predicate<? super String> cietCanonicalNameFilter)
222    {
223        this.predicatesBuilder.removeAllDetailsFilter =
224            (Predicate<String>) cietCanonicalNameFilter;
225        return this;
226    }
227
228    /**
229     * <EMBED CLASS='external-html' DATA-FILE-ID=U_SET_REM_ALL_DET_F>
230     * @param entity Specifies which HTML Detail-Section to remove.
231     * @param cietCanonicalNameFilter <EMBED CLASS='external-html' DATA-FILE-ID=U_CCNF>
232     */
233    @LinkJavaSource(handle="SetEntityFilters", name="setRemoveAllDetailsFilter")
234    public Upgrade setRemoveAllDetailsFilter
235        (Entity entity, Predicate<? super String> cietCanonicalNameFilter)
236    {
237        SetEntityFilters.setRemoveAllDetailsFilter
238            (entity, cietCanonicalNameFilter, this.predicatesBuilder);
239        return this;
240    }
241
242    /**
243     * <EMBED CLASS='external-html' DATA-FILE-ID=U_SET_HL_ALL_DET_F>
244     * @param cietCanonicalNameFilter <EMBED CLASS='external-html' DATA-FILE-ID=U_CCNF>
245     */
246    @LinkJavaSource(handle="SetEntityFilters", name="setHiLiteAllDetailsFilter")
247    public Upgrade setHiLiteAllDetailsFilter
248        (final Entity entity, final Predicate<? super String> cietCanonicalNameFilter)
249    {
250        SetEntityFilters.setHiLiteAllDetailsFilter
251            (entity, cietCanonicalNameFilter, this.predicatesBuilder);
252        return this;
253    }
254
255    /**
256     * <EMBED CLASS='external-html' DATA-FILE-ID=U_SET_SUMM_REM_F>
257     * @param cietCanonicalNameFilter <EMBED CLASS='external-html' DATA-FILE-ID=U_CCNF>
258     */
259    @SuppressWarnings("unchecked")
260    public Upgrade setSummaryRemoveFilter(Predicate<? super String> cietCanonicalNameFilter)
261    {
262        this.predicatesBuilder.summaryRemoveFilter = (Predicate<String>) cietCanonicalNameFilter;
263        return this;
264    }
265
266    /**
267     * <EMBED CLASS='external-html' DATA-FILE-ID=U_SET_HL_SCF_F>
268     * @param cietCanonicalNameFilter <EMBED CLASS='external-html' DATA-FILE-ID=U_CCNF>
269     */
270    @SuppressWarnings("unchecked")
271    public Upgrade setHiLiteSourceCodeFileFilter(Predicate<? super String> cietCanonicalNameFilter)
272    {
273        this.predicatesBuilder.hiLiteSourceCodeFileFilter =
274            (Predicate<String>) cietCanonicalNameFilter;
275
276        return this;
277    }
278
279    /**
280     * <EMBED CLASS='external-html' DATA-FILE-ID=U_SET_CSS_TAGS_F>
281     * @param cietCanonicalNameFilter <EMBED CLASS='external-html' DATA-FILE-ID=U_CCNF>
282     */
283    @SuppressWarnings("unchecked")
284    public Upgrade setCSSTagsFilter(Predicate<? super String> cietCanonicalNameFilter)
285    {
286        this.predicatesBuilder.cssTagsFilter = (Predicate<String>) cietCanonicalNameFilter;
287        return this;
288    }
289
290    /**
291     * <EMBED CLASS='external-html' DATA-FILE-ID=U_SET_VAL_HTML_F>
292     * @param cietCanonicalNameFilter <EMBED CLASS='external-html' DATA-FILE-ID=U_CCNF>
293     */
294    @SuppressWarnings("unchecked")
295    public Upgrade setValidateHTMLFilter(Predicate<? super String> cietCanonicalNameFilter)
296    {
297        this.predicatesBuilder.validateHTMLFilter = (Predicate<String>) cietCanonicalNameFilter;
298        return this;
299    }
300
301
302    // ********************************************************************************************
303    // ********************************************************************************************
304    // Setting Features: Output Printing and Log-File
305    // ********************************************************************************************
306    // ********************************************************************************************
307
308
309    /**
310     * <EMBED CLASS='external-html' DATA-FILE-ID=U_SET_VERBOSITY_LVL>
311     * @param verbosity One of the four available {@link Verbosity} constants.
312     */
313    public Upgrade setVerbosityLevel(Verbosity verbosity)
314    {
315        this.settingsBuilder.verbosityLevel = verbosity.level;
316        if (verbosity.level == 3) MsgVerbose.setVerbose();
317        return this;
318    }
319
320    /**
321     * <EMBED CLASS='external-html' DATA-FILE-ID=U_SET_LOG_FILE_APND>
322     * @param logFile An {@code Appendable} to be used for backing-up / saving Log-Writes.
323     */
324    public Upgrade setLogFile(Appendable logFile)
325    {
326        this.settingsBuilder.logFile = logFile;
327        return this;
328    }
329
330    /**
331     * <EMBED CLASS='external-html' DATA-FILE-ID=U_SET_LOG_FILE_FN>
332     * @param logFileName File-Name of a writeable File, to be used for backuping-up Log-Writes
333     * @throws UpgradeException If the File provided cannot be written to.
334     * @see UpgradeException#checkFileIsWriteable(String, String, String)
335     */
336    @LinkJavaSource(handle="LogFile")
337    public Upgrade setLogFile(final String logFileName)
338    { LogFile.set(logFileName, this.settingsBuilder, this.logFileHeader); return this; }
339
340
341    // ********************************************************************************************
342    // ********************************************************************************************
343    // The HTML <EMBED> tag.  These can be used to provide more processing to the user.
344    // ********************************************************************************************
345    // ********************************************************************************************
346
347
348    /**
349     * <EMBED CLASS='external-html' DATA-FILE-ID=U_SET_EMBED_TAG_F>
350     * @param tagIDMapFileName A Java {@code '.properties'} File-Name mapping File-ID's to Files.
351     * @throws UpgradeException If there are any problems that occur while loading the file
352     */
353    @LinkJavaSource(handle="GlobalEmbedTags", name="setMapFile")
354    public Upgrade setProjectGlobalEmbedTagsMapFile(final String tagIDMapFileName)
355    {
356        // this.stats = GlobalEmbedTags.setMapFile(tagIDMapFileName, this.settingsBuilder);
357        this.settingsBuilder.interimGlobalTagIDMapFileName = tagIDMapFileName;
358        return this;
359    }
360
361    /**
362     * <EMBED CLASS='external-html' DATA-FILE-ID=U_SET_EMBED_TAG_MAP>
363     * @param tagIDMap This should map a {@code 'DATA-FILE-ID'} to an {@code '.html'} File-Name
364     */
365    @LinkJavaSource(handle="GlobalEmbedTags", name="setMap")
366    public Upgrade setProjectGlobalEmbedTagsMap(ReadOnlyMap<String, String> tagIDMap)
367    {
368        // this.stats = GlobalEmbedTags.setMap(tagIDMap, this.settingsBuilder);
369        this.settingsBuilder.projectGlobalEmbedTagsMap = tagIDMap;
370        return this;
371    }
372
373
374    // ********************************************************************************************
375    // ********************************************************************************************
376    // Using Features: The HiLiter & HiLiter-Cache
377    // ********************************************************************************************
378    // ********************************************************************************************
379
380
381    /**
382     * Convenience Method.
383     * <BR />Invokes: {@link HiLiter#getDefault(HiLiteCache)}
384     * <BR />And-Then: {@link #setHiLiter(HiLiter)}
385     */
386    public Upgrade useHiLiterCache(HiLiteCache cache)
387    {
388        Objects.requireNonNull(cache, "HiLiteCache 'cache' Parameter has been passed null.");
389        setHiLiter(HiLiter.getDefault(cache));
390        this.settingsBuilder.hlCache = cache;
391        return this;
392    }
393
394    /**
395     * Configures the HiLiter to use the Default HiLiter, and use the provided Cache-Directory as
396     * the location for Caching HiLited HTML-Files.
397     * 
398     * @param hiLiterCacheDirectoryName The name of the File-System Directory which has 
399     * previously saved HiLited HTML-Files.
400     * 
401     * <BR /><BR /><DIV CLASS=JDHint>
402     * <B STYLE='color: red;'>Note:</B> If this is the first time using this Cache
403     * Directory, and it doesn't exists yet, this directory will be created, and future
404     * {@code Upgrade} instances will save &amp; cache HiLited-Source HTML to this directory.
405     * </DIV>
406     */
407    public Upgrade useHiLiterCache(String hiLiterCacheDirectoryName)
408    {
409        Objects.requireNonNull(
410            hiLiterCacheDirectoryName,
411            "HiLiteCache 'hiLiterCacheDirectoryName' Parameter has been passed null."
412        );
413
414
415        // These four lines allow the Upgrade Tool to cache results for documentation web-pages
416        // as they are hilited so that future builds will not have to "re-poll" the CLI when
417        // hiliting source-code files that have not changed.
418
419        final File f = new File(hiLiterCacheDirectoryName);
420    
421        if (! f.exists())
422        {
423            f.mkdirs();
424            HiLiteCache.initializeOrClear(hiLiterCacheDirectoryName, null);
425        }
426    
427        final HiLiteCache cache = new HiLiteCache(hiLiterCacheDirectoryName);
428        setHiLiter(HiLiter.getDefault(cache));
429        this.settingsBuilder.hlCache = cache;
430        return this;
431    }
432
433    /**
434     * <EMBED CLASS='external-html' DATA-FILE-ID=U_SET_HILITER>
435     * @param hiLiter Any valid implementation of the {@link HiLiter} interface
436     */
437    public Upgrade setHiLiter(HiLiter hiLiter)
438    {
439        this.settingsBuilder.hiLiter = hiLiter;
440        return this;
441    }
442
443    /**
444     * Retrieve the currently assigned {@link HiLiter} instance.
445     * @return The most recently assigned {@link HiLiter} instance.
446     */
447    public HiLiter getCurrentHiLiter() { return this.settingsBuilder.hiLiter; }
448
449
450    // ********************************************************************************************
451    // ********************************************************************************************
452    // The Big Kahuna Burger.  That is a tasty burger.  Brad - did I break your concentration?
453    // ********************************************************************************************
454    // ********************************************************************************************
455
456
457    /**
458     * <EMBED CLASS='external-html' DATA-FILE-ID=U_GET_DEF_CSS_FILES>
459     * @return All Java-Doc Upgrader {@code '.css'} Files
460     * @see #setCustomCSSFiles(CSSFiles)
461     */
462    public static CSSFiles retrieveDefaultCSSFilesFromJAR()
463    {
464        return LFEC.readObjectFromFile_JAR
465            (Upgrade.class, "data-files/AllCSSFiles.objdat", true, CSSFiles.class);
466    }
467
468    /**
469     * <EMBED CLASS='external-html' DATA-FILE-ID=U_SET_CSS_FILES>
470     * @param cssFiles All Java-Doc Upgrader {@code '.css'} Files
471     * @see #retrieveDefaultCSSFilesFromJAR()
472     */
473    public Upgrade setCustomCSSFiles(CSSFiles cssFiles)
474    {
475        this.settingsBuilder.cssFiles = cssFiles;
476        return this;
477    }
478
479    /**
480     * <EMBED CLASS='external-html' DATA-FILE-ID=U_GET_DEF_JS_FILE>
481     * @return The <B STYLE='color:red'><I>entire contents</I></B> of the {@code '.js'} File (read
482     * from disk), returned as a {@code String}.
483     */
484    public static String retrieveDefaultJSFileFromJAR()
485    {
486        return LFEC.readObjectFromFile_JAR
487            (Upgrade.class, "data-files/JDU-JS.sdat", true, String.class);
488    }
489
490    /**
491     * <EMBED CLASS='external-html' DATA-FILE-ID=U_SET_FAVICON_IF>
492     * @param faviconFileFormat An instance of {@link IF} - the Image-Format of the Favicon-File.
493     */
494    public Upgrade setFaviconFileFormat(IF faviconFileFormat)
495    {
496        this.settingsBuilder.faviconImageFileName =
497            FAVICON_FILE_NAME + '.' + faviconFileFormat.toString();
498
499        return this;
500    }
501
502    /**
503     * Retrieve the File-Name of the Favicon, if one has been assigned.
504     * @return The currently assigned favicon file-name, or null if a favicon was not assigned
505     */
506    public String getFaviconImageFileName()
507    { return this.settingsBuilder.faviconImageFileName; }
508
509
510    /**
511     * <EMBED CLASS='external-html' DATA-FILE-ID=U_ADD_HEADER_TAGS>
512     * @param headerTags HTML-Tags to be inserted into a page's {@code <HEAD>...</HEAD>} Section
513     */
514    public Upgrade addHeaderTags(Iterable<TagNode> headerTags)
515    {
516        Vector<HTMLNode> ht = this.settingsBuilder.headerTags;
517        for (TagNode tn : headerTags) { ht.add(tn); ht.add(NEWLINE); }
518        return this;
519    }
520
521    /**
522     * <EMBED CLASS='external-html' DATA-FILE-ID=U_ADD_HEADER_BLOCK>
523     * @param headerStuff HTML-Block to be inserted into a page's {@code <HEAD>...</HEAD>} Section
524     */
525    public Upgrade addHeaderBlock(Vector<HTMLNode> headerStuff)
526    { this.settingsBuilder.headerTags.addAll(headerStuff);  return this; }
527
528    /** <EMBED CLASS='external-html' DATA-FILE-ID=U_RUN_LINKS_CHECKER> */
529    public Upgrade runLinksChecker()
530    {
531        this.settingsBuilder.linksChecker = new LinksChecker();
532        return this;
533    }
534
535    /**
536     * Sets a tab-replacement policy for code-hilited HTML.
537     * 
538     * @param spacesPerTab The number of spaces that should be used as a substitue for a
539     * tab-character ({@code '\t'}) when hiliting source-code.
540     * 
541     * @param relativeOrAbsolute When this parameter receives {@code TRUE}, a tab-character is
542     * used to symbolize however many spaces are needed to place the cursor at the next 
543     * <B STYLE='color: red;'>rounded-integral</B> number-of-spaces - modulo the value in
544     * {@code 'spacesPerTab'}.
545     * 
546     * <BR /><BR />If a tab-charcter is found at index {@code 13} in a line-of-code, and the value
547     * passed to {@code 'spacesPerTab'} were {@code 4}, then the number of spaces inserted would be
548     * {@code 3}.  This is because precisely {@code 3} spaces would skip to index {@code 16}, which
549     * happens to be the next-highest <B STYLE='color: red;'>rounded-multiple</B> of {@code 4}. 
550     * 
551     * <BR /><BR />When this parameter receives {@code FALSE}, a tab-character is always 
552     * replaced by the exact number of space-characters specified by {@code spacesPerTab}.
553     * 
554     * @throws IllegalArgumentException If a number less than {@code 1} or greater than {@code 20}
555     * is passed to parameter {@code 'spacesPerTab'} 
556     * 
557     * @see StrIndent#setCodeIndent_WithTabsPolicyRelative(String, int, int)
558     * @see StrIndent#setCodeIndent_WithTabsPolicyAbsolute(String, int, String)
559     */
560    @LinkJavaSource(handle="TabsPolicy")
561    public Upgrade setTabsPolicy(int spacesPerTab, boolean relativeOrAbsolute)
562    { TabsPolicy.set(spacesPerTab, relativeOrAbsolute, this.settingsBuilder); return this; }
563
564    /**
565     * <EMBED CLASS='external-html' DATA-FILE-ID=U_SET_CHECK_BALANCE>
566     * @param checkBalance The value of this parameter can turn the balance checker on or off.
567     */
568    public Upgrade setCheckBalance(boolean checkBalance)
569    {
570        this.settingsBuilder.checkBalance = checkBalance;
571        return this;
572    }
573
574    /**
575     * <EMBED CLASS='external-html' DATA-FILE-ID=U_SET_EXTRA_TASKS>
576     * 
577     * @param extraTasks This function-pointer may be used to, sort-of, do extra processing on a
578     * JavaDoc HTML Documentation File while the vectorized-html file is already loaded into
579     * memory - and parsed.
580     * 
581     * <BR /><BR />The class {@link JavaDocHTMLFile} provides many accessor methods to retrieve
582     * the Summary Tables, and the HTML Details - <I>along with reflection-classes about the
583     * {@link Method}'s, {@link Field}'s, etc... that they describe</I>
584     */
585    public Upgrade setExtraTasks(Consumer<JavaDocHTMLFile> extraTasks)
586    {
587        this.settingsBuilder.extraTasks = extraTasks;
588        return this;
589    }
590
591    /**
592     * <EMBED CLASS='external-html' DATA-FILE-ID=U_SET_PKGSUMM_CLEAN>
593     * @param packageSummaryCleaner Java Lambda for modifying Vectorized-HTML.
594     */
595    public Upgrade setPackageSummaryCleaner(Consumer<Vector<HTMLNode>> packageSummaryCleaner)
596    {
597        this.settingsBuilder.packageSummaryCleaner = packageSummaryCleaner;
598        return this;
599    }
600
601    /** <EMBED CLASS='external-html' DATA-FILE-ID=U_USE_DEFAULT_PSC> */
602    public Upgrade useDefaultPackageSummaryCleaner()
603    {
604        this.settingsBuilder.packageSummaryCleaner = PackageSummaryHTML::defaultCleaner;
605        return this;
606    }
607
608    /**
609     * <EMBED CLASS='external-html' DATA-FILE-ID=U_SET_PKG_LIST_BP>
610     * @param packageList Instances of {@link Torello.Java.Build}'s class {@link BuildPackage}.
611     * @return {@code 'this'} instance, for method-invocation chaining.
612     * @see #setPackageList(String[])
613     */
614    public Upgrade setPackageList(Iterable<BuildPackage> packageList)
615    {
616        TreeSet<String> ts = new TreeSet<>();
617        for (BuildPackage bp : packageList) ts.add(bp.fullName);
618        this.predicatesBuilder.packagesToUpgradeFilter = StrFilter.strListKEEP(ts, false)::test;
619        return this;
620    }
621
622    /**
623     * <EMBED CLASS='external-html' DATA-FILE-ID=U_SET_PKG_LIST_STR>
624     * @param packageList A list of Package-Name's as a {@code String}.
625     * @return {@code 'this'} instance, for method-invocation chaining.
626     * @see #setPackageList(Iterable)
627     */
628    public Upgrade setPackageList(String... packageList)
629    {
630        this.predicatesBuilder.packagesToUpgradeFilter =
631            StrFilter.strListKEEP(false, packageList)::test;
632
633        return this;
634    }
635
636    /**
637     * A Configuration-Setting for requesting that the Upgrader Auto-Generate the original Java
638     * {@code 'package-frame.html'} &amp; {@code 'overview-frame.html'} Files.
639     * 
640     * <EMBED CLASS='external-html' DATA-FILE-ID=U_SET_GEN_FRAMES>
641     * 
642     * @param generateFrames The {@code boolean}-Setting for this Configuration-Field
643     * @return {@code 'this'} instance, for method-invocation chaining.
644     * 
645     * @throws UpgradeException If {@code 'generateFrames'} is passed {@code FALSE}, but you have
646     * earlier configured / applied an {@code 'overview-frame.html'} sorter.
647     * 
648     * @see PackageSummaryHTML#JD_FRAMES_WARNING_MESSAGE
649     */
650    public Upgrade setGenerateFrames(boolean generateFrames)
651    {
652        this.settingsBuilder.generateFrames = generateFrames;
653
654        if ((! generateFrames) && (this.settingsBuilder.overviewFrameSections != null))
655
656            throw new UpgradeException(
657                "Generate-Frames cannot be turned off if an Overview-Frame Sorter has already " +
658                "been applied"
659            );
660
661        return this;
662    }    
663
664    /**
665     * Generate and sort an {@code 'overview-frame.html'} File.
666     * @param sectionNames List of "Categories" or "Sections" for the packages
667     * @param sectionContents List of Packages for each Category / Section.
668     * @return {@code 'this'} instance, for method-invocation chaining.
669     */
670    @LinkJavaSource(handle="OverviewFrameSorter")
671    public Upgrade setOverviewFrameSorter(String[] sectionNames, String[][] sectionContents)
672    { OverviewFrameSorter.set(sectionNames, sectionContents, this.settingsBuilder); return this; }
673
674
675    // This is only used to prevent the "Overview Frame Sorter" from causing a Messager
676    // Exception-Throw when the Build has Opted for a "Quick-Build" - and the Overview
677    // Frame Sorter hasn't removed the Quick-Build Packages from its sort!
678    // 
679    // Later this will also be used for the (upcoming - soon) "UNDER_DEVELOPMENT" BuildPackage 
680    // flag.
681    // 
682    // This is an Internal-Method that is largely completely useless for the end user.  Hence it is
683    // Package-Visible (available through the "EXPORT_PORTAL")
684
685    void registerEliminatedBuildPackages(ReadOnlyList<BuildPackage> eliminatedBuildPackages)
686    { this.settingsBuilder.eliminatedBuildPackages = eliminatedBuildPackages; }
687
688}