Class DFBuilder


  • public abstract class DFBuilder
    extends java.lang.Object
    Can be used by Classes the need to build Data-File(s) for the 'data-files/' directory, or convert those Data-Files to Text for viewing and inspection.

    Related Utility:
    Note that this class "does not participate" in the general Build-Process. This class is an independent utility, to be used for the aforementioned purposes described above. None of the methods exported by this class are invoked during any of the various Build-Stages that comprise this Java-Project Build-Package.


    • Constructor Summary

      Constructors 
      Constructor Description
      DFBuilder()  
    • Method Summary

       
      Abstract Instance Methods: Generate Data-File(s) & Data Text-File(s)
      Modifier and Type Method
      abstract void buildAll​(String dataFileRootDir)
      void buildAllToText​(String targetDir)
      void deCompileAllToText​(String targetDir)
       
      Abstract Instance Methods: Retrieve Data-File Names
      Modifier and Type Method
      abstract Iterable<String> dataFileNames()
       
      Helper:public static void main
      Modifier and Type Method
      boolean cli​(int menuOptions, String[] argv)
       
      Static Method: Generate Data-Files for all Packages
      Modifier and Type Method
      static int buildAll​(BuildPackage pkg)
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Method Detail

      • dataFileNames

        🡅  🡇     🗕  🗗  🗖
        public abstract java.lang.Iterable<java.lang.String> dataFileNames()
        Requests a list of Data-File Names that are constructed by this instance.
      • buildAll

        🡅  🡇     🗕  🗗  🗖
        public abstract void buildAll​(java.lang.String dataFileRootDir)
                               throws java.io.IOException
        Requests that this Data-File Builder run and generate all Data-Files that it can build.
        Parameters:
        dataFileRootDir - The target directory location for writing the file(s)

        Relative Directory Path: This parameter is necessary becase an instance of DFBuilder might be invoked from just about anywhere. Thus, it is imperative that the actual root '../data-files/' directory be passed to this method, to avoid writing the Data-Files into the wrong place.

        This String-Parameter 'dataFileRootDir' must be a String that is a Relative-Path, from the CWD / Current-Working-Directory from whence the current Java-Instance was invoked, to the '../data-files/' directory where the Data-Files are to be written.
        Throws:
        java.io.IOException - If there are any problems while writing the data-file.
      • buildAllToText

        🡅  🡇     🗕  🗗  🗖
        public void buildAllToText​(java.lang.String targetDir)
                            throws java.io.IOException
        Requests that this Data-File Builder generate all Data-Files as Text-Files, so that they may be viewed and inspected.

        Default Implementation:
        This method is intentaionally not declared abstract, so as to allow a user to avoid implementing this at all. Writing Data-Files to Text-Files is important during the debugging phase of a Data-File, but isn't mandatory for using this class.

        This default implementation, instead, simply throws the UnsupportedOperationException, instead.
        Parameters:
        targetDir - The target directory location for writing the file(s)

        Relative Directory Path: This parameter is necessary becuase an instance of DFBuilder might be invoked from just about anywhere. Thus it is imperative to pass the target-directory location to this method.

        This String-Parameter 'targetDir' must be a String that is a Relative-Path, from the CWD / Current-Working-Directory from whence the current Java Instance was invoked, to the directory where the output Text-Files are to be written.
        Throws:
        java.io.IOException - If there are any problems reading or writing files to the Operation-System, then this exception throws.
        java.lang.UnsupportedOperationException - This method is not declared abstract, so that implementations which do not have a need for it can rely-on / fall-back-on this default version - thus avoiding the otherwise-inevitable exception "This class must impleent ---, or be declared abstract."

        This implementation throws UnsupportedOperationException
        Code:
        Exact Method Body:
         throw new UnsupportedOperationException();
        
      • deCompileAllToText

        🡅  🡇     🗕  🗗  🗖
        public void deCompileAllToText​(java.lang.String targetDir)
                                throws java.io.IOException
        Requests that this Data-File Builder convert the existing Data-Files themselves into Text-Files, so that they may be viewed and inspected.

        Default Implementation:
        This method is intentaionally not declared abstract, so as to allow a user to avoid implementing this at all. Writing Data-Files to Text-Files is important during the debugging phase of a Data-File, but isn't mandatory for using this class.

        This default implementation, instead, simply throws the UnsupportedOperationException, instead.
        Parameters:
        targetDir - The target directory location for writing the file(s)

        Relative Directory Path: This parameter is necessary becuase an instance of DFBuilder might be invoked from just about anywhere. Thus it is imperative to pass the target-directory location to this method.

        This String-Parameter 'targetDir' must be a String that is a Relative-Path, from the CWD / Current-Working-Directory from whence the current Java Instance was invoked, to the directory where the output Text-Files are to be written.
        Throws:
        java.io.IOException - If there are any problems reading or writing files to the Operation-System, then this exception throws.
        java.lang.UnsupportedOperationException - This method is not declared abstract, so that implementations which do not have a need for it can rely-on / fall-back-on this default version - thus avoiding the otherwise-inevitable exception "This class must impleent ---, or be declared abstract."

        This implementation throws UnsupportedOperationException
        Code:
        Exact Method Body:
         throw new UnsupportedOperationException();
        
      • buildAll

        🡅  🡇     🗕  🗗  🗖
        public static int buildAll​(BuildPackage pkg)
                            throws java.io.IOException
        Runs / Executes the method buildAll(java.lang.String) on all Class-File(s) found insdie the 'data-files/' directory for a given package. If the package provided to parameter 'pkg' does not have a 'data-files/' directory, then this method exists gracefully
        Parameters:
        pkg - Any one of the Configured Project Packages. The relevant fields used by this method are BuildPackage.classPathLocation and BuildPackage.pkgRootDirectory. These two fields are concatenated, and that directory is searched for any / all class files that implement this DFBuilder interface.
        Returns:
        The number of class-files implementing the DFBuilder interface.
        Throws:
        java.io.IOException
        Code:
        Exact Method Body:
         String  dirName = pkg.classPathLocation + pkg.pkgRootDirectory;
         File    f       = new File(dirName);
        
         if ((! f.exists()) || (! f.isDirectory())) return 0;
        
         String[] fNameArr = FileNode
             .createRoot(dirName)
             .loadTree(-1, (File dir, String fName) -> fName.endsWith(".class"), null)
             .flattenJustFiles(RTC.FULLPATH_ARRAY());
        
         int counter = 0;
        
         TOP:
         for (String classFileName : fNameArr)
         {
             // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
             // FileRW.readClass
             // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
        
             // Pulls the Class-Name out of the Class-FileName:
             //      1) Removes the ".class" extension
             //      2) Removes the leading "data-files/..." directory string stuff from File-Name
        
             final String className = StringParse.beforeExtension
                 (StringParse.fromLastFileSeparatorPos(classFileName));
        
             // Runs the FileRW.readClass method & catches the exceptions it throws.
             final Class<?> c;
        
             try
                 { c = FileRW.readClass(classFileName, className); }
        
             catch (Exception e)
                 { continue; }
        
        
             // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
             // Make sure class is a DFBuilder instance
             // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
        
             Class<?> temp = c;
        
             while (true)
        
                 if (temp == null)                   continue TOP;
                 else if (temp == Object.class)      continue TOP;
                 else if (temp == DFBuilder.class)   break;
                 else                                temp = temp.getSuperclass();
        
        
             // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
             // Instantiate and call instance buildAll()
             // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
        
             final DFBuilder dfb;
        
             try
                 { dfb = ((Class<DFBuilder>) c).getDeclaredConstructor().newInstance(); }
        
             catch (Exception e)
             {
                 System.out.println(
                     "Unable to instantiate DFBuilder.\n" +
                     "Do you have a Zero-Argument Public Constructor?\n" +
                     EXCC.toString(e)
                 );
        
                 System.exit(1);
                 return -1; // Shut-Up Compiler
             }
                    
             counter++;
             dfb.buildAll(dirName);
         }
        
         return counter;
        
      • cli

        🡅     🗕  🗗  🗖
        public final boolean cli​(int menuOptions,
                                 java.lang.String[] argv)
        This method is intended to be used by classes that inherit this abstract class. Classes that inherit DFBuilder may add a method into their implementation, as in the hilited source-code below. This provides a standard Java 'Main'-Method that may be invoked as a CLI: Command Line Interface.

        Example:
         // The class extending DFBuilder can use this method so that it can be invoked at the
         // command line.  Passing '1' means that only the 'buildAll' was written by the extending
         // Type.
         
         public static void main(String[] argv) { new YourDataFileBuilder().cli(1, argv); }
        
        Parameters:
        menuOptions - The value passed to this parameter must be one of the values excplicitly named in this set: 1, 2, 3, 4, 6. Any value other than these 5 numbers will force this method to throw an IllegalArgumentException.

        This meaning of these is clearly explained, in the table below:

        'menuOptions'Meaning
        '1' The only method implemented is the buildAll method. The others, on invokation, will throw the UnsupportedOperationException
        '3' 3 => 1 & 2
        Methods buildAll and buildAllToText are implemented, and may be invoked.

        Attempting to call deCompileAllToText would cause an UnsupportedOperationException to throw.
        '4' 4 => 1 & 3
        Methods buildAll and deCompileAllToText are implemented, and may be invoked.

        Attempting to call buildAllToText would cause an UnsupportedOperationException to throw.
        '6' 6 ==> 1, 2 & 3
        All three methods exported by this class have been implemented, and may be invoked without worry that the UnsupportedOperationException will throw.
        argv - The Command-Line Parameter String[]-Array. This should just be the argv-Array that was sent to the actual Java 'Main'-Method that his invoking this helper.
        Returns:
        TRUE if and only if the invoked builder method terminated successfully.
        Code:
        Exact Method Body:
         if ((menuOptions < 1) || (menuOptions > 6) || (menuOptions == 2) || (menuOptions == 5))
        
             throw new IllegalArgumentException(
                 "Parameter 'menuOptions' must be a value in this set: [1, 3, 4, 6]\n" + 
                 "These are the only valid values to pass here, but [" + menuOptions + "] was " +
                     "provided, instead."
             );
        
         if ((argv.length != 1) && (argv.length != 2))
         {
             printManPage(menuOptions);
             return false;
         }
        
         final boolean   twoOK   = (menuOptions == 3) || (menuOptions == 6);
         final boolean   threeOK = (menuOptions == 4) || (menuOptions == 6);
         final String    dirName = (argv.length == 2) ? argv[1] : "";
        
         try
         {
             switch (argv[0])
             {
                 case "1":
                     buildAll(dirName);
                     break;
        
                 case "2":
                     if (twoOK)  buildAllToText(dirName);
                     else        printManPage(menuOptions);
                     break;
        
                 case "3":
                     if (threeOK)    deCompileAllToText(dirName);
                     else            printManPage(menuOptions);
                     break;
             }
         }
        
         catch (Exception e)
         {
             System.out.println(
                 "This DFBuilder Instance has thrown an Exception while writing a File:\n" +
                 EXCC.toString(e) + '\n'
             );
        
             return false;
         }
        
         return true;