001package Torello.Java.Build;
002
003import Torello.Java.StringParse;
004import Torello.Java.FileNode;
005import Torello.Java.RTC;
006
007import Torello.Java.Additional.Counter;
008
009import java.io.File;
010import java.io.FilenameFilter;
011import java.io.IOException;
012
013import java.util.ArrayList;
014import java.util.function.Predicate;
015
016import Torello.Java.ReadOnly.ROArrayListBuilder;
017import Torello.Java.ReadOnly.ROHashtableBuilder;
018import Torello.Java.ReadOnly.ReadOnlyList;
019import Torello.Java.ReadOnly.ReadOnlyArrayList;
020
021import Torello.Java.StrCSV;
022
023import static Torello.Java.C.BRED;
024import static Torello.Java.C.RESET;
025
026/**
027 * Given a list of packges, collate a list of files to processed by the various
028 * Build-Stages.
029 */
030@Torello.JavaDoc.StaticFunctional
031public class Files
032{
033    // Completely irrelevant, and the 'private' modifier keeps it off of JavaDoc
034    private Files() { }
035
036    private static final String FS = File.separator;
037
038
039    // ********************************************************************************************
040    // ********************************************************************************************
041    // File-Array Builder
042    // ********************************************************************************************
043    // ********************************************************************************************
044
045
046    private static final int addMore
047        (ROArrayListBuilder<String> b, String dir, boolean depth, FilenameFilter filter)
048    {
049        Counter c = new Counter(0);
050
051        FileNode
052            .createRoot         (dir)
053            .loadTree           (depth ? -1 : 0, filter, null)
054            .flattenJustFiles   (RTC.FULLPATH_VECTOR())
055            .forEach            ((String srcFileName) -> { c.addOne(); b.add(srcFileName); });
056
057        return c.get();
058    }
059
060
061    // ********************************************************************************************
062    // ********************************************************************************************
063    // Stage 01, Compile Files
064    // ********************************************************************************************
065    // ********************************************************************************************
066
067
068    /**
069     * Retrieve the Stage 1 Files List of {@code '.java'} Files.  The master list that is returned
070     * as a result of this method is the complete list of files sent to {@code 'javac'}, as command
071     * line parameters.
072     * 
073     * @param packagesToCompile The list of packages whose files need to be compiled.  This list,
074     * itself, was built by class {@link Packages} method
075     * {@link Packages#packagesToCompile(Builder) builder} using all User-Provided Configurations,
076     * and Command-Line Switch Choices.
077     * 
078     * @param logAndScreen Prints log information to both the log and the terminal-screen.
079     * 
080     * @return The list of files to be compiled by the Stage 1 Build-Class
081     * {@link S01_JavaCompiler}.
082     * 
083     * @throws IOException Required due to the {@code Appendable} parameter {@code 'logAndScreen'}
084     * @see Printing#printFilesCount(ReadOnlyList, ArrayList, Appendable)
085     * @see BuildPackage#pkgRootDirectory
086     * @see BuildPackage#hasSubPackages
087     * @see BuildPackage#hasUpgradeFilesDir
088     * @see BuildPackage#hasPackageSourceDir
089     * @see BuildPackage#helperPackages
090     */
091    public static ReadOnlyList<String> filesToCompile(
092            ReadOnlyList<BuildPackage>  packagesToCompile,
093            Appendable                  logAndScreen
094        )
095        throws IOException
096    {
097        // This is much easier to understand.  It is actually smarter to just go to the class
098        // "Files" and look what it is doing.  The loop that collects the files for a "Package"
099        // uses the following BuildPackage boolean-fields, which are defined, as below, inside the
100        // BuildPackage-Constructor:
101        //
102        // BuildPackage.hasSubPackages     = (flags & HAS_SUB_PACKAGES)    >= 1;
103        // BuildPackage.pkgRootDirectory   = classPathLocation + fullName.replace(".", FS) + FS;
104        //
105        // this.helperPackages = (helperPackages == null) || (helperPackages.length == 0)
106        //     ? EMPTY_LIST
107        //     : ReadOnlyList.of(helperPackages);
108        //
109        // Just go to class "Files" to see how those "BuildPackage" boolean Configuration-Fields
110        // pick files to insert into the "filesToCompile" list.
111
112        // This keeps a complete list of all files that will need to be compiled
113        ROArrayListBuilder<String> b = new ROArrayListBuilder<>();
114
115        // This is used for printing to the screen only, it is discarded when this method
116        // exits.
117
118        final ArrayList<Integer> packageFilesCount = new ArrayList<>(packagesToCompile.size());
119
120        for (final BuildPackage pkg : packagesToCompile)
121        {
122            int count = 0;
123
124            count += addMore(b, pkg.pkgRootDirectory, pkg.hasSubPackages, FileNode.JAVA_FILES);
125
126            if (pkg.hasUpgradeFilesDir) count += addMore
127                (b, pkg.pkgRootDirectory + "upgrade-files" + FS, true, FileNode.JAVA_FILES);
128
129            if (pkg.hasPackageSourceDir) count += addMore
130                (b, pkg.pkgRootDirectory + "package-source" + FS, true, FileNode.JAVA_FILES);
131
132            for (String helperPkgDirName : pkg.helperPackages) count += addMore
133                (b, helperPkgDirName, false, FileNode.JAVA_FILES);
134
135            packageFilesCount.add(Integer.valueOf(count));
136        }
137
138        Printing.printFilesCount(packagesToCompile, packageFilesCount, logAndScreen);
139
140        return b.build();
141    }
142
143
144    // ********************************************************************************************
145    // ********************************************************************************************
146    // Stage 02, JavaDoc Files
147    // ********************************************************************************************
148    // ********************************************************************************************
149
150
151    /**
152     * Retrieve the Stage 1 Files List of {@code '.java'} Files.  The master list that is returned
153     * as a result of this method is the complete list of files sent to {@code 'javadoc'}, as
154     * command line parameters.
155     * 
156     * @param packagesToJavaDoc The list of packages whose files need to be compiled.  This list,
157     * itself, was built by class {@link Packages} method
158     * {@link Packages#packagesToCompile(Builder) builder} using all User-Provided Configurations,
159     * and Command-Line Switch Choices.
160     * 
161     * @param logAndScreen Prints log information to both the log and the terminal-screen.
162     * 
163     * @return The list of files to be compiled by the Stage 2 Build-Class
164     * {@link S02_JavaDoc}.
165     * 
166     * @throws IOException Required due to the {@code Appendable} parameter {@code 'logAndScreen'}
167     * @see Printing#printFilesCount(ReadOnlyList, ArrayList, Appendable)
168     * @see BuildPackage#pkgRootDirectory
169     * @see BuildPackage#hasPackageSourceDir
170     */
171    public static ReadOnlyList<String> filesToJavaDoc(
172            ReadOnlyList<BuildPackage>  packagesToJavaDoc,
173            Appendable                  logAndScreen
174        )
175        throws IOException
176    {
177        // This keeps a complete list of all files that will need to be compiled
178        ROArrayListBuilder<String> b = new ROArrayListBuilder<>();
179
180        // This is used for printing to the screen only, it is discarded when this method
181        // exits.
182
183        final ArrayList<Integer> packageFilesCount = new ArrayList<>(packagesToJavaDoc.size());
184
185        for (final BuildPackage pkg : packagesToJavaDoc)
186        {
187            int count = 0;
188
189            count += addMore(b, pkg.pkgRootDirectory, false, FileNode.JAVA_FILES);
190
191            if (pkg.hasPackageSourceDir) count += addMore
192                (b, pkg.pkgRootDirectory + "package-source" + FS, true, FileNode.JAVA_FILES);
193
194            packageFilesCount.add(Integer.valueOf(count));
195        }
196
197        Printing.printFilesCount(packagesToJavaDoc, packageFilesCount, logAndScreen);
198
199        return b.build();
200    }
201}