1 29 30 package com.caucho.server.dispatch; 31 32 import com.caucho.config.ConfigException; 33 import com.caucho.server.util.CauchoSystem; 34 import com.caucho.util.CharBuffer; 35 import com.caucho.util.L10N; 36 37 import javax.annotation.PostConstruct; 38 import javax.servlet.ServletException ; 39 import java.util.ArrayList ; 40 import java.util.HashSet ; 41 import java.util.regex.Pattern ; 42 43 46 public class FilterMapping extends FilterConfigImpl { 47 static L10N L = new L10N(FilterMapping.class); 48 49 private String _urlPattern; 50 private final ArrayList <String > _servletNames = new ArrayList <String >(); 51 52 private final ArrayList <Match> _matchList = new ArrayList <Match>(); 54 55 private HashSet <String > _dispatcher; 56 57 60 public FilterMapping() 61 { 62 } 63 64 67 public URLPattern createUrlPattern() 68 throws ServletException 69 { 70 return new URLPattern(); 71 } 72 73 76 public String getURLPattern() 77 { 78 return _urlPattern; 79 } 80 81 84 public void setURLRegexp(String pattern) 85 throws ServletException 86 { 87 Pattern regexp; 88 89 if (CauchoSystem.isCaseInsensitive()) 90 regexp = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE); 91 else 92 regexp = Pattern.compile(pattern, 0); 93 94 _matchList.add(Match.createInclude(regexp)); 95 } 96 97 100 public void addServletName(String servletName) 101 { 102 _servletNames.add(servletName); 103 } 104 105 108 public void addDispatcher(String dispatcher) 109 throws ConfigException 110 { 111 if (_dispatcher == null) 112 _dispatcher = new HashSet <String >(); 113 114 if (dispatcher == null 115 || (! dispatcher.equals("REQUEST") 116 && ! dispatcher.equals("FORWARD") 117 && ! dispatcher.equals("INCLUDE") 118 && ! dispatcher.equals("ERROR"))) { 119 throw new ConfigException(L.l("`{0}' is an unknown value for <dispatcher> `REQUEST', `FORWARD', `INCLUDE', and `ERROR' are the valid values.", 120 dispatcher)); 121 } 122 123 _dispatcher.add(dispatcher); 124 } 125 126 129 public boolean isRequest() 130 { 131 return _dispatcher == null || _dispatcher.contains("REQUEST"); 132 } 133 134 137 public boolean isInclude() 138 { 139 return _dispatcher != null && _dispatcher.contains("INCLUDE"); 140 } 141 142 145 public boolean isForward() 146 { 147 return _dispatcher != null && _dispatcher.contains("FORWARD"); 148 } 149 150 153 public boolean isError() 154 { 155 return _dispatcher != null && _dispatcher.contains("ERROR"); 156 } 157 158 164 boolean isMatch(String servletName) 165 { 166 for (int i = 0; i < _servletNames.size(); i++) { 167 String matchName = _servletNames.get(i); 168 169 if (servletName.equals(matchName) || "*".equals(matchName)) 170 return true; 171 } 172 173 return false; 174 } 175 176 181 boolean isMatch(ServletInvocation invocation) 182 { 183 return isMatch(invocation.getServletPath(), invocation.getPathInfo()); 184 } 185 186 189 public boolean isMatch(String servletPath, String pathInfo) 190 { 191 String uri; 192 193 if (pathInfo == null) 194 uri = servletPath; 195 else if (servletPath == null) 196 uri = pathInfo; 197 else 198 uri = servletPath + pathInfo; 199 200 int size = _matchList.size(); 201 202 for (int i = 0; i < size; i++) { 203 Match match = _matchList.get(i); 204 205 int value = match.match(uri); 206 207 switch (value) { 208 case Match.INCLUDE: 209 return true; 210 case Match.EXCLUDE: 211 return false; 212 } 213 } 214 215 return false; 216 } 217 218 226 private Pattern urlPatternToRegexp(String pattern, int flags) 227 throws ServletException 228 { 229 if (pattern.length() == 0 || 230 pattern.length() == 1 && pattern.charAt(0) == '/') { 231 try { 232 return Pattern.compile("^/$", flags); 233 } catch (Exception e) { 234 throw new ServletException (e); 235 } 236 } 237 238 int length = pattern.length(); 239 boolean isExact = true; 240 241 if (pattern.charAt(0) != '/' && pattern.charAt(0) != '*') { 242 pattern = "/" + pattern; 243 length++; 244 } 245 246 int prefixLength = -1; 247 boolean isShort = false; 248 CharBuffer cb = new CharBuffer(); 249 cb.append("^"); 250 for (int i = 0; i < length; i++) { 251 char ch = pattern.charAt(i); 252 253 if (ch == '*' && i + 1 == length && i > 0) { 254 isExact = false; 255 256 if (pattern.charAt(i - 1) == '/') { 257 cb.setLength(cb.length() - 1); 258 259 if (prefixLength < 0) 260 prefixLength = i - 1; 261 262 } 263 else if (prefixLength < 0) 264 prefixLength = i; 265 266 if (prefixLength == 0) 267 prefixLength = 1; 268 } 269 else if (ch == '*') { 270 isExact = false; 271 cb.append(".*"); 272 if (prefixLength < 0) 273 prefixLength = i; 274 275 if (i == 0) 276 isShort = true; 277 } 278 else if (ch == '.' || ch == '[' || ch == '^' || ch == '$' || 279 ch == '{' || ch == '}' || ch == '|' || 280 ch == '(' || ch == ')' || ch == '?') { 281 cb.append('\\'); 282 cb.append(ch); 283 } 284 else 285 cb.append(ch); 286 } 287 288 if (isExact) 289 cb.append('$'); 290 else 291 cb.append("(?=/)|" + cb.toString() + "$"); 292 293 try { 294 return Pattern.compile(cb.close(), flags); 295 } catch (Exception e) { 296 throw new ServletException (e); 297 } 298 } 299 300 303 public String toString() 304 { 305 return "FilterMapping[pattern=" + _urlPattern + ",name=" + getFilterName() + "]"; 306 } 307 308 public class URLPattern { 309 boolean _hasInclude = false; 310 311 314 public void addText(String pattern) 315 throws ServletException 316 { 317 pattern = pattern.trim(); 318 319 _urlPattern = pattern; 320 321 Pattern regexp; 322 323 if (CauchoSystem.isCaseInsensitive()) 324 regexp = urlPatternToRegexp(pattern, Pattern.CASE_INSENSITIVE); 325 else 326 regexp = urlPatternToRegexp(pattern, 0); 327 328 _hasInclude = true; 329 330 _matchList.add(Match.createInclude(regexp)); 331 } 332 333 336 public void addIncludePattern(String pattern) 337 throws ServletException 338 { 339 pattern = pattern.trim(); 340 341 Pattern regexp; 342 343 if (CauchoSystem.isCaseInsensitive()) 344 regexp = urlPatternToRegexp(pattern, Pattern.CASE_INSENSITIVE); 345 else 346 regexp = urlPatternToRegexp(pattern, 0); 347 348 _hasInclude = true; 349 350 _matchList.add(Match.createInclude(regexp)); 351 } 352 353 356 public void addExcludePattern(String pattern) 357 throws ServletException 358 { 359 pattern = pattern.trim(); 360 361 Pattern regexp; 362 363 if (CauchoSystem.isCaseInsensitive()) 364 regexp = urlPatternToRegexp(pattern, Pattern.CASE_INSENSITIVE); 365 else 366 regexp = urlPatternToRegexp(pattern, 0); 367 368 _matchList.add(Match.createExclude(regexp)); 369 } 370 371 374 public void addIncludeRegexp(String pattern) 375 { 376 pattern = pattern.trim(); 377 378 Pattern regexp; 379 380 if (CauchoSystem.isCaseInsensitive()) 381 regexp = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE); 382 else 383 regexp = Pattern.compile(pattern, 0); 384 385 _hasInclude = true; 386 387 _matchList.add(Match.createInclude(regexp)); 388 } 389 390 393 public void addExcludeRegexp(String pattern) 394 { 395 pattern = pattern.trim(); 396 397 Pattern regexp; 398 399 if (CauchoSystem.isCaseInsensitive()) 400 regexp = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE); 401 else 402 regexp = Pattern.compile(pattern, 0); 403 404 _matchList.add(Match.createExclude(regexp)); 405 } 406 407 410 @PostConstruct 411 public void init() 412 throws Exception 413 { 414 if (_matchList.size() > 0 && ! _hasInclude) { 415 Pattern regexp = Pattern.compile(""); 416 _matchList.add(Match.createInclude(regexp)); 417 } 418 } 419 } 420 421 static class Match { 422 static final int INCLUDE = 1; 423 static final int EXCLUDE = -1; 424 static final int NO_MATCH = 0; 425 426 private final Pattern _regexp; 427 private final int _value; 428 429 private Match(Pattern regexp, int value) 430 { 431 _regexp = regexp; 432 _value = value; 433 } 434 435 438 static Match createInclude(Pattern regexp) 439 { 440 return new Match(regexp, INCLUDE); 441 } 442 443 446 static Match createExclude(Pattern regexp) 447 { 448 return new Match(regexp, EXCLUDE); 449 } 450 451 454 int match(String uri) 455 { 456 if (_regexp.matcher(uri).find()) 457 return _value; 458 else 459 return NO_MATCH; 460 } 461 } 462 } 463 | Popular Tags |