WildcardMatcher.java

    1/*******************************************************************************
    2 * Copyright (c) 2009, 2010 Mountainminds GmbH & Co. KG and Contributors
    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 *******************************************************************************/
   12package org.jacoco.core.runtime;
   13
   14import java.util.StringTokenizer;
   15import java.util.regex.Pattern;
   16
   17/**
   18 * Matches strings against <code>?</code>/<code>*</code> wildcard expressions.
   19 * Multiple expressions can be separated with a vertical bar (|). In this case
   20 * the expression matches if at least one part matches.
   21 * 
   22 * @author Marc R. Hoffmann
   23 * @version 0.4.1.20101007204400
   24 */
   25public class WildcardMatcher {
   26
   27    private final Pattern pattern;
   28
   29    /**
   30     * Creates a new matcher with the given expression.
   31     * 
   32     * @param expression
   33     *            wildcard expressions
   34     */
   35    public WildcardMatcher(final String expression) {
   36        final String[] parts = expression.split("\\|");
   37        final StringBuilder regex = new StringBuilder(expression.length() * 2);
   38        boolean next = false;
   39        for (final String part : parts) {
   40            if (next) {
   41                regex.append('|');
   42            }
   43            regex.append('(').append(toRegex(part)).append(')');
   44            next = true;
   45        }
   46        pattern = Pattern.compile(regex.toString());
   47    }
   48
   49    private static CharSequence toRegex(final String expression) {
   50        final StringBuilder regex = new StringBuilder(expression.length() * 2);
   51        final StringTokenizer st = new StringTokenizer(expression, "?*", true);
   52        while (st.hasMoreTokens()) {
   53            final String token = st.nextToken();
   54            if (token.equals("?")) {
   55                regex.append(".?");
   56            } else if (token.equals("*")) {
   57                regex.append(".*");
   58            } else {
   59                regex.append(Pattern.quote(token));
   60            }
   61        }
   62        return regex;
   63    }
   64
   65    /**
   66     * Matches the given string against the expressions of this matcher.
   67     * 
   68     * @param s
   69     *            string to test
   70     * @return <code>true</code>, if the expression matches
   71     */
   72    public boolean matches(final String s) {
   73        return pattern.matcher(s).matches();
   74    }
   75
   76}