Rename wildcard matcher to glob matcher.
[svjatoslav_commons.git] / src / main / java / eu / svjatoslav / commons / string / GlobMatcher.java
diff --git a/src/main/java/eu/svjatoslav/commons/string/GlobMatcher.java b/src/main/java/eu/svjatoslav/commons/string/GlobMatcher.java
new file mode 100755 (executable)
index 0000000..b27f1f0
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Svjatoslav Commons - shared library of common functionality.
+ * Copyright ©2012-2017, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 3 of the GNU Lesser General Public License
+ * or later as published by the Free Software Foundation.
+ */
+
+package eu.svjatoslav.commons.string;
+
+public class GlobMatcher {
+
+    /**
+     * Allow only for * in wildcards
+     */
+    private static boolean checkWildCardEnd(final String wildcardExpression,
+                                            int wildCardPosition) {
+        for (; wildCardPosition < wildcardExpression.length(); wildCardPosition++) {
+            final char wildCardChar = wildcardExpression
+                    .charAt(wildCardPosition);
+            if (wildCardChar != '*')
+                return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * <pre>
+     * Test input string against wildcard expression.
+     * * -- corresponds to any amount of characters.
+     * ? -- corresponds to any single character.
+     * </pre>
+     *
+     * @param inputString        input string
+     * @param wildcardExpression wildcard expression
+     * @return <code>true</code> if input string matches input pattern
+     */
+    public static boolean match(final String inputString,
+                                final String wildcardExpression) {
+
+        if (inputString == null)
+            return false;
+
+        if (wildcardExpression == null)
+            return false;
+
+        int i;
+
+        for (i = 0; i < inputString.length(); i++) {
+            if (i >= wildcardExpression.length())
+                return false;
+            final char wildCardChar = wildcardExpression.charAt(i);
+            if (wildCardChar == '*')
+                return matchPiece(inputString, i, wildcardExpression, i + 1);
+            if (wildCardChar != '?')
+                if (inputString.charAt(i) != wildCardChar)
+                    return false;
+        }
+
+        return checkWildCardEnd(wildcardExpression, i);
+    }
+
+    private static boolean matchPiece(final String inputString,
+                                      final int inputStringIndex, final String wildcardExpression,
+                                      final int wildCardExpressionIndex) {
+
+        int wildCardPosition = wildCardExpressionIndex;
+
+        for (int i = inputStringIndex; i < inputString.length(); i++) {
+
+            wildCardPosition = wildCardExpressionIndex;
+
+            subMatchAttempt:
+            {
+
+                for (int j = i; j < inputString.length(); j++) {
+                    if (wildCardPosition >= wildcardExpression.length())
+                        break subMatchAttempt;
+                    final char wildCardChar = wildcardExpression
+                            .charAt(wildCardPosition);
+
+                    if (wildCardChar == '*')
+                        return matchPiece(inputString, j, wildcardExpression,
+                                wildCardPosition + 1);
+
+                    if (wildCardChar != '?')
+                        if (inputString.charAt(j) != wildCardChar)
+                            break subMatchAttempt;
+
+                    wildCardPosition++;
+                }
+
+                return checkWildCardEnd(wildcardExpression, wildCardPosition);
+            }
+
+        }
+
+        return checkWildCardEnd(wildcardExpression, wildCardPosition);
+    }
+
+}