842d0a2f9ad5c96accdeeadc6960c77a8c25aaa5
[svjatoslav_commons.git] / src / main / java / eu / svjatoslav / commons / string / GlobMatcher.java
1 /*
2  * Svjatoslav Commons - shared library of common functionality.
3  * Copyright ©2012-2020, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of version 3 of the GNU Lesser General Public License
7  * or later as published by the Free Software Foundation.
8  */
9
10 package eu.svjatoslav.commons.string;
11
12 public class GlobMatcher {
13
14     /**
15      * Allow only for * in wildcards
16      */
17     private static boolean checkWildCardEnd(final String wildcardExpression,
18                                             int wildCardPosition) {
19         for (; wildCardPosition < wildcardExpression.length(); wildCardPosition++) {
20             final char wildCardChar = wildcardExpression
21                     .charAt(wildCardPosition);
22             if (wildCardChar != '*')
23                 return false;
24         }
25
26         return true;
27     }
28
29     /**
30      * <pre>
31      * Test input string against wildcard expression.
32      * * -- corresponds to any amount of characters.
33      * ? -- corresponds to any single character.
34      * </pre>
35      *
36      * @param inputString        input string
37      * @param wildcardExpression wildcard expression
38      * @return <code>true</code> if input string matches input pattern
39      */
40     public static boolean match(final String inputString,
41                                 final String wildcardExpression) {
42
43         if (inputString == null)
44             return false;
45
46         if (wildcardExpression == null)
47             return false;
48
49         int i;
50
51         for (i = 0; i < inputString.length(); i++) {
52             if (i >= wildcardExpression.length())
53                 return false;
54             final char wildCardChar = wildcardExpression.charAt(i);
55             if (wildCardChar == '*')
56                 return matchPiece(inputString, i, wildcardExpression, i + 1);
57             if (wildCardChar != '?')
58                 if (inputString.charAt(i) != wildCardChar)
59                     return false;
60         }
61
62         return checkWildCardEnd(wildcardExpression, i);
63     }
64
65     private static boolean matchPiece(final String inputString,
66                                       final int inputStringIndex, final String wildcardExpression,
67                                       final int wildCardExpressionIndex) {
68
69         int wildCardPosition = wildCardExpressionIndex;
70
71         for (int i = inputStringIndex; i < inputString.length(); i++) {
72
73             wildCardPosition = wildCardExpressionIndex;
74
75             subMatchAttempt:
76             {
77
78                 for (int j = i; j < inputString.length(); j++) {
79                     if (wildCardPosition >= wildcardExpression.length())
80                         break subMatchAttempt;
81                     final char wildCardChar = wildcardExpression
82                             .charAt(wildCardPosition);
83
84                     if (wildCardChar == '*')
85                         return matchPiece(inputString, j, wildcardExpression,
86                                 wildCardPosition + 1);
87
88                     if (wildCardChar != '?')
89                         if (inputString.charAt(j) != wildCardChar)
90                             break subMatchAttempt;
91
92                     wildCardPosition++;
93                 }
94
95                 return checkWildCardEnd(wildcardExpression, wildCardPosition);
96             }
97
98         }
99
100         return checkWildCardEnd(wildcardExpression, wildCardPosition);
101     }
102
103 }