Package Torello.Java

Class StrSource


  • public class StrSource
    extends java.lang.Object



    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
    • 20 Method(s), 20 declared static
    • 8 Field(s), 8 declared static, 8 declared final


    • Method Detail

      • grep_HREF_tag

        🡅  🡇     🗕  🗗  🗖
        public static java.lang.String grep_HREF_tag​(java.lang.String s)
        If parameter String s contains any tag within-which there is a valid "HREF", this will return the contents of the HREF Attribute/InnerTag.
        Parameters:
        s - This is usually some variant of an HTML element/tag String. This method was the first one written for HTML in this scrape package, and is just kept here for legacy reasons. The class HTML.TagNode has a number of options for extracting the 'HREF' attribute from an HTML element.
        Returns:
        The attribute-value of an HREF=... attribute inside (usually an <A> 'Anchor') HTML tag. This will return 'null' if there is no HREF="..." attribute-value pair is found or identified.
        Throws:
        java.lang.IllegalArgumentException - If there is no end-quote found for the HREF="..." sub-string.
        Code:
        Exact Method Body:
         s = s.toLowerCase();
         String quote = "\"";
        
         int hrefPos = s.indexOf("href=\"");
        
         if (hrefPos == -1)
         {
             hrefPos = s.indexOf("href='");
             if (hrefPos == -1) return null;
             quote = "'";
         }
        
         // System.out.print("\t[hrefPos=" + hrefPos + "]");
                
         // the " + 6" is because the string HREF=" is 6 characters long
         String ret = s.substring(hrefPos + 6);
         int endQuotePos = ret.indexOf(quote);
                
         if (endQuotePos == -1) throw new IllegalArgumentException
             ("HREF has no End-Quote!\n\nFor String:\n" + s);
        
         // System.out.print("endQuotePos = " + endQuotePos + " " + ret.substring(0, endQuotePos));
        
         return ret.substring(0,endQuotePos);
        
      • grep_IMG_SRC_tag

        🡅  🡇     🗕  🗗  🗖
        public static java.lang.String grep_IMG_SRC_tag​(java.lang.String s)
        If parameter String s contains an HTML "IMG" tag, this will return the contents of the "SRC=..." attribute tag-field.
        Parameters:
        s - This is usually some variant of an HTML element/tag String. This method was the first one written for HTML in this scrape package, and is just kept here for legacy reasons. The class HTML.TagNode has a number of options for extracting the 'SRC' attribute from an HTML element.
        Returns:
        The attribute-value of a SRC=... attribute inside (usually an <IMG> 'Image') HTML tag. 'null' is returned if:

        1. There is no HTML 'IMG' token found in the String
        2. There is no SRC='...' attribute-value pair found.
        Code:
        Exact Method Body:
         String stlc = s.toLowerCase();
         // System.out.println("1: " + stlc);
                
         int imgPos = stlc.indexOf("<img ");
        
         if (imgPos == -1) return null;
        
         stlc = stlc.substring(imgPos + 5);
         // System.out.println("2: " + stlc + "[imgPos=" + imgPos + "]");
        
         // first check for double-quotes
         String  quote   = "\"";
         int     srcPos  = stlc.indexOf("src=\"");
        
         if (srcPos == -1)
         {
             // if no double-quotes, try single quotes
             srcPos = stlc.indexOf("src='");
        
             if (srcPos == -1) return null;
        
             quote = "'";
         }
        
         stlc = stlc.substring(srcPos + 5);
        
         // System.out.println("3: " + stlc + "[srcPos=" + srcPos + "]");
                
         int endSrcPos = stlc.indexOf(quote);
        
         if (endSrcPos == -1) return null;
                
         int urlStart    = imgPos + srcPos + 10;
         int urlEnd      = urlStart + endSrcPos;
                
         // System.out.println
         //     ("4: [endSrcPos=" + endSrcPos + ", urlStart=" + urlStart + ", urlEnd=" + urlEnd);
        
         return s.substring(urlStart, urlEnd);
        
      • escStrForJavaScript

        🡅  🡇     🗕  🗗  🗖
        public static java.lang.String escStrForJavaScript​(java.lang.String str)

        Copied from Stackoverflow.com - and all the "BRILLIANT ENGINEERS"!
        Really, I wish I had a reputation!!! So awful...




        Question: String.replaceAll single backslahes with double backslashes

        I'm trying to convert the String \something\ into the String \\something\\ using replaceAll, but I keep getting all kinds of errors. I thought this was the solution:

        theString.replaceAll("\\", "\\\\");

        But this gives the below exception:

        java.util.regex.PatternSyntaxException: Unexpected internal error near index 1




        The String#replaceAll() interprets the argument as a regular expression. The \ is an escape character in both String and regex. You need to double-escape it for regex:

        string.replaceAll("\\\\", "\\\\\\\\");
        But you don't necessarily need regex for this, simply because you want an exact character-by-character replacement and you don't need patterns here. So String#replace() should suffice:

        string.replace("\\", "\\\\");

        Update: as per the comments, you appear to want to use the string in JavaScript context. You'd perhaps better use StringEscapeUtils#escapeEcmaScript() instead to cover more characters
        Parameters:
        str - This may be any String in java. It is intended to be inserted into a Java-Script file between an open and close quotation marks.
        Returns:
        The String that is returned will have certain characters escaped, so that it may be wrapped in quotation marks and easily inserted into any java-script ".js" text-file.

        Escaped-Text:

        • char '\' will be escaped to: "\\"
        • char '/' will be escaped to: "\/", this is required in Java-Script, but not Java!
        • char '"' will be escaped to: "\""
        • char '\n' will be escaped to: "\\n"

        IMPORTANT NOTE: There is no easy, nor clear, way to express what is being replaced and/or escaped in a simple list. You may run this method on any String and view for yourself what changes. The primary goal of the method is to allow *any* Java String of *any* length to be converted, wrapped inside of an open and closed quotation-marks, and printed into a Java-Script ".js" file. Escaping "escape characters" which does come up some-what often in HTML text/string processing is near-impossible to explain clearly! Review the stack-overflow "incantation" for possible help.
        Code:
        Exact Method Body:
         return StrReplace.r(str, JS_ESCAPE_CHARS_ARR, '\\');
        
      • escStrForRegEx

        🡅  🡇     🗕  🗗  🗖
        public static java.lang.String escStrForRegEx​(java.lang.String str)
        This method should only be used for a precise String match using a regular-expression. This method shall 'escape' all characters that the JVM Regular Expression Matcher in package java.util.regex.* would expect be escaped. If the input parameter 'str' contains any regular-expression code, then this method would FAIL as it would escape regular-expression code into unusable text.
        Parameters:
        str - This should be any String for which the user would like to find an exact match, as-is.
        Returns:
        A regular-expression ready String
        Code:
        Exact Method Body:
         return StrReplace.r(str, REGEX_ESCAPE_CHARS_ARR, '\\');
        
      • parseGenericType

        🡅  🡇     🗕  🗗  🗖
        public static java.lang.String[] parseGenericType​
                    (java.lang.String genericTypeParamOrDefinition)
        
        Parses a String such as T extends TreeMap<Integer, List<String>>. It is strictly used, to only parse the generic-definition lists that are at the top of generic classes and interfaces.

        Sample Input StringOutput String[] array
        "HashMap<E extends Comparable, F extends Comparable>" { "E extends Comparable", "F extends Comparable" }
        "Ret6<A, B, C, D, E, F>" { "A", "B", "C", "D", "E", "F" }
        "AbstractHNLI<?, Vector<Vector<? extends HTMLNode>>>" { "?", "Vector<Vector<? extends HTMLNode>>" }
        "VarList<Vector<HashMap<String, String>>, FileNode>" { "Vector<HashMap<String, String>>", "FileNode" }
        Parameters:
        genericTypeParamOrDefinition - This should be String retrieved from inside the less-than ('<') and greater-than ('>') symbols. For example, for SortedList<A extends Comparable, B> the String passed to this method should be "A extends Comparable, B"
        Returns:
        This should break down this CSV (comma separated value) list into individual String's.
        Throws:
        NoMatchException - if the input String parameter does not match the generics regular-expression GENERIC_PARAMS.
        StringFormatException - If the input String could not be parsed.
        Code:
        Exact Method Body:
         Matcher m               = GENERIC_PARAMS.matcher(genericTypeParamOrDefinition);
         String  innerGenericStr = m.find() ? m.group(1) : null;
        
         if (innerGenericStr == null) throw new NoMatchException(
             "The provided value to parameter 'genericTypeParamOrDefinition' [" + 
             genericTypeParamOrDefinition + "] did not match the Java Generics " +
             "Regular-Expression:\n" + GENERIC_PARAMS.toString()
         );
        
         Stream.Builder<String>  b               = Stream.builder();
         String[]                sArr            = innerGenericStr.split(",");
        
         for (int i=0; i < sArr.length; i++)
        
             // We have shifted elements, and now all of the remaining elements would be null
             // return immediately
        
             if (sArr[i] == null) return b.build().toArray(String[]::new);
        
             // Simple generic-type definition: has no "sub-generics" or "inner-generics"
             // Add this to the list, and move on
        
             else if ((! sArr[i].contains("<")) && (! sArr[i].contains(">")))
                 b.accept(sArr[i].trim());
        
             // This is a generic-type definition that has at least one "sub-generic"
             // If there are an equal number of '<' and '>' then there were no commas
             // in between the sub-generics.  Add this to this list, and move on.
        
             else if (   StringParse.countCharacters(sArr[i], '<') ==
                         StringParse.countCharacters(sArr[i], '>')
             )
                 b.accept(sArr[i].trim());
        
             // There was a generic with a sub-generic that had a comma...
             else
             {
                 // If we have reached the end of the String, the number of greater than and
                 // less than symbols was not balanced.
        
                 if (i == (sArr.length - 1)) throw new StringFormatException(
                     "The provided value to parameter 'genericTypeParamOrDefinition' [" + 
                     genericTypeParamOrDefinition + "], was not properly formatted, and could " +
                     "not be parsed."
                 );
        
                 // Join the next String Array Element with the current one.
                 sArr[i] = sArr[i].trim() + ", " + sArr[i + 1].trim();
        
                 // Shift the rest of the array left.
                 for (int j=i+1; j < (sArr.length-1); j++) sArr[j] = sArr[j+1];
                 sArr[sArr.length - 1] = null;
        
                 // decrement the counter to retest this array-index location
                 i--;
             }
        
         // Return the list
         return b.build().toArray(String[]::new);
        
      • caretBeneath

        🡅  🡇     🗕  🗗  🗖
        public static java.lang.String caretBeneath​(java.lang.String str,
                                                    int strPos)
        This will print a caret-symbol on a line of text underneath the input String parameter 'str'. Preceeding the caret-symbol will be exactly strPos - 1 space characters. This look of the output-String is similar to some of the error messages generated by a Java Compiler.

        The caret-symbol '^' will bee pointing to the character at index strPos.

        Example:
         // Notice the (accidental, on-purpose) use of the '@'' character instead of an 'a'
         // To make this easy, lets compute the exact location of this erroneous character.
         String   s   = "This string has an inv@lid character.";
         int      pos = s.indexOf("@");
         
         // This will print out a line of text containing the string, with a caret pointing
         // at the '@' symbol.
         System.out.println(StringParse.caretBeneath(s, pos));
        
         // PRINTS:
         // This string has an inv@lid character.
         //                       ^
        
        Parameters:
        str - This may be any input-String that is less than 100 characters.
        strPos - This must be a number between 0 and the length
        Returns:
        The same input-String with a second line appended underneath (using a newline) having a caret ('^') directly underneath the character at strPos.
        Throws:
        java.lang.IllegalArgumentException - If the input String is longer than 100 characters.
        StringFormatException - If the input String contains any new-line '\n' or tab '\t' characters.
        java.lang.StringIndexOutOfBoundsException - If the value pased to strPos is negative or greater than the length of the input-String.
        See Also:
        StringParse.nChars(char, int)
        Code:
        Exact Method Body:
         if (str.length() > 100) throw new IllegalArgumentException(
             "The length of the input-string must be less than 100.  str has length: " +
             str.length()
         );
        
         if (StrCmpr.containsOR(str, "\n", "\t")) throw new StringFormatException
             ("The input-string may not contain new-line or tab characters.");
        
         if (strPos >= str.length()) throw new StringIndexOutOfBoundsException(
             "The value you have passed to 'strPos' [" + strPos + "] is greater than the length " +
             "the input-string [" + str.length() + "]"
         );
        
         if (strPos < 0) throw new StringIndexOutOfBoundsException
             ("You have passed a negative value to strPos [" + strPos + "]");
        
         return str + "\n" + StringParse.nChars(' ', strPos) + '^';
        
      • removeGeneric

        🡅  🡇     🗕  🗗  🗖
        public static java.lang.String removeGeneric​(java.lang.String typeAsStr)
        This will remove the generic type-parameters expression from a Java Type Declaration or Reference. In simple terms, this removes the '<K, V>' from a String such as Map.Entry<K, V>.
        Returned String Input String
        "Vector" "Vector<E>"
        "AbstractHNLI" "AbstractHNLI<E extends HTMLNode, F>"
        "Torello.HTML.TagNode" "Torello.HTML.TagNode"
        "ClassA.InnerClassB.InnerClassC" "ClassA<X>.InnerClassB<Y>.InnerClassC"
        "String[]" "String[]"
        "java.lang.String[]" "java.lang.String[]"
        "Vector" "Vector<String[]>"
        "java.util.Vector" "java.util.Vector<String[]>"
        Point of Interest:
        "I watched the World Series" "I watched the World Series"
        "Vector" "Vector<Quoth the Raven>"
        Throws an Exception
        "HNLI<E> <"
        "> <Quoth the Raven>"
        Parameters:
        typeAsStr - The "Reference Type" or "Declaration Type".
        Returns:
        The same String, having everything between the outer-most, matching '<' and '>' symbols.

        NOTE: The returned String will not contain any leading or trailing white-space. It is trimmed before being returned.
        Throws:
        StringFormatException - An exhaustive check on everything that could be wrong with a type-String is an impossibility (if you include checking for valid types). This exception is only thrown if the '<' and '>' symbols inside the input-String do not match-up.

        In order to avoid throwing this exception, there must be an equal number of opening and closing symbols.

        There is also a check to ensure that the charcters in this String are valid.
        Code:
        Exact Method Body:
         int leftPos = typeAsStr.indexOf('<');
        
         if (leftPos == -1)
         {
             int pos = typeAsStr.indexOf('>');
        
             if (pos == -1) return typeAsStr.trim();
        
             throw REM_GENERIC_ERROR_MSG(typeAsStr, pos);
         }
        
         char[]  cArr    = typeAsStr.toCharArray();
         int     count   = 1;            // The number of OPENING-CLOSING tags (same as Inclusive)
         int     END     = cArr.length;  // This is the location JUST-AFTER the last USEABLE-char
         int     delta   = 0;            // How many characters have been deleted already.
                                         // NOTE: This is zero, because the loop hasn't started.
                                         //       If there is a "Shift" this will be PRECISELY-EQUAL
                                         //       to the size of the last generic parameter-expression.
                                         // ALSO: The only purpose of this is for error-reporting.
        
         // check for a closing '>' before the first opening '<'
         for (int j=0; j < leftPos; j++)
             if (cArr[j] == '>') throw REM_GENERIC_ERROR_MSG(typeAsStr, j);
        
         // Check for in-valid characters
         // This is a lot of lines of code, but these methods are extremely short, and the input
         // string (for all VALID) input will be very short.  This is peace of mind.  It checks...
         for (int pos=0; pos < cArr.length; pos++)
         {
             char c = cArr[pos];
             if (! Character.isJavaIdentifierPart(c))
                 if (! Character.isIdentifierIgnorable(c))
                     if (! Character.isWhitespace(c))
                         if (
                                 (c != '[') && (c != ']') && (c != '?') && (c != '<') &&
                                 (c != '>') && (c != ',') && (c != '.')
                         )
                             throw REM_GENERIC_ERROR_MSG(typeAsStr, pos);
         }
        
         do
         {
             // Keeps a count on the number of "Opening Braces" and "Closing Braces" 
             // This is the same thing as the whole "Inclusive" deal, but with braces instead.
             //
             // count: At loop start, count is '1'  If it ever reaches 0, the loop exits.
             // leftPos: The location of the '<' that has been found.
             int i = leftPos + 1;
            
             while ((count > 0) && (i < END))
             {
                 if      (cArr[i] == '<')    count++;
                 else if (cArr[i] == '>')    count--;
        
                 if (count > 0) i++;
             }
        
             // The '<' and the '>' didn't match up.  Better to throw exception, than ignore it.
             if ((count != 0) && (i == END))
                 throw REM_GENERIC_ERROR_MSG(typeAsStr, leftPos);
        
             int rightPos = i; // 'i' is currently pointing to the '>'
        
             // Erase the most recently found <...> expression
             int     sourcePos       = rightPos + 1; // Pointing at first VALID / NEED-TO-COPY char
             int     destPos         = leftPos;      // Pointing at '<'
             boolean possiblyAnother = false;
        
             while (sourcePos < END)
             {
                 // The next character to copy... check it first to see if it is valid!
                 char c = cArr[sourcePos]; 
        
                 // continue to shift all the characters left to erase the expression.
                 cArr[destPos] = c;
        
                 if (! possiblyAnother) // Haven't found an opening '<'
                 {
                     // If there is a '>' - ***AND NO '<' HAS BEEN FOUND***, this is an error.    
                     if (c == '>')
                         throw REM_GENERIC_ERROR_MSG(typeAsStr, delta + sourcePos);
        
                     // If there is another '<', then it is possible another expression awaits us
                     if (c == '<')
                     {
                         // Reset the outer-loop variables for the next iteration.  There is going
                         // to be another iteration - guaranteed.
                         //
                         // NOTE: Delta is supposed to hold how many characters are being deleted.
                         //       This is used for proper error-reporting (only)
        
                         // This is how many chars are in the current <...> expression
                         delta   = rightPos - leftPos + 1;
        
                         leftPos = destPos;  // Now pointing at the next open '<' char (just found!)
                         count   = 1;        // There was a new-unclosed '>', prepares for next loop
        
                         // You know it
                         possiblyAnother = true;
                     }
                 }
        
                 sourcePos++; destPos++;
             }
        
             // Completed without errors, and without another expression being found.
             // NOTE: This used to be a one-line return call.
             // ADDED: This now does a String.trim().   These little loops skip leading and 
             //        trailing white-space BEFORE returning the String
             //
             // WORKS-NO-TRIM: return new String(cArr, 0, destPos);
             //                replace loop-body with the above line to get rid of trim()
             if (! possiblyAnother)
             {
                 int sPos    = 0;
                 int len     = destPos;  // REMEMBER:    new String(char[], int OFFSET, int COUNT)
                                         // NOT:         new String(char[], int SPOS, int EPOS)
        
                 // Skip LEADING-WHITESPACE
                 while ((sPos < cArr.length) && (destPos > 0) && Character.isWhitespace(cArr[sPos]))
                 { sPos++; destPos--; } // Advance start, *AND* shorten "count"
        
                 // Skip TRAILING WHITE-SPACE
                 while ((destPos > 1) && Character.isWhitespace(cArr[sPos + destPos-1]))
                     destPos--; // Shorten length *ONLY*
        
                 return new String(cArr, sPos, destPos);
             }
                    
             END = destPos;  // Pointing at the first invalid / unused / ALREADY-MOVED char
         }
         while (true);
        
      • typeToJavaIdentifier

        🡅  🡇     🗕  🗗  🗖
        public static java.lang.String typeToJavaIdentifier​
                    (java.lang.String typeStr)
        
        This will remove any generic-parameter information from a Java type-String and then remove all package-information or outer-class String's. What is left is a single Java Identifier String that, as long as the proper scope has been provided, identifies a Java Type (Class, Interface, Enum, Record, Annotation).
        OutputInput
        "Integer""java.lang.Integer"
        "Vector""java.util.Vector<E>"
        "Entry""java.util.Map.Entry<String, Integer>"
        "Entry""Map.Entry<String, Intger>"
        "Entry""Entry<String, Integer>"
        "Entry""Entry"
        "String[]""String[]"
        "String[]""java.lang.String[]"
        "Vector""Vector<String[]>"
        "Vector[]""Vector<String>[]"
        Point of Interest:
        "The World Series""The World Series"
        "Quoth the Raven""Quoth the Raven<java.lang.Integer>"
        Finally:
        "String...""String..."
        "String...""java.lang.String..."
        "Vector...""Vector<E>..."
        "Vector...""java.util.Vector<E>..."
        Parameters:
        typeStr - This is a type as a String. These are usually retrieved from Java Parser, in the Java Doc Upgrader package. This method does not provide an exhaustive check for all variants of format and naming erros of a Java Type. Some validity checks are performed regarding the use of non-Java type characters.

        NOTE: All the exceptions thrown by the method removeGeneric(String) will also be thrown here, if 'typeStr' is not not properly formatted.
        Returns:
        a Simplified version of the type that leaves out the scope, but provides a simple Java Identifier, instead. Throws exceptions if not properly formatted. If any array-bracket characters are passed, they is preserved, unless the arrays in this type are part of the generic-type parameters; please see the examples above.
        Throws:
        StringFormatException - Please see the explanation provided in removeGeneric(String) under 'Throws'.
        See Also:
        removeGeneric(String)
        Code:
        Exact Method Body:
         String  ret         = removeGeneric(typeStr);
         boolean isVarArgs   = false;
        
         if (ret.endsWith("..."))
         {
             ret = ret.substring(0, ret.length() - 3);
             isVarArgs = true;
         }
        
         int pos = ret.lastIndexOf('.');
        
         if (isVarArgs)
         {
             if (pos == -1)  return ret + "...";
             else            return ret.substring(pos+1) + "...";
         }
        
         else
         {
             if (pos == -1)  return ret;
             else            return ret.substring(pos+1);
         }
        
      • removeExtendsClause

        🡅  🡇     🗕  🗗  🗖
        public static java.lang.String removeExtendsClause​(java.lang.String decl)
        Removes the 'extends' part of a Java Generic

        TO DO: This will fail for a class such as:
        public class MyClass<T extends Vector<String>, where the extends clause also has a generic in it. Java HTML does not define such classes, but they are possible, and this needs to be fixed, as soon as they let me!
        Parameters:
        decl - Any Type Declaration that includes has the word {'extends'}, followed by type-parameter information.
        Returns:
        The same String without the clause.
        Code:
        Exact Method Body:
         Matcher m = exClause.matcher(decl);
        
         while (m.find())
         {
             decl = m.replaceFirst(m.group(1));
             m.reset(decl);
         }
        
         return decl;
        
      • isJavaTypeStr

        🡅  🡇     🗕  🗗  🗖
        public static boolean isJavaTypeStr​(java.lang.String s)
        Checks whether an input String is a valid Type Identifier. Type Identifiers are the names of Java Classes, Interfaces, Enumerated-Types, Annotations and Records. The two methods Character.isJavaIdentifier.start(char) and Characters.isJavaIdentifer.part(char) are utilized here to produce this method's return value. Below is a table of several output-results (table's second column) that would be returned by the specified inputs String's (first column).

        Function InputReturn Value
        Stringtrue
        Map.Entrytrue
        Vectortrue
        Vector<String>false
        Map.Entry<String, Integer>false
        String.indexOf(1)false
        String.indexOftrue
        MyOuterClass.MyInnerClass03true
        MyOuterClass.03MyInnerClassfalse


        The only real check being performed is whether the String is a valid 'Java Identifier' - or, if a period '.' is present - that it is a list of Java Identifier's which are all separated by a single period character. This is done to ensure that String's which reference Java Inner Classes, Interfaces, Enumerations, etc. also produce a TRUE return value.
        Parameters:
        s - Any Java String.
        Returns:
        TRUE if and only if the Java Compiler could interpret 's' as a valid reference to a Java Type. In computer-programming, the world Type can have a lot of meanings, but here, the word should be interpreted as a Java Class, Interface, Enumeration (an 'enum'), Annotation or Record.

        NOTE: 's' may include the period '.' since inner classes, enum's and interfaces are also valid Java Type's. Two consecutive period-characters, or a period at the beginning or ending of 's' will result in this method returning FALSE.
        Code:
        Exact Method Body:
         if (s.length() == 0) return false;
        
         // Java restricts the first character of a java-identifier to a smaller subset than the
         // other characters in an identifier.  Use method 'isJavaIdentifierStart'
        
         if (! Character.isJavaIdentifierStart(s.charAt(0))) return false;
        
         int     len = s.length();
         char    c   = 0;
        
         for (int i=1; i < len; i++)
        
             if (! Character.isJavaIdentifierPart(c = s.charAt(i)))
             {
                 if (c == '.')
                 {
                     // A second (subsequent) period-character (in a row) ==> FALSE
                     if (s.charAt(i-1) == '.') return false;
        
                     // The LAST character in the String is a period-character ==> FALSE
                     if (i == (len-1)) return false;
        
                     // The character immediately following a period isn't a valid Java Identifier
                     // Start ==> FALSE
        
                     if (! Character.isJavaIdentifierStart(s.charAt(++i))) return false;
                 }
                 else
                     // Character is NEITHER a period, NOR a Java Identifier Part ==> FALSE
                     return false;
             }
        
         // All metrics / tests have succeeded (which would have resulted in immediate exiting of
         // this method, and a FALSE return value) ... therefore return TRUE.
         return true;
        
      • isValidJavaIdentifier

        🡅  🡇     🗕  🗗  🗖
        public static boolean isValidJavaIdentifier​(java.lang.String identifier)
        Checks whether an input String would be allowed as a Java Identifier - for instance, whether the input would make a valid Field-Name, Variable-Name, Class-Name or Method-Name.

        ChatGPT Note:
        ChatGPT, 3.5 wrote this whole thing, including the in-line comments. I had to write the Java-Doc Comments, but I guess I could have asked it to do that too.
        Parameters:
        identifier - Any Java String
        Returns:
        TRUE if-and-only-if parameter 'identifier' is a valid Java Identifier.
        Code:
        Exact Method Body:
         // Check if the string is not null or empty
         if (identifier == null || identifier.isEmpty()) return false;
        
         // Check if the first character is a letter, underscore, or dollar sign
         if (! Character.isJavaIdentifierStart(identifier.charAt(0))) return false;
        
         // Check the remaining characters
         for (int i = 1; i < identifier.length(); i++)
             if (!Character.isJavaIdentifierPart(identifier.charAt(i)))
                 return false;
        
         // Check if the identifier is a reserved keyword
         if (reservedKeywords.contains(identifier)) return false;
        
         // The string is a valid Java identifier
         return true;
        
      • replaceNBSP

        🡅  🡇     🗕  🗗  🗖
        public static java.lang.String replaceNBSP​(java.lang.String s)
        There are actually people out there who are willing to put character '160' into a file or document, instead of a simple '&nbsp;' element. How rude. Any instances of this character shall be replaced with the standard space character ASCII #32.
        Parameters:
        s - Any String will pass. Generally String's that were converted from HTML pages will contain char #160 as it is occasionally translated from the HTML escape sequence &nbsp;
        Returns:
        A String where any instance of white-space character #160 have been replaced with character #32
        Code:
        Exact Method Body:
         return s.replace(("" + ((char) 160)), " ");
        
      • replaceZWSP

        🡅  🡇     🗕  🗗  🗖
        public static java.lang.String replaceZWSP​(java.lang.String s)
        Even lower than #160, apparently is the "Zero Width Space" (character #8203. This is actually inserted by the JavaDoc Tool (by Sun / Oracle) into JavaDoc generated HTML Pages. Here, it shall be replaced by character #32 - the space-character.

        A.K.A.: "​".

        Can you see the character, above? No? That's zero width space for you! If you ever sitting and wondering why a String seems to be something else than what it looks like - you might have a zero-width space in your String. If so, it will take a while to find the bug.
        Parameters:
        s - Any String will pass. Generally String's that were converted from JavaDoc HTML pages will contain char #8203.
        Returns:
        A String where any instance of white-space character #8203 have been replaced with character #32
        Code:
        Exact Method Body:
         return s.replace(("" + ((char) 8203)), " ");
        
      • isCSSPropertyName

        🡅  🡇     🗕  🗗  🗖
        public static boolean isCSSPropertyName​(java.lang.String cssPropertyName)
        Checks if a Java-String constitutes a valid CSS Property-Name. Note that this method, in no way consults any "complete list" of all known CSS-Properties. Instead, it simply analyzes whether the name is conguent with the CSS-Property Validator Reg-ex.
        Parameters:
        cssPropertyName - Any Java-String
        Returns:
        TRUE if and ony if 'attributeName' is a valid HTML Atribute-Name, according to the agreed upon CSS-Property Regular-Expression Validator.
        Code:
        Exact Method Body:
         if (cssPropertyName.length() == 0) return false;
        
         if (! isCSSPropertyNameStart(cssPropertyName.charAt(0))) return false;
        
         for (int i=1; i < cssPropertyName.length(); i++)
         {
             final char c = cssPropertyName.charAt(i);
             if ((c >= 'A') && (c <= 'Z')) continue;
             if ((c >= 'a') && (c <= 'z')) continue;
             if ((c >= '0') && (c <= '9')) continue;
             if ((c == '-') || (c == '_')) continue;
             return false;
         }
        
         return true;
        
      • isCSSPropertyNameStart

        🡅  🡇     🗕  🗗  🗖
        public static boolean isCSSPropertyNameStart​(char c)
        Checks whether parameter 'c' is one of the agreed-upon standard characters that are allowed to begin CSS Property-Names.
        Parameters:
        c - Any Java char-primitive
        Returns:
        TRUE if and ony if 'c' is a character that would be allowed to begin a CSS Property-Name
        Code:
        Exact Method Body:
         if ((c >= 'A') && (c <= 'Z')) return true;
         if ((c >= 'a') && (c <= 'z')) return true;
         if ((c == '-') || (c == '_')) return true;
         return false;
        
      • isCSSPropertyNamePart

        🡅  🡇     🗕  🗗  🗖
        public static boolean isCSSPropertyNamePart​(char c)
        Checks whether parameter 'c' is one of the agreed-upon standard characters that are permitted within CSS Property-Names, after the first character of the name.
        Parameters:
        c - Any Java char-primitive
        Returns:
        TRUE if and ony if 'c' is a character that would be allowed within a valid CSS Property-Name.
        Code:
        Exact Method Body:
         if ((c >= 'A') && (c <= 'Z')) return true;
         if ((c >= 'a') && (c <= 'z')) return true;
         if ((c >= '0') && (c <= '9')) return true;
         if ((c == '-') || (c == '_')) return true;
         return false;
        
      • isAttributeName

        🡅  🡇     🗕  🗗  🗖
        public static boolean isAttributeName​(java.lang.String attributeName)
        Checks if a Java-String constitutes a valid HTML Attibute-Name. Note that this method, in no way consults any "complete list" of all know HTML-Attributes. Instead, it simply analyzes whether the name is conguent with the Attribute-Name Validator Reg-ex.
        Parameters:
        attributeName - Any Java-String
        Returns:
        TRUE if and ony if 'attributeName' is a valid HTML Atribute-Name, according to the agreed upon Attribute-Name Regular-Expression Validator.
        Code:
        Exact Method Body:
         if (attributeName.length() == 0) return false;
        
         if (! isAttributeNameStart(attributeName.charAt(0))) return false;
        
         for (int i=1; i < attributeName.length(); i++)
         {
             final char c = attributeName.charAt(i);
             if ((c >= 'A') && (c <= 'Z')) continue;
             if ((c >= 'a') && (c <= 'z')) continue;
             if ((c >= '0') && (c <= '9')) continue;
             if ((c == '-') || (c == '_')) continue;
             return false;
         }
        
         return true;
        
      • isAttributeNameStart

        🡅  🡇     🗕  🗗  🗖
        public static boolean isAttributeNameStart​(char c)
        Checks whether parameter 'c' is one of the agreed-upon standard characters that are allowed to begin HTML Attribute-Names.
        Parameters:
        c - Any Java char-primitive
        Returns:
        TRUE if and ony if 'c' is a character that would be allowed to begin an HTML Attribute-Name
        Code:
        Exact Method Body:
         if ((c >= 'A') && (c <= 'Z')) return true;
         if ((c >= 'a') && (c <= 'z')) return true;
         return false;
        
      • isAttributeNamePart

        🡅     🗕  🗗  🗖
        public static boolean isAttributeNamePart​(char c)
        Checks whether parameter 'c' is one of the agreed-upon standard characters that are permitted within HTML Attribute-Names, after the first character of the name.
        Parameters:
        c - Any Java char-primitive
        Returns:
        TRUE if and ony if 'c' is a character that would be allowed within a valid HTML Attribute-Name.
        Code:
        Exact Method Body:
         if ((c >= 'A') && (c <= 'Z')) return true;
         if ((c >= 'a') && (c <= 'z')) return true;
         if ((c >= '0') && (c <= '9')) return true;
         if ((c == '-') || (c == '_')) return true;
         return false;