1 11 package org.eclipse.jdt.internal.corext.util; 12 13 import org.eclipse.jdt.core.Flags; 14 import org.eclipse.jdt.core.search.IJavaSearchConstants; 15 import org.eclipse.jdt.core.search.IJavaSearchScope; 16 import org.eclipse.jdt.core.search.SearchEngine; 17 import org.eclipse.jdt.core.search.SearchPattern; 18 import org.eclipse.jdt.core.search.TypeNameMatch; 19 20 import org.eclipse.jdt.ui.dialogs.ITypeInfoFilterExtension; 21 22 import org.eclipse.jdt.internal.ui.util.StringMatcher; 23 24 public class TypeInfoFilter { 25 26 private static class PatternMatcher { 27 28 private String fPattern; 29 private int fMatchKind; 30 private StringMatcher fStringMatcher; 31 32 private static final char END_SYMBOL= '<'; 33 private static final char ANY_STRING= '*'; 34 private static final char BLANK= ' '; 35 36 public PatternMatcher(String pattern, boolean ignoreCase) { 37 this(pattern, SearchPattern.R_EXACT_MATCH | SearchPattern.R_PREFIX_MATCH | 38 SearchPattern.R_PATTERN_MATCH | SearchPattern.R_CAMELCASE_MATCH); 39 } 40 41 public PatternMatcher(String pattern, int allowedModes) { 42 initializePatternAndMatchKind(pattern); 43 fMatchKind= fMatchKind & allowedModes; 44 if (fMatchKind == SearchPattern.R_PATTERN_MATCH) { 45 fStringMatcher= new StringMatcher(fPattern, true, false); 46 } 47 } 48 49 public String getPattern() { 50 return fPattern; 51 } 52 53 public int getMatchKind() { 54 return fMatchKind; 55 } 56 57 public boolean matches(String text) { 58 switch (fMatchKind) { 59 case SearchPattern.R_PATTERN_MATCH: 60 return fStringMatcher.match(text); 61 case SearchPattern.R_EXACT_MATCH: 62 return fPattern.equalsIgnoreCase(text); 63 case SearchPattern.R_CAMELCASE_MATCH: 64 if (SearchPattern.camelCaseMatch(fPattern, text)) { 65 return true; 66 } 67 default: 69 return Strings.startsWithIgnoreCase(text, fPattern); 70 } 71 } 72 73 private void initializePatternAndMatchKind(String pattern) { 74 int length= pattern.length(); 75 if (length == 0) { 76 fMatchKind= SearchPattern.R_EXACT_MATCH; 77 fPattern= pattern; 78 return; 79 } 80 char last= pattern.charAt(length - 1); 81 82 if (pattern.indexOf('*') != -1 || pattern.indexOf('?') != -1) { 83 fMatchKind= SearchPattern.R_PATTERN_MATCH; 84 switch (last) { 85 case END_SYMBOL: 86 fPattern= pattern.substring(0, length - 1); 87 break; 88 case BLANK: 89 fPattern= pattern.trim(); 90 break; 91 case ANY_STRING: 92 fPattern= pattern; 93 break; 94 default: 95 fPattern= pattern + ANY_STRING; 96 } 97 return; 98 } 99 100 if (last == END_SYMBOL) { 101 fMatchKind= SearchPattern.R_EXACT_MATCH; 102 fPattern= pattern.substring(0, length - 1); 103 return; 104 } 105 106 if (last == BLANK) { 107 fMatchKind= SearchPattern.R_EXACT_MATCH; 108 fPattern= pattern.trim(); 109 return; 110 } 111 112 if (SearchUtils.isCamelCasePattern(pattern)) { 113 fMatchKind= SearchPattern.R_CAMELCASE_MATCH; 114 fPattern= pattern; 115 return; 116 } 117 118 fMatchKind= SearchPattern.R_PREFIX_MATCH; 119 fPattern= pattern; 120 } 121 } 122 123 private String fText; 124 private IJavaSearchScope fSearchScope; 125 private boolean fIsWorkspaceScope; 126 private int fElementKind; 127 private ITypeInfoFilterExtension fFilterExtension; 128 private TypeInfoRequestorAdapter fAdapter= new TypeInfoRequestorAdapter(); 129 130 private PatternMatcher fPackageMatcher; 131 private PatternMatcher fNameMatcher; 132 133 private static final int TYPE_MODIFIERS= Flags.AccEnum | Flags.AccAnnotation | Flags.AccInterface; 134 135 public TypeInfoFilter(String text, IJavaSearchScope scope, int elementKind, ITypeInfoFilterExtension extension) { 136 fText= text; 137 fSearchScope= scope; 138 fIsWorkspaceScope= fSearchScope.equals(SearchEngine.createWorkspaceScope()); 139 fElementKind= elementKind; 140 fFilterExtension= extension; 141 142 int index= text.lastIndexOf("."); if (index == -1) { 144 fNameMatcher= new PatternMatcher(text, true); 145 } else { 146 fPackageMatcher= new PatternMatcher(evaluatePackagePattern(text.substring(0, index)), true); 147 String name= text.substring(index + 1); 148 if (name.length() == 0) 149 name= "*"; fNameMatcher= new PatternMatcher(name, true); 151 } 152 } 153 154 157 private String evaluatePackagePattern(String s) { 158 StringBuffer buf= new StringBuffer (); 159 boolean hasWildCard= false; 160 for (int i= 0; i < s.length(); i++) { 161 char ch= s.charAt(i); 162 if (ch == '.') { 163 if (!hasWildCard) { 164 buf.append('*'); 165 } 166 hasWildCard= false; 167 } else if (ch == '*' || ch =='?') { 168 hasWildCard= true; 169 } 170 buf.append(ch); 171 } 172 if (!hasWildCard) { 173 buf.append('*'); 174 } 175 return buf.toString(); 176 } 177 178 public String getText() { 179 return fText; 180 } 181 182 public boolean isSubFilter(String text) { 183 if (! fText.startsWith(text)) 184 return false; 185 186 return fText.indexOf('.', text.length()) == -1; 187 } 188 189 public boolean isCamelCasePattern() { 190 return fNameMatcher.getMatchKind() == SearchPattern.R_CAMELCASE_MATCH; 191 } 192 193 public String getPackagePattern() { 194 if (fPackageMatcher == null) 195 return null; 196 return fPackageMatcher.getPattern(); 197 } 198 199 public String getNamePattern() { 200 return fNameMatcher.getPattern(); 201 } 202 203 public int getSearchFlags() { 204 return fNameMatcher.getMatchKind(); 205 } 206 207 public int getPackageFlags() { 208 if (fPackageMatcher == null) 209 return SearchPattern.R_EXACT_MATCH; 210 211 return fPackageMatcher.getMatchKind(); 212 } 213 214 public boolean matchesRawNamePattern(TypeNameMatch type) { 215 return Strings.startsWithIgnoreCase(type.getSimpleTypeName(), fNameMatcher.getPattern()); 216 } 217 218 public boolean matchesCachedResult(TypeNameMatch type) { 219 if (!(matchesPackage(type) && matchesFilterExtension(type))) 220 return false; 221 return matchesName(type); 222 } 223 224 public boolean matchesHistoryElement(TypeNameMatch type) { 225 if (!(matchesPackage(type) && matchesModifiers(type) && matchesScope(type) && matchesFilterExtension(type))) 226 return false; 227 return matchesName(type); 228 } 229 230 public boolean matchesFilterExtension(TypeNameMatch type) { 231 if (fFilterExtension == null) 232 return true; 233 fAdapter.setMatch(type); 234 return fFilterExtension.select(fAdapter); 235 } 236 237 private boolean matchesName(TypeNameMatch type) { 238 return fNameMatcher.matches(type.getSimpleTypeName()); 239 } 240 241 private boolean matchesPackage(TypeNameMatch type) { 242 if (fPackageMatcher == null) 243 return true; 244 return fPackageMatcher.matches(type.getTypeContainerName()); 245 } 246 247 private boolean matchesScope(TypeNameMatch type) { 248 if (fIsWorkspaceScope) 249 return true; 250 return fSearchScope.encloses(type.getType()); 251 } 252 253 private boolean matchesModifiers(TypeNameMatch type) { 254 if (fElementKind == IJavaSearchConstants.TYPE) 255 return true; 256 int modifiers= type.getModifiers() & TYPE_MODIFIERS; 257 switch (fElementKind) { 258 case IJavaSearchConstants.CLASS: 259 return modifiers == 0; 260 case IJavaSearchConstants.ANNOTATION_TYPE: 261 return Flags.isAnnotation(modifiers); 262 case IJavaSearchConstants.INTERFACE: 263 return Flags.isInterface(modifiers); 264 case IJavaSearchConstants.ENUM: 265 return Flags.isEnum(modifiers); 266 case IJavaSearchConstants.CLASS_AND_INTERFACE: 267 return modifiers == 0 || Flags.isInterface(modifiers); 268 case IJavaSearchConstants.CLASS_AND_ENUM: 269 return modifiers == 0 || Flags.isEnum(modifiers); 270 } 271 return false; 272 } 273 } 274 | Popular Tags |