/** * Analytica - beta version - Systems Monitoring Tool * * Copyright (C) 2013, KleeGroup, direction.technique@kleegroup.com (http://www.kleegroup.com) * KleeGroup, Centre d'affaire la Boursidi�re - BP 159 - 92357 Le Plessis Robinson Cedex - France * * This program is free software; you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Foundation; * either version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with this program; * if not, see <http://www.gnu.org/licenses> * * Linking this library statically or dynamically with other modules is making a combined work based on this library. * Thus, the terms and conditions of the GNU General Public License cover the whole combination. * * As a special exception, the copyright holders of this library give you permission to link this library * with independent modules to produce an executable, regardless of the license terms of these independent modules, * and to copy and distribute the resulting executable under terms of your choice, provided that you also meet, * for each linked independent module, the terms and conditions of the license of that module. * An independent module is a module which is not derived from or based on this library. * If you modify this library, you may extend this exception to your version of the library, * but you are not obliged to do so. * If you do not wish to do so, delete this exception statement from your version. */ package io.analytica.spies.imp.javassist.matcher; import java.util.StringTokenizer; /** * Class matches simple regular expressions of the form: * <li>this* * <li>* is so * * <li>input_file_*.dat * <li>com.ml.gdfs.common.util.text.* * <li>?he q???k br?wn fox * <li>java 1.4.? * * @author npiedeloup * @version $Id: GlobMatcher.java,v 1.1 2011/05/12 10:16:12 prahmoune Exp $ */ public final class RegExpMatcher implements Matcher<String> { private final char[][] patternParts; private final String pattenString; /** * @param pattenString initializes the matcher with the glob patterm. */ public RegExpMatcher(final String pattenString) { //Assertion.notNull(pattenString); //--------------------------------------------------------------------- this.pattenString = pattenString; patternParts = getPatternParts(pattenString); } /** {@inheritDoc}*/ public boolean isMatch(final String inputString) { //Assertion.notNull(inputString); //--------------------------------------------------------------------- return isMatch(inputString, patternParts); } private static char[][] getPatternParts(final String pattenString) { final String[] sections = tokenize(pattenString, "*", true); final char[][] patternParts = new char[sections.length][]; for (int i = 0; i < sections.length; i++) { patternParts[i] = sections[i].toCharArray(); } return patternParts; } private static boolean isMatch(final String input, final char[][] patternParts) { final char[] in = input.toCharArray(); boolean canSkip = false; int currentIndex = 0; for (int i = 0; i < patternParts.length; i++) { if (patternParts[i][0] == '*') { canSkip = true; } else { if (!canSkip) { if (!matchesFixed(in, currentIndex, patternParts[i])) { return false; } currentIndex = currentIndex + patternParts[i].length; } else { final int m = nextFixedMatch(in, currentIndex, patternParts[i]); if (m == -1) { return false; } currentIndex = m + patternParts[i].length; } canSkip = false; } } return canSkip || currentIndex == in.length; } private static int nextFixedMatch(final char[] cs, final int offSet, final char[] ps) { final int endIndex = cs.length - ps.length + 1; for (int i = offSet; i < endIndex; i++) { if (matchesFixed(cs, i, ps)) { return i; } } return -1; } private static boolean matchesFixed(final char[] cs, final int offSet, final char[] ps) { for (int i = 0; i < ps.length; i++) { final int c = i + offSet; if (c >= cs.length) { return false; } if (cs[c] != ps[i] && ps[i] != '?') { return false; } } return true; } private static String[] tokenize(final String str, final String delim, final boolean returnDelims) { //Assertion.notNull(str); //Assertion.notNull(delim); final StringTokenizer tokenizer = new StringTokenizer(str, delim, returnDelims); final String[] matches = new String[tokenizer.countTokens()]; for (int i = 0; i < matches.length; i++) { matches[i] = tokenizer.nextToken(); } return matches; } /** {@inheritDoc} */ @Override public String toString() { return "<regexp pattern=\"" + pattenString + "\"/>"; } }