Search code examples
javaregexjava-9java-module

Regex or String operation to derive automatic module name from String


I need to find the Automatic Module name given a String filename, as:

"common-io-1.2.3.jar" -> "common.io"
"---apple...orange..jar" -> "apple.orange"
"google-api-v1-beta.jar" -> "google.api.v1.beta"

I know I can use ModuleFinder.of(Path) but my requirement is to derive it without any file-system IO.

What I found so far:

Looking up the source code how ModuleFinder.of() works I found this method, but that is too much for what I need.

How can I do it with simple Regex or string operation?


Solution

  • Following this JavaDoc:

    public static String deriveModule(String filename) {
    
        // strip ".jar" at the end
        filename = filename.replaceAll("\\.jar$", "");
    
        // drop everything after the version
        filename = filename.replaceAll("-\\d.*", "");
    
        // all non alphanumeric get's converted to "."
        filename = filename.replaceAll("[^A-Za-z0-9]", ".");
    
        // strip "." at beginning and end
        filename = filename.replaceAll("^\\.*|\\.*$", "");
    
        // all double "." stripped to single
        filename = filename.replaceAll("\\.{2,}", ".");
    
    
        return filename;
    }
    

    You can also check if it is a valid module name:

    public static boolean isValidModuleName(String name) {
        String VALID_REGEX = "([\\p{L}_$][\\p{L}\\p{N}_$]*\\.)*[\\p{L}_$][\\p{L}\\p{N}_$]*";
    
    
        if (!name.matches(VALID_REGEX))
            return false;
    
    
        Set<String> keywords = Set.of("abstract", "continue", "for", "new", 
                        "switch", "assert", "default", "goto", "package",
                        "synchronized", "boolean", "do", "if", "private", "this",
                        "break", "double", "implements","protected", "throw", 
                        "byte", "else", "import", "public", "throws", "case", 
                        "enum", "instanceof", "return", "transient", "catch", 
                        "extends",  "int", "short", "try", "char", "final",
                        "interface", "static", "void", "class", "finally", 
                        "long", "strictfp", "volatile", "const",
                        "float", "native", "super", "while", "module", "open", 
                        "opens", "exports", "requires",
                        "transitive", "to", "with", "provides", "uses");
    
    
        String[] tokens = name.split("\\.");
        for (String t : tokens) {
            if (keywords.contains(t))
                return false;
        }
    
        return true;
    }