WildcardMatcher.java revision 91d87e36c322e55b4aeaef267abefc123309c642
1/*******************************************************************************
2 * Copyright (c) 2009, 2012 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.regex.Pattern;
15
16/**
17 * Matches strings against <code>?</code>/<code>*</code> wildcard expressions.
18 * Multiple expressions can be separated with a colon (:). In this case the
19 * expression matches if at least one part matches.
20 */
21public class WildcardMatcher {
22
23	private final Pattern pattern;
24
25	/**
26	 * Creates a new matcher with the given expression.
27	 *
28	 * @param expression
29	 *            wildcard expressions
30	 */
31	public WildcardMatcher(final String expression) {
32		final String[] parts = expression.split("\\:");
33		final StringBuilder regex = new StringBuilder(expression.length() * 2);
34		boolean next = false;
35		for (final String part : parts) {
36			if (next) {
37				regex.append('|');
38			}
39			regex.append('(').append(toRegex(part)).append(')');
40			next = true;
41		}
42		pattern = Pattern.compile(regex.toString());
43	}
44
45	private static CharSequence toRegex(final String expression) {
46		final StringBuilder regex = new StringBuilder(expression.length() * 2);
47		for (final char c : expression.toCharArray()) {
48			switch (c) {
49			case '?':
50				regex.append(".?");
51				break;
52			case '*':
53				regex.append(".*");
54				break;
55			default:
56				regex.append(Pattern.quote(String.valueOf(c)));
57			}
58		}
59		return regex;
60	}
61
62	/**
63	 * Matches the given string against the expressions of this matcher.
64	 *
65	 * @param s
66	 *            string to test
67	 * @return <code>true</code>, if the expression matches
68	 */
69	public boolean matches(final String s) {
70		return pattern.matcher(s).matches();
71	}
72
73}
74