001 /*
002 * Sonar, open source software quality management tool.
003 * Copyright (C) 2009 SonarSource SA
004 * mailto:contact AT sonarsource DOT com
005 *
006 * Sonar is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 3 of the License, or (at your option) any later version.
010 *
011 * Sonar is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 * Lesser General Public License for more details.
015 *
016 * You should have received a copy of the GNU Lesser General Public
017 * License along with Sonar; if not, write to the Free Software
018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
019 */
020 package org.sonar.api.utils;
021
022 import org.apache.commons.lang.StringUtils;
023
024 import java.util.HashMap;
025 import java.util.Map;
026 import java.util.regex.Pattern;
027
028 /**
029 * @since 1.10
030 */
031 public class WildcardPattern {
032
033 private static final Map<String, WildcardPattern> patterns = new HashMap<String, WildcardPattern>();
034
035 private Pattern pattern;
036 private String stringRepresentation;
037
038 protected WildcardPattern(String pattern, String directorySeparator) {
039 this.stringRepresentation = pattern;
040 this.pattern = Pattern.compile(toRegexp(pattern, directorySeparator));
041 }
042
043 public boolean match(String value) {
044 return pattern.matcher(removeSlahesToIgnore(value)).matches();
045 }
046
047 private String toRegexp(String wildcardPattern, String directorySeparator) {
048 String patternStr = removeSlahesToIgnore(wildcardPattern);
049 patternStr = StringUtils.replace(patternStr, "**/**", "**");
050 patternStr = StringUtils.replace(patternStr, "**/", "(&/|)");
051 patternStr = StringUtils.replace(patternStr, "/**", "&");
052 patternStr = StringUtils.replace(patternStr, "**", "&");
053 StringBuilder sb = new StringBuilder();
054
055 for (char c : patternStr.toCharArray()) {
056 switch (c) {
057 case '&':
058 sb.append(".*");
059 break;
060 case '*':
061 sb.append("[^\\").append(directorySeparator).append("]*");
062 break;
063 case '?':
064 sb.append("[^\\").append(directorySeparator).append("]");
065 break;
066 case '.':
067 sb.append("\\.");
068 break;
069 case '/':
070 sb.append("\\").append(directorySeparator);
071 break;
072 default:
073 sb.append(c);
074 }
075 }
076
077 return sb.toString();
078 }
079
080 private String removeSlahesToIgnore(String wildcardPattern) {
081 String patternStr = StringUtils.removeStart(wildcardPattern, "/");
082 return StringUtils.removeEnd(patternStr, "/");
083 }
084
085 /**
086 * This method is overridden since version 2.5-RC2.
087 */
088 @Override
089 public String toString() {
090 return stringRepresentation;
091 }
092
093 /**
094 * @since 2.4
095 */
096 public static boolean match(WildcardPattern[] patterns, String value) {
097 for (WildcardPattern pattern : patterns) {
098 if (pattern.match(value)) {
099 return true;
100 }
101 }
102 return false;
103 }
104
105 public static WildcardPattern create(String pattern) {
106 return create(pattern, "/");
107 }
108
109 public static WildcardPattern[] create(String[] patterns) {
110 if (patterns == null) {
111 return new WildcardPattern[0];
112 }
113 WildcardPattern[] exclusionPAtterns = new WildcardPattern[patterns.length];
114 for (int i = 0; i < patterns.length; i++) {
115 exclusionPAtterns[i] = create(patterns[i]);
116 }
117 return exclusionPAtterns;
118 }
119
120 public static WildcardPattern create(String pattern, String directorySeparator) {
121 String key = pattern + directorySeparator;
122 WildcardPattern wildcardPattern = patterns.get(key);
123 if (wildcardPattern == null) {
124 wildcardPattern = new WildcardPattern(pattern, directorySeparator);
125 patterns.put(key, wildcardPattern);
126 }
127 return wildcardPattern;
128 }
129 }