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 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 | package Torello.Java.Build; import Torello.Java.FileTransfer; import Torello.Java.FileNode; import Torello.Java.StringParse; import Torello.Java.RTC; import Torello.Java.ReadOnly.ReadOnlyList; import Torello.Java.ReadOnly.ReadOnlyArrayList; import static Torello.Java.C.BGREEN_BKGND; import static Torello.Java.C.BRED_BKGND; import static Torello.Java.C.BCYAN; import static Torello.Java.C.BGREEN; import static Torello.Java.C.BYELLOW; import static Torello.Java.C.RESET; import java.io.File; import java.io.IOException; import java.util.Map; import java.util.TreeMap; /** * The purpose of a Build-Tool is, fundamentally, to make a project possible by doing what a * programmer would otherwise need enter manually into a keyboard hundreds of thousands of times * himself. The package {@lnk Torello.Java.Build} provides a CLI Menu that would performs hundreds * and hundreds of otherwise <B STYLE='color: red;'><I>extremely trivial tasks</I></B> via a single * UNIX CLI Command. * * <BR /><BR />It is likely that no programmer on earth would determine that running the Standard * Java Command <B>{@code 'javac'}</B> at a UNIX prompt to be an overly cumbersome or difficult * task. Building and re-building the Data-Files for a particular project requires just that: * compiling some {@code '.java'} files, and then executing their {@code '.class'} Files in order * to obtain their output. Everything seems quite trivial so far. * * <BR /><BR />Things become difficult when a project (for example the Java-HTML Library Tool) has * such Data-File Building {@code '.java'} classes spread out across quite a number of * <B STYLE='color:red;'>{@code ../data-files/}</B> directories, and furthermore each of those * directories have multiple Data-Files Classes to both compile and build. In such cases, whenever * the need arises to tweak, debug, update or add to the * <B STYLE='color:red;'>{@code ../data-files/}</B> directories, the value of some sort of * scripting tool starts to look like an invaluable tool in the programmer's arsenal. * * <BR /><BR />Why? * * <BR /><BR />Because typing: * * <BR /><BR /><OL CLASS=JDOL> * <LI>{@code 'cd <dir-name>'} and</LI> * <LI>{@code 'javac -switches <java-files>'} and</LI> * <LI>{@code 'java <class-files>'}</LI> * </OL> * * <BR /><BR >over and over again is a ROYAL PAIN IN THE ASS. * * <BR /><BR />That's what this tool does for you. It enters all {@code '../data-files/'} * sub-directories of all Package Source Directories in your project and compiles then. * Afterwards, it invokes the <B>{@link DataFileBuilderClass#build(String) build}</B> Method on * any {@code '.class'} files which have implemented the <B>{@link DataFileBuilderClass}</B> * inteface. * * <BR /><BR /><UL CLASS=JDUL> * * <LI> Enter all <B STYLE='color:red;'>{@code my/package/dir/data-files/}</B> directories * <BR ><BR /> * </LI> * * <LI> Wipe / Delete all Java {@code '.class'}-Files present in {@code ../data-files/} and its * sub-directories. * <BR /><BR /> * </LI> * * <LI> Invoke {@code 'javac'} (Re-Compile) all {@code '.java'}-Files present in the directory and * its sub-directories. * <BR /><BR /> * </LI> * * <LI> Scan {@code ../data-files/} and its sub directories for any and all {@code '.class'}-Files. * Afterwards, seek and identify if any of them implement the * {@link DataFileBuilderClass} interface. * <BR /><BR /> * </LI> * * <LI> Invoke the {@link DataFileBuilderClass#build(String)} method on those classes which do * implement the aforementioned interface. If the user has properly written them, those * classes will produce Data-Files which are needed and required for the particular * Java-Package being examined. * <BR /><BR /> * </LI> * * <LI> That's all folks! It is that simple... 😊😊😊</LI> * </UL> * * <BR /><BR /><B CLASS=JDDescLabel>CLI Output Example:</B> * * <BR />The following {@code '.html'}-Page demonstrates what the output looks like when running * this class against all of the <B STYLE='color: red;'>{@code '../data-files/'}</B> directries * which are utilized by this Java-HTML JAR-Library. This output was generated by this tool on * Janaury 6th, 2025. * * <BR /><BR /><B><CODE><A HREF='doc-files/Data-File-Builder.Output.html'> * Data-File-Builder.Output.html</A></CODE></B> */ public class BuildDataFiles { private BuildDataFiles() { } /** * This method should be invoked by any {@code public static void main} method, and pass * <B STYLE='color: red;'><I>BOTH</I></B> the provided {@code 'String[] argv'} parameter to * this method, <B STYLE='color: red;'><I>AND</I></B> the remained of the required parameters * needed. * * <BR /><BR /><B CLASS=JDDescLabel>Helper Code:</B> * * <BR />This method invokes two Package-Private and Internal-Classes for help. These external * classes are listed above, at the top of this class' documentation page, and also here, below: * * <BR /><BR /><UL CLASS=JDUL> * * <LI> <B><A HREF='hilite-files/CompileDataFilesBuilders.java.html'> * CompileDataFilesBuilders.java</A></B></LI> * * <LI> <B><A HREF='hilite-files/RunDataFilesBuilders.java.html'> * RunDataFilesBuilders.java</A></B></LI> * * </UL> * * <BR /><BR /><B CLASS=JDDescLabel>Example & Output:</B> * * <BR />This class & method are, indeed, utilized by the Java-HTML JAR-Library (this tool) * to build its own Data-Files. The links here are also included above. These links are to * Syntax-Hilited Source - <I>and the output it produces</I>- showing how this method & * class may be used. These links are also included, here, directly below: * * <BR /><BR /><UL CLASS=JDUL> * * <LI> <B><A HREF='hilite-files/DataFiles.java.html'> * Torello.BuildJAR.DataFiles.java</A></B></LI> * * <LI> <B><A HREF='doc-files/Data-File-Builder.Output.html'> * Data-File-Builder.Output.html</A></B></LI> * * </UL> * * @param pkgList This list of {@link BuildPackage} instances ought to be the exact same list * which is passed to the {@link Config} class instance used for running a build with this * package. * * @param argv This is the {@code String[] argv} parameter received from a CLI Processor at the * Command-Line. * * @param additionalCompilerArgs This should be a list * * @param JAVAC_BIN This parameter may be null, and if it is, it shall be safely ignored. This * parameter may include a relative or full path to a binary for the {@code 'javac'} program. * * <BR /><BR />When this parameter is null, this Data-File Builder-Class will utilize whichever * {@code 'javac'} binary is available within the Operating-System's {@code 'PATH'} * Environment-Variable. * * @throws IOException If any Operating-System I/O Errors throw. */ public static void build( final BuildPackage[] pkgList, final String[] argv, final ReadOnlyList<String> additionalCompilerArgs, final String JAVAC_BIN ) throws IOException { final ReadOnlyList<BuildPackage> selectedPackages = DataFilesCLI.run(pkgList, argv); final PkgTextBar textBarPrinter = new PkgTextBar (selectedPackages, "Working Package", BGREEN_BKGND, BCYAN); final Map<String, Integer> totals = new TreeMap<>(); int maxLen = 0; for (final BuildPackage bp : selectedPackages) { textBarPrinter.print(bp); clearClassFiles(bp.pkgRootDirectory + "data-files" + File.separator); CompileDataFilesBuilders.compile(bp, additionalCompilerArgs, JAVAC_BIN); int numExecuted = RunDataFilesBuilders.run(bp); totals.put(bp.fullName, numExecuted); if (bp.fullName.length() > maxLen) maxLen = bp.fullName.length(); } if (selectedPackages.size() > 1) printTotals(totals, maxLen+2); } // ******************************************************************************************** // ******************************************************************************************** // Utility / Helper Methods // ******************************************************************************************** // ******************************************************************************************** // Clear Class Files in a Directory private static void clearClassFiles(final String dataFilesDirName) throws IOException { final FileNode fn = FileNode .createRoot(dataFilesDirName) .loadTree(-1, FileNode.CLASS_FILES, null); FileTransfer.deleteFilesRecursive(fn, null, null, System.out); } // Print up the little Map that the main for-loop keeps - which contains a tally or count // on how many DataFileBuilderClass were found in each of the user's '../data-files/' // directories. private static void printTotals(Map<String, Integer> m, int MAX) { System.out.println( "\n\n" + BRED_BKGND + " Package Totals: " + RESET + "\n\n" + "The table below lists how many Java '.class'-Files were found within the " + "'../data-files/' sub-directory (and all of its sub-directories) and implemented " + "the 'DataFileBuilderClass' interface. These classes were all invoked using their " + "respective 'DataFileBuilderClass.build(String)' methods.\n" ); for (Map.Entry<String, Integer> e : m.entrySet()) { final String k = e.getKey(); final String s = StringParse.nChars(' ', MAX - k.length()); System.out.println(k + s + e.getValue()); } System.out.println(); } } |