1 17 18 19 package org.apache.commons.digester; 20 21 22 import java.util.ArrayList ; 23 import java.util.Collections ; 24 import java.util.Comparator ; 25 import java.util.HashMap ; 26 import java.util.Iterator ; 27 import java.util.List ; 28 import java.util.Map ; 29 30 31 167 168 169 public class ExtendedBaseRules extends RulesBase { 170 171 172 174 177 private int counter = 0; 178 179 180 187 private Map order = new HashMap (); 188 189 190 192 193 199 public void add(String pattern, Rule rule) { 200 super.add(pattern, rule); 201 counter++; 202 order.put(rule, new Integer (counter)); 203 } 204 205 206 215 public List match(String namespace, String pattern) { 216 String parentPattern = ""; 219 int lastIndex = pattern.lastIndexOf('/'); 220 221 boolean hasParent = true; 222 if (lastIndex == -1) { 223 hasParent = false; 225 226 } else { 227 parentPattern = pattern.substring(0, lastIndex); 229 230 } 231 232 233 List universalList = new ArrayList (counter); 235 236 List tempList = (List ) this.cache.get("!*"); 239 if (tempList != null) { 240 universalList.addAll(tempList); 241 } 242 243 tempList = (List ) this.cache.get("!" + parentPattern + "/?"); 246 if (tempList != null) { 247 universalList.addAll(tempList); 248 } 249 250 251 boolean ignoreBasicMatches = false; 255 256 257 List rulesList = (List ) this.cache.get(pattern); 259 if (rulesList != null) { 260 ignoreBasicMatches = true; 263 264 } else { 265 266 if (hasParent) { 268 rulesList = (List ) this.cache.get(parentPattern + "/?"); 270 if (rulesList != null) { 271 ignoreBasicMatches = true; 274 275 } else { 276 rulesList = findExactAncesterMatch(pattern); 279 if (rulesList != null) { 280 ignoreBasicMatches = true; 283 } 284 } 285 } 286 } 287 288 289 293 String longKey = ""; 295 int longKeyLength = 0; 296 297 Iterator keys = this.cache.keySet().iterator(); 298 while (keys.hasNext()) { 299 String key = (String ) keys.next(); 300 301 boolean isUniversal = key.startsWith("!"); 304 if (isUniversal) { 305 key = key.substring(1, key.length()); 307 } 308 309 310 boolean wildcardMatchStart = key.startsWith("*/"); 312 boolean wildcardMatchEnd = key.endsWith("/*"); 313 if (wildcardMatchStart || (isUniversal && wildcardMatchEnd)) { 314 315 boolean parentMatched = false; 316 boolean basicMatched = false; 317 boolean ancesterMatched = false; 318 319 boolean parentMatchEnd = key.endsWith("/?"); 320 if (parentMatchEnd) { 321 parentMatched = parentMatch(key, pattern, parentPattern); 323 324 } else if (wildcardMatchEnd) { 325 if (wildcardMatchStart) { 327 String patternBody = key.substring(2, key.length() - 2); 328 if (pattern.endsWith(patternBody)) { 329 ancesterMatched = true; 330 } else { 331 ancesterMatched = (pattern.indexOf(patternBody + "/") > -1); 332 } 333 } else { 334 String bodyPattern = key.substring(0, key.length() - 2); 335 if (pattern.startsWith(bodyPattern)) 336 { 337 if (pattern.length() == bodyPattern.length()) { 338 ancesterMatched = true; 340 } else { 341 ancesterMatched = ( pattern.charAt(bodyPattern.length()) == '/' ); 342 } 343 } else { 344 ancesterMatched = false; 345 } 346 } 347 } else { 348 basicMatched = basicMatch(key, pattern); 350 } 351 352 if (parentMatched || basicMatched || ancesterMatched) { 353 if (isUniversal) { 354 tempList = (List ) this.cache.get("!" + key); 357 if (tempList != null) { 358 universalList.addAll(tempList); 359 } 360 361 } else { 362 if (!ignoreBasicMatches) { 363 int keyLength = key.length(); 370 if (wildcardMatchStart) { 371 --keyLength; 372 } 373 if (wildcardMatchEnd) { 374 --keyLength; 375 } else if (parentMatchEnd) { 376 --keyLength; 377 } 378 379 if (keyLength > longKeyLength) { 380 rulesList = (List ) this.cache.get(key); 381 longKey = key; 382 longKeyLength = keyLength; 383 } 384 } 385 } 386 } 387 } 388 } 389 390 391 if (rulesList == null) { 394 rulesList = (List ) this.cache.get("*"); 395 } 396 397 if (rulesList != null) { 399 universalList.addAll(rulesList); 400 } 401 402 403 if (namespace != null) { 405 Iterator it = universalList.iterator(); 407 while (it.hasNext()) { 408 Rule rule = (Rule) it.next(); 409 String ns_uri = rule.getNamespaceURI(); 410 if (ns_uri != null && !ns_uri.equals(namespace)) { 411 it.remove(); 412 } 413 } 414 } 415 416 417 Collections.sort( 420 universalList, 421 new Comparator () { 422 423 public int compare(Object o1, Object o2) throws ClassCastException { 424 Integer i1 = (Integer ) order.get(o1); 426 Integer i2 = (Integer ) order.get(o2); 427 428 if (i1 == null) { 430 if (i2 == null) { 431 432 return 0; 433 434 } else { 435 436 return -1; 437 438 } 439 } else if (i2 == null) { 440 return 1; 441 } 442 443 return (i1.intValue() - i2.intValue()); 444 } 445 }); 446 447 return universalList; 448 } 449 450 453 private boolean parentMatch(String key, String pattern, String parentPattern) { 454 return parentPattern.endsWith(key.substring(1, key.length() - 2)); 455 } 456 457 461 private boolean basicMatch(String key, String pattern) { 462 return (pattern.equals(key.substring(2)) || 463 pattern.endsWith(key.substring(1))); 464 } 465 466 469 private List findExactAncesterMatch(String parentPattern) { 470 List matchingRules = null; 471 int lastIndex = parentPattern.length(); 472 while (lastIndex-- > 0) { 473 lastIndex = parentPattern.lastIndexOf('/', lastIndex); 474 if (lastIndex > 0) { 475 matchingRules = (List ) this.cache.get(parentPattern.substring(0, lastIndex) + "/*"); 476 if (matchingRules != null) { 477 return matchingRules; 478 } 479 } 480 } 481 return null; 482 } 483 } 484 | Popular Tags |