001 /* 002 * Sonar, open source software quality management tool. 003 * Copyright (C) 2008-2011 SonarSource 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 }