WildcardMatcher.java

    1/*******************************************************************************
    2 * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
    3 * All rights reserved. This program and the accompanying materials
    4 * are made available under the terms of the Eclipse Public License v1.0
    5 * which accompanies this distribution, and is available at
    6 * http://www.eclipse.org/legal/epl-v10.html
    7 *
    8 * Contributors:
    9 *    Marc R. Hoffmann - initial API and implementation
   10 *    
   11 * $Id: $
   12 *******************************************************************************/
   13package org.jacoco.core.runtime;
   14
   15import java.util.StringTokenizer;
   16import java.util.regex.Pattern;
   17
   18/**
   19 * Matches strings against <code>?</code>/<code>*</code> wildcard expressions.
   20 * Multiple expressions can be separated with a vertical bar (|). In this case the
   21 * expression matches if at least one part matches.
   22 * 
   23 * @author Marc R. Hoffmann
   24 * @version $Revision: $
   25 */
   26public class WildcardMatcher {
   27
   28    private final Pattern pattern;
   29
   30    /**
   31     * Creates a new matcher with the given expression.
   32     * 
   33     * @param expression
   34     *            wildcard expressions
   35     */
   36    public WildcardMatcher(final String expression) {
   37        final String[] parts = expression.split("\\|");
   38        final StringBuilder regex = new StringBuilder(expression.length() * 2);
   39        boolean next = false;
   40        for (final String part : parts) {
   41            if (next) {
   42                regex.append('|');
   43            }
   44            regex.append('(').append(toRegex(part)).append(')');
   45            next = true;
   46        }
   47        pattern = Pattern.compile(regex.toString());
   48    }
   49
   50    private static CharSequence toRegex(final String expression) {
   51        final StringBuilder regex = new StringBuilder(expression.length() * 2);
   52        final StringTokenizer st = new StringTokenizer(expression, "?*", true);
   53        while (st.hasMoreTokens()) {
   54            final String token = st.nextToken();
   55            if (token.equals("?")) {
   56                regex.append(".?");
   57            } else if (token.equals("*")) {
   58                regex.append(".*");
   59            } else {
   60                regex.append(Pattern.quote(token));
   61            }
   62        }
   63        return regex;
   64    }
   65
   66    /**
   67     * Matches the given string against the expressions of this matcher.
   68     * 
   69     * @param s
   70     *            string to test
   71     * @return <code>true</code>, if the expression matches
   72     */
   73    public boolean matches(final String s) {
   74        return pattern.matcher(s).matches();
   75    }
   76
   77}