Class HELPER


  • public class HELPER
    extends java.lang.Object
    Helper for parsing Java Source-Code using Java-Parser. Also contains several utilities for reading directly from Java '.class' Files using reflection methods and features.



    Stateless Class:
    This class neither contains any program-state, nor can it be instantiated. The @StaticFunctional Annotation may also be called 'The Spaghetti Report'. Static-Functional classes are, essentially, C-Styled Files, without any constructors or non-static member fields. It is a concept very similar to the Java-Bean's @Stateless Annotation.
    • 1 Constructor(s), 1 declared private, zero-argument constructor
    • 36 Method(s), 36 declared static
    • 2 Field(s), 2 declared static, 2 declared final


    • Method Summary

       
      Misc Utility
      Modifier and Type Method
      static void addMetaTags​(List<HTMLNode> page, Upgrade u, String dotDots)
       
      Find Files or Directories in the CLASSPATH
      Modifier and Type Method
      static Stream<String> findFileFromPackageDirList​(String simpleFileName, String[] rootPackageSourceFileDirectories)
      static String findFileNameInClassPath​(String partialFileName, String[] rootSourceFileDirectories, boolean fileOrDirectory)
      static Stream<String> findSrcDirInClassPath​(String packageName, String[] rootSourceFileDirectories)
      static Stream<String> findUpgradeDirInClassPath​(byte userUpgradeDir, String packageName, String[] rootSourceFileDirectories)
      static Stream<String> findUpgradeDirInClassPath​(String[] rootPackageSourceFileDirectories)
      static Stream<String> findUpgradeDirInClassPath​(String packageName, String[] rootSourceFileDirectories)
       
      Manually load a Java '.class' Files & Static-Fields
      Modifier and Type Method
      static Field getStaticField​(Class<?> c, String fieldName, Class<?> expectedFieldType, String classFileName, JDUProcessor jdup)
      static Object getStaticFieldEvaluation​(Field f, String classFileName, JDUProcessor jdup)
      static Class<?> readClass​(String classFileName, byte userUpgradeDirectory, String className, String packageName)
       
      Fun with Java Parser™ (Utilities)
      Modifier and Type Method
      static Ret2<Integer,​Integer> countMethodsFields​(TypeDeclaration<?> td)
      static CIET getCIET​(TypeDeclaration<?> td)
      static String[] getExtendedTypes​(NodeList<type.ClassOrInterfaceType> extendedTypes)
      static String[] getGenericTypeParameters​(CompilationUnit cu, String name, CIET kind)
      static String[] getGenericTypeParameters​(NodeList<type.TypeParameter> genericTypeParameters)
      static String[] getImplementedTypes​(NodeList<type.ClassOrInterfaceType> implementedTypes)
      static Ret3<String,​String,​String> getInnerTypeNames​(TypeDeclaration<?> td)
      static String getPackageName​(CompilationUnit cu)
      static boolean isContainedByCorrectCIET​(Optional<Node> p, String name)
       
      Fun with Oracle's com.sun.source.tree
      Modifier and Type Method
      static Ret2<Integer,​Integer> countMethodsFields​(com.sun.source.tree.ClassTree ct, CIET ciet)
      static CIET getCIET​(com.sun.source.tree.ClassTree ct)
      static String[] getExtendedTypes​(com.sun.source.tree.ClassTree ct)
      static String[] getGenericTypeParameters​(com.sun.source.tree.ClassTree ct)
      static String[] getImplementedTypes​(com.sun.source.tree.ClassTree ct)
      static Ret3<String,​String,​String> getInnerTypeNames​(com.sun.source.tree.ClassTree ct, TreeUtils util)
       
      Debugging / Difference Engine Helpers (For Internal Use)
      Modifier and Type Method
      static void diff​(boolean b1, boolean b2, String bName, Appendable a, String indentation)
      static void diff​(int int1, int int2, int radix, String intName, Appendable a, String indentation)
      static void diff​(int int1, int int2, String intName, Appendable a, String indentation)
      static void diff​(String[] arr1, String[] arr2, String arrName, Appendable a, String indentation)
      static void diff​(String s1, String s2, String sName, Appendable a, String indentation, boolean separateLines)
      static void diffModifiers​(String[] arr1, String[] arr2, Appendable a, String indentation)
      static void diffMultiLine​(String s1, String s2, String sName, Appendable a, String indentation)
      static void diffParamTypes​(String[] arr1, String[] arr2, String arrName, Appendable a, String indentation)
      static void diffType​(String s1, String s2, String sName, Appendable a, String indentation, boolean separateLines)
      • Methods inherited from class java.lang.Object

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

      • addMetaTags

        🡇    
        public static void addMetaTags​(java.util.List<HTMLNode> page,
                                       Upgrade u,
                                       java.lang.String dotDots)
        Code:
        Exact Method Body:
         TagNode favicon=null;
        
        
         // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
         // Build the FAVICON <LINK> element.
         // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
        
         if (u.faviconImageFileName != null)
         {
             // Retrieve the 'favicon' <LINK> element from the headerTags to insert list.
             favicon = (TagNode) u.headerTags.elementAt(Upgrade.FAV_HEADER_TAG_VEC_POS);
        
             // Insert a new 'favicon' with the correct relative-path string to the root
             // Java Doc directory.
             //
             // IMPORTANT: Do **NOT** clobber the original 'favicon' link, because the next insert
             //            (For another file) will need to do this String-Replace again!
        
             u.headerTags.setElementAt(
                 new TagNode(favicon.str.replace("DOTDOTS", dotDots)),
                 Upgrade.FAV_HEADER_TAG_VEC_POS
             );
         }
        
         // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
         // Build the JavaDoc.css <LINK> element
         // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
        
         // Retrieve the 'JavaDoc.css' <LINK> element from the headerTags to insert list.
         TagNode cssFileLink = (TagNode) u.headerTags.elementAt(Upgrade.CSS_URL_HEADER_TAG_VEC_POS);
                
         // Insert a new 'CSS-File Link' with the correct relative-path string to the root
         // Java Doc directory.
         //
         // AGAIN: Do **NOT** clobber cssFileLink.  The next file will need the original one
         //        that has the String "DOTDOTS" so it can do the replacement for a differnt
         //        location
        
         // The original one has to be kept and put back into the vector!  Don't clobber it!
         TagNode newCSSFileLink = new TagNode(cssFileLink.str.replace("DOTDOTS", dotDots));
        
         u.headerTags.setElementAt(newCSSFileLink, Upgrade.CSS_URL_HEADER_TAG_VEC_POS);
        
        
         // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
         // Build the JavaScript <SCRIPT> element.
         // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
        
         // Retrieve the 'JavaScript' <SCRIPT> element from the headerTags to insert list.
         TagNode upgraderJavaScript = (TagNode) u.headerTags.elementAt
             (Upgrade.JAVA_SCRIPT_HEADER_TAG_VEC_POS);
        
         // Set the <SCRIPT> with the correct relative-path string to the root Java Doc directory.
         TagNode newUpgraderJavaScript = new TagNode
             (upgraderJavaScript.str.replace("DOTDOTS", dotDots));
        
         u.headerTags.setElementAt
             (newUpgraderJavaScript, Upgrade.JAVA_SCRIPT_HEADER_TAG_VEC_POS);
        
        
         // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
         // NOW ADD THE HEADER TAGS
         // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
        
         // Add all to the position AFTER the <HEAD> tag
         page.addAll(1, u.headerTags);
        
        
         // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
         // NOW DO THE CLEAN UP FOR THE NEXT PAGE - PUT THE ORIGINAL/UNREPLACED VERSIONS BACK!
         // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
        
         // Setup the 'headerTags' Vector for the next file.
         // SPECIFICALLY: Put original TagNode's back, because they have the replace-string
         // REMEMBER:     The "DOTDOTS" replace-string was removed a few lines previously.  If you
         //               don't put the "un-replaced" version back, then this whole thing falls
         //               apart!
            
         u.headerTags.setElementAt(cssFileLink, Upgrade.CSS_URL_HEADER_TAG_VEC_POS);
         u.headerTags.setElementAt(upgraderJavaScript, Upgrade.JAVA_SCRIPT_HEADER_TAG_VEC_POS);
        
         if (u.faviconImageFileName != null)
             u.headerTags.setElementAt(favicon, Upgrade.FAV_HEADER_TAG_VEC_POS);
        
      • findFileNameInClassPath

        🡅  🡇    
        public static java.lang.String findFileNameInClassPath​
                    (java.lang.String partialFileName,
                     java.lang.String[] rootSourceFileDirectories,
                     boolean fileOrDirectory)
        
        Searches the root source directories for a particular file (or directory)
        Parameters:
        partialFileName - This String will be appended to the end of each & every one of the String's inside 'rootSourceFileDirectories' until a file-name that exists on the file-system has been found - or all root sorce-code directories have been checked for this 'partialFileName'
        rootSourceFileDirectories - This is the 'CLASSPATH', as it is implemented inside Java HTML. The contents of this String[] are actually stored inside the class Upgrade.
        fileOrDirectory - If TRUE is passed, this will look for a file, and if FALSE is passed to this parameter, this method will look for a directory.
        Returns:
        This returns the complete filename and path of partialFileName where it was located among the directories listed by rootSourceFileDirectories.

        If partialFileName is not located within any of the rootSourceFileDirectories, then null is returned. null will also be returned if partialFileName is located, but does not match the type/kind specified by parameter fileOrDirectory.
        Code:
        Exact Method Body:
         for (String rootSrcDir : rootSourceFileDirectories)
         {
             String fName = rootSrcDir + partialFileName;
        
             File f = new File(fName);
        
             // Remember, there cannot be another file with the exact same name that was a
             // directory (if this one is a file), and vice-versa... 
             //
             // If the file (or directory) *DOES EXIST*, make sure that it matches the type/kind
             // that was specified by input parameter 'fileOrDirectory' (TRUE for file, and FALSE
             // for directory).
        
             if (f.exists())
        
                 if ((fileOrDirectory && f.isFile()) || ((! fileOrDirectory) && f.isDirectory()))
        
                     return fName;
         }
        
         return null;
        
      • findUpgradeDirInClassPath

        🡅  🡇    
        public static java.util.stream.Stream<java.lang.String> findUpgradeDirInClassPath​
                    (byte userUpgradeDir,
                     java.lang.String packageName,
                     java.lang.String[] rootSourceFileDirectories)
        
        This method will locate any one of the user-provided configuration sub-directories of the primary upgrade-files/ directory. Currently there are three potential / possible sub-directories of upgrade-files/. This method takes requests to find any one of those three directories. The three are explicity listed below, in the table for input parameter 'userUpgradeDir'.

        Java does allow a user to keep class files for a particular package in more than one directory - as long as the CLASSPATH environment-variable has been properly configured. When this occurs, this method is capable of returning all directories for that match the search.

        Please note that in the list below, all three of these configuration-class directories are actually directories for the exact same Java-Package (which happens to be package com.MyPackage). This is an example of a Java-Package that has code which is being contributed from three different locations, and therefore is a Package that could also easily have three different 'upgrade-files/config-classes/' directories as well.

        • src/main/com/MyPackage/upgrade-files/config-classes/
        • alt-src/main/com/MyPackage/upgrade-files/config-classes/
        • contractor/code/main/com/MyPackage/upgrade-files/config-classes/

        If a user were to be looking for the 'config-classes/' configuration directory, all three of the above directories would be returned within the Stream<String> from a call to this method.
        Parameters:
        userUpgradeDir - There are only three valid values that may be passed to this parameter. Each one indicates a different one of the upgrade-files/ user specified directories. This parameter is of type byte merely to remind the programmer of the limited values, and (hopefully) to look at this documentation before calling this method.

        Byte ValueMeaning
        1"upgrade-files/config-classes/"
        2"upgrade-files/external-html/"
        3"upgrade-files/user-processors/"
        defaultMessager assert-fail
        packageName - This should be the fully-specified package for which a user configuration directory (or set of directories - since a package can actually exist across multiple locations) is sought.
        rootSourceFileDirectories - This is the 'CLASSPATH', as it is implemented inside Java HTML. The contents of this String[] are actually stored inside the class Upgrade.
        Returns:
        A Stream of Java String's for all matching directories. If no such directory is found, and empty Stream will be returned.
        Code:
        Exact Method Body:
         String partialDirName = packageName.replace(".", File.separator) + File.separator +
             "upgrade-files" + File.separator;
        
         Stream.Builder<String> b = Stream.builder();
        
         switch (userUpgradeDir)
         {
             case 1: partialDirName += "config-classes";     break;
             case 2: partialDirName += "external-html";      break;
             case 3: partialDirName += "user-processors";    break;
        
             default: Messager.assertFailGeneralPurpose(
                 "An incorrect byte-value [" + userUpgradeDir + "] has been passed to the " +
                 "'userUpgradeDirectory'.\n",
                 null
             );
         }
        
         for (String rootSrcDir : rootSourceFileDirectories)
         {
             String fName = rootSrcDir + partialDirName;
        
             File f = new File(fName);
        
             if (f.exists() && f.isDirectory()) b.accept(fName + File.separator);
         }
        
         return b.build();
        
      • findUpgradeDirInClassPath

        🡅  🡇    
        public static java.util.stream.Stream<java.lang.String> findUpgradeDirInClassPath​
                    (java.lang.String packageName,
                     java.lang.String[] rootSourceFileDirectories)
        
        This method will locate all copies of the user-provided configuration sub-directory upgrade-files/.

        Java does allow a user to keep class files for a particular package in more than one directory - as long as the CLASSPATH environment-variable has been properly configured. When this occurs, this method is capable of returning all directories for that match the search.

        Please note that in the list below, all three ../upgrade-files/ directories are actually directories for the exact same Java-Package! (which happens to be package com.MyPackage). This is an example of a Java-Package that has code which is being contributed from three different locations. In this case, this is also a Java Package with three separate 'upgrade-files/' directories as well.

        • src/main/com/MyPackage/upgrade-files/
        • alt-src/main/com/MyPackage/upgrade-files/
        • contractor/code/main/com/MyPackage/upgrade-files/

        All three of the above directories would be returned within the Stream<String> from a call to this method.
        Parameters:
        packageName - This should be the fully-specified package for which a user configuration directory (or set of directories - since a package can actually exist across multiple locations) is sought.
        rootSourceFileDirectories - This is the 'CLASSPATH', as it is implemented inside Java HTML. The contents of this String[] are actually stored inside the class Upgrade.
        Returns:
        A Stream of Java String's for all matching directories. If no such directory is found, and empty Stream will be returned.
        Code:
        Exact Method Body:
         String partialDirName = packageName.replace(".", File.separator) + File.separator +
             "upgrade-files";
        
         Stream.Builder<String> b = Stream.builder();
        
         for (String rootSrcDir : rootSourceFileDirectories)
         {
             String fName = rootSrcDir + partialDirName;
        
             File f = new File(fName);
        
             if (f.exists() && f.isDirectory()) b.accept(fName + File.separator);
         }
        
         return b.build();
        
      • findUpgradeDirInClassPath

        🡅  🡇    
        public static java.util.stream.Stream<java.lang.String> findUpgradeDirInClassPath​
                    (java.lang.String[] rootPackageSourceFileDirectories)
        
        This method will locate all copies of the user-provided configuration sub-directory upgrade-files/. This is the third method in the series of methods for locating configuration and upgrade directories in the class-path. This method differs from the previous two methods of the same-name as this one - in that it expects as input a list of valid package source-code directories, rather than a list of CLASSPATH directories.

        In short, this version of 'findUpgradeDirInClassPath' simply checks each of the input-directories to identify if there is an upgrade-files/ sub-directory. When one is found, the full-path / complete name of that sub-directory as added to the returned Java-Stream.
        Parameters:
        rootPackageSourceFileDirectories - This parameter is best generated by a call to {@link #findSrcDirInClassPath(String, String[])}. This String[]-Array should contain the source-code directories for one single Java-Package. Remember that it is possible for a Java-Package to have source-code strewn across several actual directories, using the magic of the CLASSPATH environment-variable.

        Again, this parameter should contain all directories that contain source-code '.java' and '.class' files for a single Java Package.
        Returns:
        A Stream of Java String's for all matching directories. If no such directory is found, and empty Stream will be returned.
        Code:
        Exact Method Body:
         Stream.Builder<String> b = Stream.builder();
        
         for (String rootPackageSrcDir : rootPackageSourceFileDirectories)
         {
             String fName = rootPackageSrcDir + "upgrade-files";
        
             File f = new File(fName);
        
             if (f.exists() && f.isDirectory()) b.accept(fName + File.separator);
         }
        
         return b.build();
        
      • findSrcDirInClassPath

        🡅  🡇    
        public static java.util.stream.Stream<java.lang.String> findSrcDirInClassPath​
                    (java.lang.String packageName,
                     java.lang.String[] rootSourceFileDirectories)
        
        Finds all matching Java Source-Code Directories inside of a given "Class-Path." Note that at the present time, this CLASSPATH may only contain directory-names, and may not contain '.jar' files!
        Parameters:
        packageName - This should be the fully-specified package for which a user configuration directory (or set of directories - since a package can actually exist across multiple locations) is sought.
        rootSourceFileDirectories - This is the 'CLASSPATH', as it is implemented inside Java HTML. The contents of this String[] are actually stored inside the class Upgrade.
        Returns:
        A Stream of Java String's for all matching directories. A directory is considered "matching" if the portion of the directory name that follows the part from the 'rootSourceFileDirectories' matches the 'packageName' exactly. The only difference in this match would be that all '.' (period/dot) characters will have replaced by the Operating System's File-Separator character.

        If no such directory is found, and empty Stream will be returned.
        Code:
        Exact Method Body:
         String partialDirName = packageName.replace(".", File.separator);
        
         Stream.Builder<String> b = Stream.builder();
        
         for (String rootSrcDir : rootSourceFileDirectories)
         {
             String fName = rootSrcDir + partialDirName;
        
             File f = new File(fName);
        
             if (f.exists() && f.isDirectory()) b.accept(fName + File.separator);
         }
        
         return b.build();
        
      • findFileFromPackageDirList

        🡅  🡇    
        public static java.util.stream.Stream<java.lang.String> findFileFromPackageDirList​
                    (java.lang.String simpleFileName,
                     java.lang.String[] rootPackageSourceFileDirectories)
        
        Given a list of potential Source-Code Directories, this method will return the full and complete name of a Source-Code File when-and-if a directory in the 'srcDirList' parameter has such a Java '.java' Source-Code File.
        Parameters:
        simpleFileName - The Simple Java '.java' Source-Code File-Name. The value of this parameter should just be the file-name WITHOUT any parent or containing directory-name information included.
        rootPackageSourceFileDirectories - This parameter is best generated by a call to {@link #findSrcDirInClassPath(String, String[])}. This String[]-Array should contain the source-code directories for one single Java-Package. Remember that it is possible for a Java-Package to have source-code strewn across several actual directories, using the magic of the CLASSPATH environment-variable.

        Again, this parameter should contain all directories that contain source-code '.java' and '.class' files for a single Java Package.
        Returns:
        A list of all files whose name matches 'simpleFileName' and whose directory location is in one of the directories listed in 'srcDirList'
        Code:
        Exact Method Body:
         Stream.Builder<String> b = Stream.builder();
        
         for (String rootSrcDir : rootPackageSourceFileDirectories)
         {
             String fName = rootSrcDir + File.separator + simpleFileName;
        
             File f = new File(fName);
        
             if (f.exists() && f.isFile()) b.accept(fName);
         }
        
         return b.build();
        
      • readClass

        🡅  🡇    
        public static java.lang.Class<?> readClass​(java.lang.String classFileName,
                                                   byte userUpgradeDirectory,
                                                   java.lang.String className,
                                                   java.lang.String packageName)
        This method simply wraps the FileRW method FileRW.readClass(String, String[]) - and does all of the necessary error messaging. This method is largely used to ensure that consistent error messaging is provided for any operations that load user-provided class files into memory. This method simply reads a specified Java '.class' file into memory, and returns a java.lang.Class object.

        NOTE: All Messager errors are fatal and, when used, will result in a fatal-exception throw without a return value.
        Parameters:
        classFileName - The exact file-name that contains the '.class' file to load.
        userUpgradeDirectory - This is used for Messager error-reporting. This value that may be passed are listed in the table below. Again this value is used, strictly, for proper error reporting with the Messager.

        Byte Value Meaning
        1 ../upgrade-files/config-classes/
        2 ../upgrade-files/user-processors/
        default Messager - assert fail!


        This parameter is of type 'byte' to make sure you pay close attention to what value is being passed. As of now, there are only 2 valid values. Remember to cast Java numeric-literals using the syntax: (byte).

        ALSO: The value for this parameter could be easily extracted / computed from the 'classFileName' parameter, but for brevity and efficiency this redundant value must be passed as a parameter
        className - The simple (Just One Word!) name of the configuration or user-processor class. Three of the classes that are read using this method are: 'PackageSummarySort', 'SummarySorters' and 'ExtraHiLitedSrc'. These are valid values to pass to this parameter.
        packageName - This package-name should be the name of the package which the configuration class or user-processor class is operating on. The 'readClass' method checks multiple possible package-names when reading a '.class' file from disk.
        Returns:
        The requested '.class' file as an instance of Java's 'Class' class.
        Throws:
        JavaDocError - On a TypeNotPresentException - when the user did not declare the appropriate package on his class.
        UpgradeException - If there are any IOException's or other unknown exceptions when reading the class file.
        Code:
        Exact Method Body:
         // The only purpose of this whole method is to guarantee that whenever any of the classes
         // in this tool make use of the "FileRW.readClass" method - which literally just reads a
         // '.class' file from disk into memory as a Java "Class" isntance...  Whenever that is done
         // on the upgrade-files/ classes IF THERE ARE ANY ERRORS, THE MESSAGES WILL ALL BE THE
         // SAME / CONSISTENT
         //
         // As of June 20th, 2023 there are three places where the FileRW.readClass method is
         // used, and there is going to be a fourth one soon.
        
         try 
             { return FileRW.readClass(classFileName, packageName + '.' + className, className); }
        
         catch (IOException ioe)
         {
             Messager.setCurrentFileName(classFileName, USER_PROVIDED_CLASS_FILE);
        
             return Messager.assertFailGeneralPurpose(
                 ioe,
                 "IOException throw while reading '.class' file from Disk.\n" +
                 DESCRIPTION(userUpgradeDirectory, className),
                 null
             );
         }
        
         catch (TypeNotPresentException tnpe)
         {
             Messager.setCurrentFileName(classFileName, USER_PROVIDED_CLASS_FILE);
        
             return Messager.userErrorHalt(
                 tnpe,
                 "TypeNotPresentException thrown while attempting to load '.class' file from disk.\n" +
                 DESCRIPTION(userUpgradeDirectory, className) +
                 "Loading a Configuration or Processor Class requires a correct Package-Name to be " +
                     "placed onto that class.\n" +
                 "Valid Package Names are:\n" +
                 "    1) No Package-Name  2) Same Package-Name as the Package it's configuring\n" +
                 "Cannot Load Class File:[" + BCYAN + classFileName + RESET + "]"
             );
         }
        
         catch (Exception e)
         {
             Messager.setCurrentFileName(classFileName, USER_PROVIDED_CLASS_FILE);
        
             return Messager.assertFailGeneralPurpose(
                 e,
                 "Unexpected Exception thrown attempting to load class.\n" +
                 DESCRIPTION(userUpgradeDirectory, className),
                 null
             );
         }
        
      • getStaticField

        🡅  🡇    
        public static java.lang.reflect.Field getStaticField​
                    (java.lang.Class<?> c,
                     java.lang.String fieldName,
                     java.lang.Class<?> expectedFieldType,
                     java.lang.String classFileName,
                     JDUProcessor jdup)
        
        Retrieves an instance of java.lang.reflect.Field from a class, using soley the expected name of that field. Error checks are done to make sure that the field has been declared according to an "expected type". If it is not properly declared, then error messages are printed to the messager.
        Parameters:
        c - The class that ought to contain the field (the one specified by parameter 'fieldName').
        fieldName - The name of a public and static field contained by class 'c'. This field's reflection-mirror will be extracted.
        expectedFieldType - The type that the field is supposed to have. If the field does not have this type, or is not assignable-from this type, an error message is printed to the messager, and null is returned.
        classFileName - The file-name from whence class 'c' was loaded. This is strictly used by the messager, in case of error, to ensure a proper error-message. The filename is not used to load the class from disk, that must be done by the user before even calling this method.
        jdup - Used by the Messager for better error-reporting. Indicates which of the processors is making this call. Because this method utilizes the "Error Continue" methods offered by the Messager, it is better to pass this processor as a parameter rather than getting the processor by generating a StackTraceElement[]-Array (by throwing a miscellaneous exception).
        Returns:
        The java.lang.reflect.Field whose name is consistent with 'fieldName', and type is consistend with 'expectedFieldType'. If no such field exists, then null is returned.
        Code:
        Exact Method Body:
         java.lang.reflect.Field f = null;
        
         try 
             { f = c.getField(fieldName); }
        
         catch (NoSuchFieldException e)
         {
             Messager.userErrorContinue(
                 "User-Provided Source-Code Configuration-Class File:\n" +
                 "\t[" + BYELLOW + classFileName + RESET + "]\n" +
                 "There does not appear to contain a 'public' " +
                 BGREEN + expectedFieldType.getCanonicalName() + RESET + " Field named '" +
                 BGREEN + fieldName + RESET + "'.  Please review the documentation for this " +
                 "configuration-class.",
                 jdup
             );
        
             return null;
         }
        
         catch (Exception e)
         {
             Messager.userErrorContinue(
                 e,
                 "User-Provided Source-Code Configuration-Class File:\n" +
                 "\t[" + BYELLOW + classFileName + RESET + "]\n" +
                 "An exception was thrown while attempting to access the " + 
                 BGREEN + expectedFieldType.getCanonicalName() + RESET + " Field named '" +
                 BGREEN + fieldName + RESET + "'.",
                 jdup
             );
        
             return null;
         }
        
         if ((f.getModifiers() & java.lang.reflect.Modifier.STATIC) == 0)
         {
             Messager.userErrorContinue(
                 "User-Provided Source-Code Configuration-Class File:\n" +
                 "\t[" + BYELLOW + classFileName + RESET + "]\n" +
                 "Field [" + BGREEN + fieldName + RESET + "] was not declared 'static'",
                 jdup
             );
        
             return null;
         }
        
         Class<?> fieldType = f.getType();
        
         if (! expectedFieldType.isAssignableFrom(fieldType))
         {
             Messager.userErrorContinue(
                 "User-Provided Source-Code Configuration-Class File:\n" +
                 "\t[" + BYELLOW + classFileName + RESET + "]\n" +
                 "Field [" + BGREEN + fieldName + RESET + "] has a declared-type of '" +
                 BRED + fieldType.getCanonicalName() + RESET + "', but " +
                 "the type should be\n:\t" +
                 "'" + BGREEN + expectedFieldType.getCanonicalName() + RESET + "'.",
                 jdup
             );
        
             return null;
         }
        
         else return f;
        
      • getStaticFieldEvaluation

        🡅  🡇    
        public static java.lang.Object getStaticFieldEvaluation​
                    (java.lang.reflect.Field f,
                     java.lang.String classFileName,
                     JDUProcessor jdup)
        
        This only real purpose of this method is to do BOTH consistent error-checking for all potential problems during the actual Field-lookup here, AND make sure that any error-messages printed (in the event of an error) are consistent and explanatory.

        USE: This method is used when reading the user-defined configuration-classes PackageSummarySort and ExtraHiLitedSrc that may be placed in their 'somePackageDir/upgrade-files/config-classes/' directories.
        Parameters:
        f - This is presumed to be a 'static' field inside of whatever class it was derived.

        NOTE: This method will not do any exception checks on the input-parameter 'f'. The name of this method does, indeed, imply that the passed field parameter 'f' must be a 'static' member of whatever 'class' in which it resides.
        classFileName - The only reason for passing this file-name String as a parameter here - is for error-printing purposes. This parameter needs to contain the original file-name of the '.class' file from which the Field parameter 'f' was retrieved.

        NOTE: At the time of the writing of this method, the feature which was being written that necessitated this method was one of the features where a User-Provided '.class'-File (one which acts as a "Configuration Class") is loaded from disk, and used to configure the feature. (These were 'SummarySorters' and 'ExtraHiLitedSrc').
        jdup - Used by the Messager for better error-reporting. Indicates which of the processors is making this call. Because this method utilizes the "Error Continue" methods offered by the Messager, it is better to pass this processor as a parameter rather than getting the processor by generating a StackTraceElement[]-Array (by throwing a miscellaneous exception).
        Returns:
        The value of the 'static' member-field 'f'
        Code:
        Exact Method Body:
         Object ret = null;
        
         // This needs to be checked, so that if there is a NullPointerException resulting from
         // attempting to evaluate 'f' on 'null' - BUT 'f' IS NOT STATIC...
         //
         // NOTE: Handled using an exception, rather than the messager, because it could only be
         //       thrown if somebody else was using this method.  My use of this will not call this
         //       method if the field is not found (and therefore null).
        
         if (f == null)
             throw new NullPointerException("You have passed null to Field parameter 'f'");
        
         // It is presumed that the field 'f' is a static field.  This means that there is no need
         // to evaluate this "field.get(...)" method using an object.  Passing 'null' here is how to
         // evaluate a 'java.lang.reflect.Field' when that field is declared using the 'static' 
         // modifier.
        
         try
             { ret = f.get(null); }
        
         // A "Java Acces Control Rule" (seems very unlikely - I don't have any idea, and it has
         // never happened to me, The Sun-Oracle Docs say it could possibly be thrown).  Note that
         // this is actually a "Checked Exception"
        
         catch (IllegalAccessException e)
         {
             Messager.userErrorContinue(
                 "Apparently a Java Language Access Control rule is being enforced, and the " +
                 "static " + ERROR_MESSAGE(f, classFileName) + '\n' +
                 "cannot be accessed.",
                 jdup
             );
        
             return null;
         }
        
         // This actually could happen, theoretically, if the user had static-initializers
         // in his code.  This error is thrown when the 'Class' cannot be loaded by the ClassLoader
         // because of an error that occured in a "Static-Initializer"  - If you forgot what than is
         // it is Java Code that isn't inside a method, but rather a "static { ... code }" block
        
         catch (ExceptionInInitializerError e)
         {
             Throwable thrown = e.getException();
        
             Messager.userErrorContinue(
                 "While attempting to load " + ERROR_MESSAGE(f, classFileName) +
                 "Apparently there was an Exception or Throwable that was thrown inside of one " +
                 "of the static initializer's located inside that class" +
                 ((thrown != null) ? (":\n" + EXCC.toString(thrown, 4)) : ""),
                 jdup
             );
        
             return null;
         }
        
         catch (NullPointerException e)
         {
             // Unless somebody else is using this little HELPER thing, this is essentially an
             // "UnreachableError" situation.  This could only be thrown if the Field was not
             // a "static" field, but rather an "instance" field.
             //
             // NOTE: For effeciency, this isn't checked at the top of this method.
             //
             // ALSO: The NPE Check at the top of this method is to make sure that *THIS* Field
             //       (parameter 'f') is NON-NULL.  However, if the field was an "instance" field,
             //       not a "static" field, according to the Java Sun/Oracle JavaDoc Page, then
             //       this exception would throw.  I'm changing the wording, and the exception name.
             //
             // NOTE: THIS STATEMENT IS UNREACHABLE - UNLESS FIELD IS NON-STATIC, BUT THAT WAS THE
             //       PRE-REQUISITE FOR USING THIS METHOD.
        
             throw new IllegalArgumentException(
                 "While attempting to load " + ERROR_MESSAGE(f, classFileName) +
                 "A NullPointerException was thrown when attempting to evaluate what was " +
                 "thought to be a 'static' java.lang.reflect.Field using field.get(null).  " +
                 "Did you check whether the Field had the 'static' modifier before asking this " +
                 "method to evaluate it.",
                 e
             );
         }
        
         // If this static field actually equals null, make sure to report that to the messager. 
         // This is only used for "User Configuration Classes" - and none of them really accept 
         // null as a value, and therefore it would always be tantamount to user error.
        
         if (ret == null)
         {
             Messager.userErrorContinue
                 (ERROR_MESSAGE(f, classFileName) + "the field evaluated to null.", jdup);
        
             return null;
         }
        
         return ret;
        
      • getCIET

        🡅  🡇    
        public static CIET getCIET​
                    (com.github.javaparser.ast.body.TypeDeclaration<?> td)
        
        Finds the "kind" of a type. The "kind" is one of many ways of expressing the word "type". "Type," thus-far, has been referred to by the acronym CIET. A "kind of type" is a class, interface, enum, annotation or record. This is the complete list of possible declarations from a '.java' source-code file.

        HELPER METHOD: org.github.javaparser Java-Parser ™ AST-Compiler
        Parameters:
        td - A Java-Parser Type-Declaration. The sub-classes of TypeDeclaration include: ClassOrInterfaceDeclaration, EnumDeclaration, AnnotationDeclaration and RecordDeclaration.
        Returns:
        The CIET constant that maps to the Java-Parser type.
        Code:
        Exact Method Body:
         if (td.isEnumDeclaration())
             return CIET.ENUM;
        
         else if (td.isAnnotationDeclaration())
             return CIET.ANNOTATION;
        
         else if (td.isClassOrInterfaceDeclaration())
             return td.asClassOrInterfaceDeclaration().isInterface() ? CIET.INTERFACE : CIET.CLASS;
        
         // *** NOT-IMPLEMENTED YET ***
         // else if (td.isRecordDeclaration()) this.ciet = CIET.RECORD;
        
         return null;
        
      • getInnerTypeNames

        🡅  🡇    
        public static Ret3<java.lang.String,​java.lang.String,​java.lang.String> getInnerTypeNames​
                    (com.github.javaparser.ast.body.TypeDeclaration<?> td)
        
        Retrieves relevant name String's for an enclosed-class. Returned are the package-name, the fully-qualified name (not including the generic-type parameter's expression - <T, U>), and the name including all container-types.

        This method is only useful for classes that are enclosed by another class, specifically classes & types defined inside of another type '.java' file.

        HELPER METHOD: org.github.javaparser Java-Parser ™ AST-Compiler
        Parameters:
        td - A Java-Parser Type-Declaration that is an inner-class (a type which is defined / enclosed by another type - for instance java.util.Map.Entry).
        Returns:
        Ret3<String, String, String> instance:

        • Ret3.a String
          Package-Name

        • Ret3.b String
          Class-Name, including *all* Enclosing-Classes

        • Ret3.c String
          Fully Qualified Name

        Code:
        Exact Method Body:
         String packageName = null;
        
         Optional<Node>  p   = td.getParentNode();
         StringBuilder   sb  = new StringBuilder();
        
         sb.append(td.getNameAsString());
         for (Node n; p.isPresent(); p = n.getParentNode())
         {
             n = p.get();
        
             if (n instanceof TypeDeclaration)
                 sb.insert(0, ((TypeDeclaration) n).getName().asString() + '.');
        
             if (n instanceof CompilationUnit)
                 packageName = getPackageName((CompilationUnit) n).trim();
         }
        
         String nameWithContainer = sb.toString().trim();
        
         String fullyQualifiedName =
             (((packageName != null) && (packageName.length() > 0))
                 ? (packageName + '.')
                 : "") +
             nameWithContainer;
        
         return new Ret3<>(packageName, nameWithContainer, fullyQualifiedName);
        
      • getPackageName

        🡅  🡇    
        public static java.lang.String getPackageName​
                    (com.github.javaparser.ast.CompilationUnit cu)
        
        Retrieves the Package-Name from an instance of Java-Parser class CompilationUnit

        HELPER METHOD: org.github.javaparser Java-Parser ™ AST-Compiler
        Parameters:
        cu - Any Compilation Unit, but it must be one which was parsed from a complete source-file, otherwise the information will not have been made available to Java Parser (and will not be able to find the Package-Name)
        Returns:
        The Package-Name from whence cu was built, or null if there is no Package-Name or it was not found.
        Code:
        Exact Method Body:
         Optional<PackageDeclaration> optPD = cu.getPackageDeclaration();
         return optPD.isPresent() ? optPD.get().getName().asString().trim() : null;
        
      • getGenericTypeParameters

        🡅  🡇    
        public static java.lang.String[] getGenericTypeParameters​
                    (com.github.javaparser.ast.CompilationUnit cu,
                     java.lang.String name,
                     CIET kind)
        
        Retrieves the list of generic type parameters for a Class, Interface or Annotation.

        HELPER METHOD: org.github.javaparser Java-Parser ™ AST-Compiler
        Parameters:
        cu - An instance of the Java Parser Type CompilationUnit, but one which was parsed from a complete '.java' source-code file. This method searches for a class, interface, annotation or record declaration.
        name - The name of the class, interface, annotation or record. This method will handle looking for the generic type-parameters of inner-classes / nested-types that have been defined in the '.java' file.
        kind - This must be either a. CIET.CLASS or a CIET.INTERFACE, since CIET.ANNOTATION and CIET.ENUM may not have generic type-parameters, and CIET.RECORD is not implemented yet.
        Returns:
        The list of generic type parameters defined in the type 'name' inside 'cu'.
        Code:
        Exact Method Body:
         // Here, the 'cu' is for the *ENTIRE* Java Source Code File.  It should be expected to have
         // it's 'name' field set to 'name' - **BUT** if this class or interface is a generic class
         // or interface, that 'name' will not have the Type-Parameter's in it!
         //
         // FOR INSTANCE: If this were class Torello.HTML.NodeSearch.HNLI<E> - This class would be
         //               found in the 'cu' using name-String 'HNLI' (without the 'E') This line
         //               just removes the 'E'
        
         name = name.replaceFirst("<.*>", "");
        
         // This 'cu' is from a **COMPLETE** Java Source Code File.  It must be either a class or
         // an interface.
        
         NodeList<TypeParameter> genericTypeParams = null;
         Optional<ClassOrInterfaceDeclaration> ocoid;
        
         // Optional<RecordDeclaration> ord; // Not implemented yet.
        
         switch (kind)
         {
             case CLASS:
                 genericTypeParams = (ocoid = cu.getClassByName(name)).isPresent()
                     ? ocoid.get().getTypeParameters()
                     : null;
                 break;
                    
             case INTERFACE:
                 genericTypeParams = (ocoid = cu.getInterfaceByName(name)).isPresent()
                     ? ocoid.get().getTypeParameters()
                     : null;
                 break;
        
             default: throw new IllegalArgumentException(
                 "You have passed " + kind.toString() + " to parameter kind, but this method " +
                 "only handles classes and interfaces"
             );
         }
        
         if (genericTypeParams == null) Messager.assertFailJavaParser
             ("Generic Type Parameters NodeList was null", kind.toString() + " " + name);
        
         // Create a new array.  For most classes / interfaces which do not have Generic
         // Type-Parameters (like the 'E' in Vector<E>), this String-array will have zero-length.
        
         String[] ret = new String[genericTypeParams.size()];
        
         // REMEMBER: The primary-goal of the Java-Parser classes in the Java-Doc Upgrader is just
         // to simplify the JP Code by extracting the information as simple Java String's.  Here,
         // the String's being extracted are the Type-Parameters.
        
         for (int i=0; i < genericTypeParams.size(); i++)
             ret[i] = genericTypeParams.get(i).asString().trim();
        
         return ret;
        
      • getGenericTypeParameters

        🡅  🡇    
        public static java.lang.String[] getGenericTypeParameters​
                    (com.github.javaparser.ast.NodeList<com.github.javaparser.ast.type.TypeParameter> genericTypeParameters)
        
        Builds a String[]-Array that contains all of the Generic-Type Parameters used by a Type

        HELPER METHOD: org.github.javaparser Java-Parser ™ AST-Compiler
        Parameters:
        genericTypeParameters - A list of the Java Parser class TypeParameter
        Returns:
        The same list, but as a String[]-Array. This method will return null if the input list was null, or if it was empty.

        The individual String's are simply the ones returned by an invocation of TypeParameter.toString(). If wild-cards were used, the '?' will be retained, and if they were declared with upper bounds ('extends'), the extends-clause will also be included.
        Code:
        Exact Method Body:
         if ((genericTypeParameters != null) && (genericTypeParameters.size() > 0))
         {
             String[] ret = new String[genericTypeParameters.size()];
        
             for (int i=0; i < genericTypeParameters.size(); i++)
                 ret[i] = genericTypeParameters.get(i).toString().trim();
        
             return ret;
         }
        
         return null;
        
      • getImplementedTypes

        🡅  🡇    
        public static java.lang.String[] getImplementedTypes​
                    (com.github.javaparser.ast.NodeList<com.github.javaparser.ast.type.ClassOrInterfaceType> implementedTypes)
        
        Builds a String[]-Array that contains the type-names for the interface's that are implemented by a Type

        HELPER METHOD: org.github.javaparser Java-Parser ™ AST-Compiler
        Parameters:
        implementedTypes - A list of the Java Parser class ClassOrInterfaceType
        Returns:
        The same list, but as a String[]-Array. This method will return null if the input list was null, or if it was empty. The individual String's that are returned in this array are passed through StringParse.typeToJavaIdentifier(String), and will adhere to the JOW: Just One Word type-name convention.
        See Also:
        StringParse.typeToJavaIdentifier(String)
        Code:
        Exact Method Body:
         if ((implementedTypes != null) && (implementedTypes.size() > 0))
         {
             String[] ret = new String[implementedTypes.size()];
        
             for (int i=0; i < implementedTypes.size(); i++)
                 ret[i] = StringParse.typeToJavaIdentifier
                     (implementedTypes.get(i).toString()).trim();
        
             return ret;
         }
        
         return null;
        
      • getExtendedTypes

        🡅  🡇    
        public static java.lang.String[] getExtendedTypes​
                    (com.github.javaparser.ast.NodeList<com.github.javaparser.ast.type.ClassOrInterfaceType> extendedTypes)
        
        Convenience Method
        Invokes: getImplementedTypes(NodeList)
        NOTE: The code for "Extended-Types" is identical to that for "Implemented-Interfaces".
        Code:
        Exact Method Body:
         return getImplementedTypes(extendedTypes);
        
      • countMethodsFields

        🡅  🡇    
        public static Ret2<java.lang.Integer,​java.lang.Integer> countMethodsFields​
                    (com.github.javaparser.ast.body.TypeDeclaration<?> td)
        
        Counts the number of methods and fields declared in any Java-Parser TypeDeclaration

        HELPER METHOD: org.github.javaparser Java-Parser ™ AST-Compiler
        Parameters:
        td - A Java-Parser Type-Declaration. The sub-classes of TypeDeclaration include: ClassOrInterfaceDeclaration, EnumDeclaration, AnnotationDeclaration and RecordDeclaration.
        Returns:
        Ret2<Integer, Integer> instance:

        • Ret3.a Integer
          The Number of Methods Declared in td

        • Ret3.b Integer
          The Number of Fields Declared in td

        Code:
        Exact Method Body:
         // Same-Same: numFields are *FINAL* fields in this class, the counters are not.
         int numMethods=0, numFields=0;
        
         // A field or a method has to be a direct child of the TypeDeclaration
         for (Node n : td.getChildNodes())
        
             if (n instanceof MethodDeclaration)
                 numMethods++;
             else if (n instanceof FieldDeclaration)
                 numFields += ((FieldDeclaration) n).getVariables().size();
        
         return new Ret2<>(numMethods, numFields);
        
      • isContainedByCorrectCIET

        🡅  🡇    
        public static boolean isContainedByCorrectCIET​
                    (java.util.Optional<com.github.javaparser.ast.Node> p,
                     java.lang.String name)
        
        The Tree-Traversal algorithm / tree-walker for a JavaParser AST will visit all of the Methods, Constructors, and Enumerated-Types - even ones defined in inner classes. This checks that an instance of Node belongs to a class/type with a given name.

        HELPER METHOD: org.github.javaparser Java-Parser ™ AST-Compiler
        Parameters:
        p - This is the (Optional) parent-node for any Java Parser Node instance. In. It may be retrieved by querying for the node's parent using the line below:

        Java Line of Code:
         p = n.getParentNode();
        
        name - The expected container class for the node in 'p'. This name must contain any and all container-class names, and cannot contain the full-package attached to it, nor any generic-type parameter information.

        This table depicts the exact name that should be passed to parameter 'name', in order to check that given node is a member node of the a particular type or inner-type.

        Fully-Qualified Type NameThis Parameter's Requirements
        java.lang.StringString
        java.util.Vector<E>Vector
        java.util.Iterator<E extends Iterable>Iterable
        Torello.Java.FileNode.RetTypeChoiceFileNode.RetTypeChoice
        java.util.Map.Entry<K, V>Map.Entry
        Returns:
        This will return TRUE if the parent/containing CIET where this node is defined is the correct CIET/Type having a name 'name'
        Code:
        Exact Method Body:
         StringBuilder foundCIETName = new StringBuilder();
        
         // This crawls "upwards" in the JavaParser AST for the Class, Interface or Enumerated
         // Type that contains the declared variable
        
         for (Node n; p.isPresent(); p = n.getParentNode())
         {
             String isInnerClass = (foundCIETName.length() > 0) ? "." : "";
             n = p.get();
        
             // 'ClassOrInterfaceDeclaration' is a JavaParser class
             if (n instanceof ClassOrInterfaceDeclaration)
                 foundCIETName.insert
                     (0, ((ClassOrInterfaceDeclaration) n).getName().asString() + isInnerClass);
        
             // 'EnumDeclaration' is a JavaParser class
             else if (n instanceof EnumDeclaration)
                 foundCIETName.insert
                     (0, ((EnumDeclaration) n).getName().asString() + isInnerClass);
        
             // 'AnnotationDeclaration' is a JavaParser class
             else if (n instanceof AnnotationDeclaration)
                 foundCIETName.insert
                     (0, ((AnnotationDeclaration) n).getName().asString() + isInnerClass);
         }
        
         // See above note about the 'name' and including the Generic Variable-Types in the
         // name.  The above getName().asString() from the JavaParser code does not include the
         // Generic Type Parameters in the name of the containing class.  Therefore, in this
         // comparison, they are left out.  There is no way a class could contain an inner-class
         // with the same-name, but different generic-type parameters.  It would be illegal.
        
         return foundCIETName.toString().equals(name);
        
      • getGenericTypeParameters

        🡅  🡇    
        public static java.lang.String[] getGenericTypeParameters​
                    (com.sun.source.tree.ClassTree ct)
        
        Builds a String[]-Array that contains all of the Generic-Type Parameters used by a Type

        HELPER METHOD: com.sun.source.tree (Sun/Oracle Parse Trees)
        Parameters:
        ct - An instance of com.sun.source.tree.ClassTree
        Returns:
        The list of type-parameters used by this class, as a String[]-Array. This method will return null if the input list was null, or if it was empty.
        Code:
        Exact Method Body:
         List<? extends TypeParameterTree> genericTypeParams = ct.getTypeParameters();
        
         if ((genericTypeParams != null) && (genericTypeParams.size() > 0))
         {
             String[] ret = new String[genericTypeParams.size()];
        
             for (int i=0; i < genericTypeParams.size(); i++)
                 ret[i] = genericTypeParams.get(i).toString().trim();
        
             return ret;
         }
        
         return null;
        
      • getImplementedTypes

        🡅  🡇    
        public static java.lang.String[] getImplementedTypes​
                    (com.sun.source.tree.ClassTree ct)
        
        Builds a String[]-Array that contains the type-names for the interface's that are implemented by a Type

        HELPER METHOD: com.sun.source.tree (Sun/Oracle Parse Trees)
        Parameters:
        ct - An instance of com.sun.source.tree.ClassTree
        Returns:
        The list of interfaces implemented by this class, as a String[]-Array. This method will return null if the input list was null, or if it was empty.

        The individual String's that are returned in this array are passed through StringParse.typeToJavaIdentifier(String), and will adhere to the JOW: Just One Word type-name convention.
        See Also:
        StringParse.typeToJavaIdentifier(String)
        Code:
        Exact Method Body:
         List<? extends Tree> implementedTypes = ct.getImplementsClause();
        
         if ((implementedTypes == null) || (implementedTypes.size() == 0)) return null;
        
         String[] ret = new String[implementedTypes.size()];
        
         for (int i=0; i < implementedTypes.size(); i++)
             ret[i] = StringParse.typeToJavaIdentifier
                 (implementedTypes.get(i).toString()).trim();
        
         return ret;
        
      • getExtendedTypes

        🡅  🡇    
        public static java.lang.String[] getExtendedTypes​
                    (com.sun.source.tree.ClassTree ct)
        
        Code:
        Exact Method Body:
         Tree extendsTree = ct.getExtendsClause();
        
         if (extendsTree == null) return null;
        
         if (ct.getSimpleName().toString().equals("I")) Q.BP(extendsTree.toString());
        
         return new String[] { extendsTree.toString() };
        
      • getInnerTypeNames

        🡅  🡇    
        public static Ret3<java.lang.String,​java.lang.String,​java.lang.String> getInnerTypeNames​
                    (com.sun.source.tree.ClassTree ct,
                     TreeUtils util)
        
        Retrieves relevant name String's for an enclosed-class. Returned are the package-name, the fully-qualified name (not including the generic-type parameter's expression - <T, U>), and the name including all container-types.

        This method is only useful for classes that are enclosed by another class, specifically classes & types defined inside of another type '.java' file.

        HELPER METHOD: com.sun.source.tree (Sun/Oracle Parse Trees)
        Parameters:
        ct - A com.sun.source.tree.ClassTree Type-Declaration that is an inner-class (a type which is defined / enclosed by another type - for instance java.util.Map.Entry).
        Returns:
        Ret3<String, String, String> instance:

        THIS COMMENT NEEDS TO BE FINISHED. IN THE Unordered List BELOW, MAKE SURE TO INSERT THE ACTUAL VALUES OF Ret3.a, b and c!!! (USING java.util.Map.Entry K,V AS THE EXAMPLE) **ALSO** MAKE SURE TO PUT THIS ANSWER INTO AN EMBED, BECAUSE IT IS DUPLICATED ABOVE.

        • Ret3.a String
          Package-Name

        • Ret3.b String
          Class-Name, including *all* Enclosing-Classes

        • Ret3.c String
          Fully Qualified Name

        Code:
        Exact Method Body:
         String          packageName = util.compilationUnitTree.getPackageName().toString();
         TreePath        treePath    = util.getTreePath(ct);
         Iterator<Tree>  iter        = treePath.iterator();
         StringBuilder   sb          = new StringBuilder();
         Tree            n           = null;
        
         // Append the first / leaf type-name, and then skip it in the iterator.  This is another
         // one of the "Priming-Read" scenario's because inside the loop, there is always a period
         // appended to the end of the type-name.  The first type-name cannot have a period / dot in
         // front of it.  So just append the main-type name, skip it inside the iterator, and then
         // start the loop.
        
         sb.append(ct.getSimpleName().toString());
         if (iter.hasNext()) iter.next();
        
         // This loop iterates all of the parent nodes from the tree.  The actual leaf node was just
         // skipped in the previous statement.
        
         while (iter.hasNext())
        
             if (ClassTree.class.isAssignableFrom((n = iter.next()).getClass()))
                 sb.insert(0, ((ClassTree) n).getSimpleName().toString().trim() + '.');
        
         // For example, for class java.util.Map.Entry<K, V> the 'name with container' would be:
         // "Map.Entry"  (It is what was just built in the previous loop)
        
         String nameWithContainer = sb.toString();
        
         // For class java.util.Map.Entry<K, V> the "fully qualified name" would be:
         // "java.util.Map.Entry"
        
         String fullyQualifiedName =
        
             (((packageName != null) && (packageName.length() > 0))
                 ? (packageName + '.')
                 : "") +
             nameWithContainer;
        
         // Return everything
         return new Ret3<>(packageName, nameWithContainer, fullyQualifiedName);
        
      • countMethodsFields

        🡅  🡇    
        public static Ret2<java.lang.Integer,​java.lang.Integer> countMethodsFields​
                    (com.sun.source.tree.ClassTree ct,
                     CIET ciet)
        
        Counts the number of methods and fields declared in any Java-Parser TypeDeclaration

        HELPER METHOD: com.sun.source.tree (Sun/Oracle Parse Trees)
        Parameters:
        ct - An instance of com.sun.source.tree.ClassTree
        Returns:
        Ret2<Integer, Integer> instance:

        • Ret3.a Integer
          The Number of Methods Declared in ct

        • Ret3.b Integer
          The Number of Fields Declared in ct

        Code:
        Exact Method Body:
         // Same-Same: numFields are *FINAL* fields in this class, the counters are not.
         int numMethods=0, numFields=0;
        
         String cietName = ct.getSimpleName().toString();
        
         for (Tree member : ct.getMembers())
        
             // Constructors, Methods & Annotation-Elements
             if (MethodTree.class.isAssignableFrom(member.getClass()))
             {
                 // Constructor's are named "<init>"
                 if (! ((MethodTree) member).getName().toString().contains("<init>")) numMethods++;
             }
        
             // Fields & Enum-Constants
             else if (VariableTree.class.isAssignableFrom(member.getClass()))
             {
                 if (ciet == CIET.ENUM)
                 {
                     ExpressionTree initTree = ((VariableTree) member).getInitializer();
        
                     if (    (initTree != null)
                         &&  NewClassTree.class.isAssignableFrom(initTree.getClass())
                         &&  ((NewClassTree) initTree)
                                 .getIdentifier().toString().equals(cietName)
                     )
                         continue; // addEnumConstant
                     else
                         numFields++;
                 }
                 else numFields++;
             }
        
        
         return new Ret2<>(numMethods, numFields);
        
      • getCIET

        🡅  🡇    
        public static CIET getCIET​(com.sun.source.tree.ClassTree ct)
        Code:
        Exact Method Body:
         switch (ct.getKind())
         {
             case CLASS:             return CIET.CLASS;
             case INTERFACE:         return CIET.INTERFACE;
             case ENUM:              return CIET.ENUM;
        
             // case RECORD:            return CIET.RECORD;  - THIS NEEDS TO BE DEALT WITH SOON
             //                                              - NOTE THAT THIS CANNOT BE COMPILED
             //                                              - INTO JAVA 11.
        
             case ANNOTATION_TYPE:   return CIET.ANNOTATION;
        
             // Since this method will not accept any parameter which is not an instance of
             // 'ClassTree' - it should be impossible for any other 'Kind' to be returned from the
             // method 'getKind()' (but you never know!)
        
             default: throw new UnreachableError();
         }
        
      • diff

        🡅  🡇    
        public static void diff​(int int1,
                                int int2,
                                java.lang.String intName,
                                java.lang.Appendable a,
                                java.lang.String indentation)
                         throws java.io.IOException
        Checks for differences between an integer field from two different instances, generated by two different source-parsers.
        Parameters:
        int1 - Integer field from the first instance being diff'ed
        int2 - Integer field from the other / second instance being diff'ed
        intName - The name of the field being diff'ed. This is required solely for better output & printing purposes.
        a - This may be any Java jav.lang.Appendable. It is used to collect the output of the difference's between two separate parsers. When no differences are detected, this Java Appendable will not actually receive any character data.
        indentation - This is a java.lang.String that contains solely whitespace. If & when differences are detected, this white-space String is pre-pended to each line of output text. It helps ensure the output is more readable.
        Throws:
        java.io.IOException
        Code:
        Exact Method Body:
         if (int2 != int1) a.append(
             indentation +
             "this." + intName + ": [" + BGREEN + ("" + int1) + RESET + "], " +
             "other." + intName + ": [" + BGREEN + ("" + int2) + RESET + "]\n"
         );
        
      • diff

        🡅  🡇    
        @Deprecated
        public static void diff​(int int1,
                                int int2,
                                int radix,
                                java.lang.String intName,
                                java.lang.Appendable a,
                                java.lang.String indentation)
                         throws java.io.IOException
        Deprecated.
        Fields that are of type integer - but allows for a small (radix) margin of error. Since the Java-Parser version does Java-Doc Comment AST/Tree's slightly differently, the line numbers for the comments were usually off by one (and possibly more). When debugging and testing the parser, allowing for a small difference between the two parser tools makes worrying about trivial little nothings less of a problem.

        NOTE: The JavaDoc line-numbers issue seems to have mostly been solved. The line numbers returned by the com.sun.source.tree parser start with the location of the first non-space character of the Java-Doc comment - and end with the line-location of the last non-space character of the comment. In Java-Parser, the line-numbers are simply the location of the '/**' and the character sequences.

        NOTE: There is another minor issue that Java-Parser™ seems to fail to find the Java-Doc Comment's at all for a very small fraction of such comments. If they are poorly placed (with other front-slash comments '//' in-between them), they will not be marked as comments for an entity. com.sun.source.tree seems to be running at 100% for all JD Comments.
        Parameters:
        int1 - Integer field from the first instance being diff'ed
        int2 - Integer field from the other / second instance being diff'ed
        radix - An optional margin-of-error when doing checks for integers. Useful early on.
        intName - The name of the field being diff'ed. This is required solely for better output & printing purposes.
        a - This may be any Java jav.lang.Appendable. It is used to collect the output of the difference's between two separate parsers. When no differences are detected, this Java Appendable will not actually receive any character data.
        indentation - This is a java.lang.String that contains solely whitespace. If & when differences are detected, this white-space String is pre-pended to each line of output text. It helps ensure the output is more readable.
        Throws:
        java.io.IOException
        Code:
        Exact Method Body:
         if (Math.abs(int2 - int1) > radix) a.append(
             indentation +
             "this." + intName + ": [" + BGREEN + ("" + int1) + RESET + "], " +
             "other." + intName + ": [" + BGREEN + ("" + int2) + RESET + "]\n"
         );
        
      • diff

        🡅  🡇    
        public static void diff​(java.lang.String s1,
                                java.lang.String s2,
                                java.lang.String sName,
                                java.lang.Appendable a,
                                java.lang.String indentation,
                                boolean separateLines)
                         throws java.io.IOException
        Checks for differences between a String field from two different instances, generated by two different source-parsers. For instance: Declaration.name & Field.definition.
        Parameters:
        s1 - String field from the first instance being diff'ed
        s2 - String field from the other / second instance being diff'ed
        sName - The name of the field being diff'ed. This is required solely for better output & printing purposes.
        a - This may be any Java jav.lang.Appendable. It is used to collect the output of the difference's between two separate parsers. When no differences are detected, this Java Appendable will not actually receive any character data.
        indentation - This is a java.lang.String that contains solely whitespace. If & when differences are detected, this white-space String is pre-pended to each line of output text. It helps ensure the output is more readable.
        Throws:
        java.io.IOException
        Code:
        Exact Method Body:
         if ((s1 == null) && (s2 == null)) return;
        
         if (    ((s1 == null) && (s2 != null))
             ||  ((s2 == null) && (s1 != null))
             ||  (! s1.equals(s2))
         )
             a.append(
                 indentation +
                 "this." + sName + ": [" + BGREEN + s1 + RESET + "]" +
                 (separateLines ? ("\n" + indentation) : ", ") +
                 "other." + sName + ": [" + BGREEN + s2 + RESET + "]\n"
             );
        
      • diff

        🡅  🡇    
        public static void diff​(java.lang.String[] arr1,
                                java.lang.String[] arr2,
                                java.lang.String arrName,
                                java.lang.Appendable a,
                                java.lang.String indentation)
                         throws java.io.IOException
        Checks for differences between a String-Array field from two different instances, generated by two different source-parsers.
        Parameters:
        arr1 - String-Array field from the first instance being diff'ed
        arr2 - String-Array field from the other / second instance being diff'ed
        arrName - The name of the field being diff'ed. This is required solely for better output & printing purposes.
        a - This may be any Java jav.lang.Appendable. It is used to collect the output of the difference's between two separate parsers. When no differences are detected, this Java Appendable will not actually receive any character data.
        indentation - This is a java.lang.String that contains solely whitespace. If & when differences are detected, this white-space String is pre-pended to each line of output text. It helps ensure the output is more readable.
        Throws:
        java.io.IOException
        Code:
        Exact Method Body:
         boolean printIt = false;
        
         if ((arr1 == null) && (arr2 == null)) return;
        
         if (    ((arr1 == null) && (arr2 != null))
             ||  ((arr2 == null) && (arr1 != null))
             ||  (arr1.length != arr2.length)
         )
             printIt = true;
         else
             for (int i=0; i < arr1.length; i++)
                 if (! arr1[i].equals(arr2[i]))
                 {
                     printIt = true;
                     break;
                 }
        
         if (printIt) a.append(
             indentation +
             "this." + arrName + ": " +
                 ((arr1 == null) ? "null" : StrCSV.toCSV(arr1, PRINTER, true, null)) + '\n' +
             indentation + 
             "other." + arrName + ": " +
                 ((arr2 == null) ? "null" : StrCSV.toCSV(arr2, PRINTER, true, null)) + '\n'
         );
        
      • diffType

        🡅  🡇    
        public static void diffType​(java.lang.String s1,
                                    java.lang.String s2,
                                    java.lang.String sName,
                                    java.lang.Appendable a,
                                    java.lang.String indentation,
                                    boolean separateLines)
                             throws java.io.IOException
        Used for Method.returnType and Field.type when using the difference-engine debugger / tester.

        All it does is remove ", " and replace it with ",". If a type has any generic parameters in it, the Java-Parser version will remove all extra spaces between the types in a Generic-Parameter Expression. The com.sun.source.tree version will have a nicely placed space-character (' ') between each of the expressions inside the generic-param expression.

        In order to make sure that from the SunOracle returnType actually equals the returnType from JP ™ - this will eliminate spaces found in those type String's that come right after comma characters ','.
        Parameters:
        s1 - String field from the first instance being diff'ed
        s2 - String field from the other / second instance being diff'ed
        sName - The name of the field being diff'ed. This is required solely for better output & printing purposes.
        a - This may be any Java jav.lang.Appendable. It is used to collect the output of the difference's between two separate parsers. When no differences are detected, this Java Appendable will not actually receive any character data.
        indentation - This is a java.lang.String that contains solely whitespace. If & when differences are detected, this white-space String is pre-pended to each line of output text. It helps ensure the output is more readable.
        Throws:
        java.io.IOException
        Code:
        Exact Method Body:
         if ((s1 == null) && (s2 == null)) return;
        
         if (    ((s1 == null) && (s2 != null))
             ||  ((s2 == null) && (s1 != null))
             ||  (! s1.replaceAll(", ", ",").equals(s2.replaceAll(", ", ",")))
         )
             a.append(
                 indentation +
                 "this." + sName + ": [" + BGREEN + s1 + RESET + "]" +
                 (separateLines ? ("\n" + indentation) : ", ") +
                 "other." + sName + ": [" + BGREEN + s2 + RESET + "]\n"
             );
        
      • diffModifiers

        🡅  🡇    
        public static void diffModifiers​(java.lang.String[] arr1,
                                         java.lang.String[] arr2,
                                         java.lang.Appendable a,
                                         java.lang.String indentation)
                                  throws java.io.IOException
        When JP extracts the modifiers from a method, field or constructor - the order that they are inserted are NOT THE SAME as the order that is returned from com.sun.source.tree This checks that the contents of 'arr1' and 'arr2' are the same - EVEN IF THE ELEMENTS OF THE ARRAY ARE IN A DIFFERENT ORDER
        Parameters:
        arr1 - String-Array field (of modifiers) from the first instance being diff'ed
        arr2 - String-Array field (of modifiers) from the other / second instance being diff'ed
        a - This may be any Java jav.lang.Appendable. It is used to collect the output of the difference's between two separate parsers. When no differences are detected, this Java Appendable will not actually receive any character data.
        indentation - This is a java.lang.String that contains solely whitespace. If & when differences are detected, this white-space String is pre-pended to each line of output text. It helps ensure the output is more readable.
        Throws:
        java.io.IOException
        Code:
        Exact Method Body:
         boolean printIt = false;
        
         if ((arr1 == null) && (arr2 == null)) return;
        
         if (    ((arr1 == null) && (arr2 != null))
             ||  ((arr2 == null) && (arr1 != null))
             ||  (arr1.length != arr2.length)
         )
             printIt = true;
         else
         {
             TreeSet<String> mods = new TreeSet<>();
             for (String s : arr1) mods.add(s);
             for (String s : arr2) if (! mods.contains(s)) { printIt = true; break; }
         }
        
         if (printIt) a.append(
             indentation +
             "this.modifiers: " +
                 ((arr1 == null) ? "null" : StrCSV.toCSV(arr1, PRINTER, true, null)) + '\n' +
             indentation + 
             "other.modifiers: " +
                 ((arr2 == null) ? "null" : StrCSV.toCSV(arr2, PRINTER, true, null)) + '\n'
         );
        
      • diffMultiLine

        🡅  🡇    
        public static void diffMultiLine​(java.lang.String s1,
                                         java.lang.String s2,
                                         java.lang.String sName,
                                         java.lang.Appendable a,
                                         java.lang.String indentation)
                                  throws java.io.IOException
        Diff for the Declaration.body and Declaration.jdComment elements of class Declaration. Performs an abbreviation of the output String.
        Parameters:
        s1 - String field from the first instance being diff'ed
        s2 - String field from the other / second instance being diff'ed
        sName - The name of the field being diff'ed. This is required solely for better output & printing purposes.
        a - This may be any Java jav.lang.Appendable. It is used to collect the output of the difference's between two separate parsers. When no differences are detected, this Java Appendable will not actually receive any character data.
        indentation - This is a java.lang.String that contains solely whitespace. If & when differences are detected, this white-space String is pre-pended to each line of output text. It helps ensure the output is more readable.
        Throws:
        java.io.IOException
        Code:
        Exact Method Body:
         if ((s1 == null) && (s2 == null)) return;
        
         if (    ((s1 == null) && (s2 != null))
             ||  ((s2 == null) && (s1 != null))
             ||  (! s1.equals(s2))
         )
             a.append(
                 indentation + "this." + sName + ": " +
                 ((s1 == null)
                     ? (BRED + "null" + RESET)
                     : (BGREEN + StrPrint.abbrev(s1, 50, true, null, 100) + RESET)) + '\n' +
                 indentation + "other." + sName + ": " +
                 ((s2 == null)
                     ? (BRED + "null" + RESET)
                     : (BGREEN + StrPrint.abbrev(s2, 50, true, null, 100) + RESET)) + '\n'
             );
        
      • diffParamTypes

        🡅  🡇    
        public static void diffParamTypes​(java.lang.String[] arr1,
                                          java.lang.String[] arr2,
                                          java.lang.String arrName,
                                          java.lang.Appendable a,
                                          java.lang.String indentation)
                                   throws java.io.IOException
        All this does is remove any instances of the substring ", ", and replaces that substring with ",", if it is present in any of the String-Array elements before performing the comparisons.

        If a type has any generic parameters in it, Java-Parser™ will remove any 'extra' white-space inside a type-String. The AST Parser that Oracle Provides via package com.sun.source.tree will have a nicely placed space-character (' ') between each of the expressions inside of a generic-param expression.

        This is primarily used in the class Callable.
        Parameters:
        arr1 - String-Array field from the first instance being diff'ed
        arr2 - String-Array field from the other / second instance being diff'ed
        arrName - The name of the field being diff'ed. This is required solely for better output & printing purposes.
        a - This may be any Java jav.lang.Appendable. It is used to collect the output of the difference's between two separate parsers. When no differences are detected, this Java Appendable will not actually receive any character data.
        indentation - This is a java.lang.String that contains solely whitespace. If & when differences are detected, this white-space String is pre-pended to each line of output text. It helps ensure the output is more readable.
        Throws:
        java.io.IOException
        Code:
        Exact Method Body:
         boolean printIt = false;
        
         if ((arr1 == null) && (arr2 == null)) return;
        
         if (    ((arr1 == null) && (arr2 != null))
             ||  ((arr2 == null) && (arr1 != null))
             ||  (arr1.length != arr2.length)
         )
             printIt = true;
         else
             for (int i=0; i < arr1.length; i++)
                 if (! arr1[i].equals(arr2[i]))
                     if (! arr1[i].replaceAll(", ", ",").equals(arr2[i].replaceAll(", ", ",")))
                 {
                     printIt = true;
                     break;
                 }
        
         if (printIt) a.append(
             indentation +
             "this." + arrName + ": " +
                 ((arr1 == null) ? "null" : StrCSV.toCSV(arr1, PRINTER, true, null)) + '\n' +
             indentation + 
             "other." + arrName + ": " +
                 ((arr2 == null) ? "null" : StrCSV.toCSV(arr2, PRINTER, true, null)) + '\n'
         );
        
      • diff

        🡅    
        public static void diff​(boolean b1,
                                boolean b2,
                                java.lang.String bName,
                                java.lang.Appendable a,
                                java.lang.String indentation)
                         throws java.io.IOException
        Checks that two boolean fields are the same, and prints an error message to the output Appendable if they are not.
        Parameters:
        b1 - boolean field from the first instance being diff'ed
        b2 - boolean field from the other / second instance being diff'ed
        bName - The name of the field being diff'ed. This is required solely for better output & printing purposes.
        a - This may be any Java jav.lang.Appendable. It is used to collect the output of the difference's between two separate parsers. When no differences are detected, this Java Appendable will not actually receive any character data.
        indentation - This is a java.lang.String that contains solely whitespace. If & when differences are detected, this white-space String is pre-pended to each line of output text. It helps ensure the output is more readable.
        Throws:
        java.io.IOException
        Code:
        Exact Method Body:
         if (b1 != b2) a.append(
             indentation +
             "this." + bName + ": [" + BGREEN + b1 + RESET + "], " +
             "other." + bName + ": [" + BGREEN + b2 + RESET + "]\n"
         );