1 56 57 package org.jdom.contrib.input.scanner; 58 59 60 import java.lang.reflect.InvocationTargetException ; 61 import java.lang.reflect.Constructor ; 62 import java.lang.reflect.Modifier ; 63 64 import org.jdom.Element; 65 import org.jdom.JDOMException; 66 67 import org.xml.sax.Attributes ; 68 69 70 89 public abstract class XPathMatcher { 90 91 98 private final static String IMPLEMENTATION_CLASS_PROPERTY = 99 "org.jdom.XPathMatcher.class"; 100 101 104 private final static String DEFAULT_IMPLEMENTATION_CLASS = 105 "org.jdom.contrib.input.scanner.JakartaRegExpXPathMatcher"; 106 107 113 private static Constructor constructor = null; 114 115 118 private static boolean debug = false; 119 120 123 private final String expression; 124 125 128 private final ElementListener listener; 129 130 139 protected XPathMatcher(String expression, ElementListener listener) 140 throws JDOMException { 141 if ((expression == null) || (expression.length() == 0)) { 142 throw (new JDOMException( 143 "Invalid XPath expression: \"" + expression + "\"")); 144 } 145 if (listener == null) { 146 throw (new JDOMException("Invalid ElementListener: <null>")); 147 } 148 this.expression = expression; 149 this.listener = listener; 150 } 151 152 157 public String getExpression() { 158 return (this.expression); 159 } 160 161 166 public ElementListener getListener() { 167 return (this.listener); 168 } 169 170 186 abstract public boolean match(String path, Attributes attrs); 187 188 207 abstract public boolean match(String path, Element elt); 208 209 220 protected static String getPathPatternAsRE(String expr) 221 throws JDOMException { 222 if ((expr == null) || (expr.length() == 0)) { 223 expr = "/*"; 224 } 225 226 String path = (expr.endsWith("]"))? 232 expr.substring(0, expr.lastIndexOf('[')): expr; 233 234 int length = path.length(); 235 StringBuffer re = new StringBuffer (2 * length); 236 237 char previous = (char)0; 238 for (int i=0; i<length; i++) { 239 char current = path.charAt(i); 240 241 if (i == 0) { 242 re.append((current == '/')? '^': '/'); 243 } 244 if (current == '*') { 245 if (previous == '\\') { 246 re.setLength(re.length() - 1); 248 } 249 else { 250 re.append(".[^/]"); 253 } 254 re.append('*'); 255 } 256 else { 257 if ((current == '/') && (previous == '/')) { 258 re.setLength(re.length() - 1); 261 262 re.append("(/.*/|/)"); 264 } 265 else { 266 re.append(current); 267 } 268 } 269 previous = current; 270 } 271 re.append('$'); 272 273 return (re.toString()); 274 } 275 276 288 protected static String getTestPattern(String expr) throws JDOMException { 289 if (expr.endsWith("]")) { 290 return (expr.substring(expr.lastIndexOf('['))); 291 } 292 else { 293 return (null); 294 } 295 } 296 297 298 302 311 public static void setDebug(boolean value) { 312 debug = value; 313 } 314 315 321 public static boolean isDebug() { 322 return (debug); 323 } 324 325 337 public static void setXPathMatcherClass(Class aClass) 338 throws IllegalArgumentException , JDOMException { 339 if (aClass != null) { 340 try { 341 if ((XPathMatcher.class.isAssignableFrom(aClass)) && 342 (Modifier.isAbstract(aClass.getModifiers()) == false)) { 343 constructor = aClass.getConstructor( 346 new Class [] { String .class, ElementListener.class }); 347 } 348 else { 349 throw (new JDOMException( 350 aClass.getName() + " is not a concrete XPathMatcher")); 351 } 352 } 353 catch (Exception ex1) { 354 throw (new JDOMException(ex1.toString(), ex1)); 356 } 357 } 358 else { 359 throw (new IllegalArgumentException ("aClass")); 360 } 361 } 362 363 373 public static final XPathMatcher newXPathMatcher( 374 String expression, ElementListener listener) 375 throws JDOMException { 376 try { 377 if (constructor == null) { 378 String className = System.getProperty( 381 IMPLEMENTATION_CLASS_PROPERTY, 382 DEFAULT_IMPLEMENTATION_CLASS); 383 384 setXPathMatcherClass(Class.forName(className)); 385 } 386 return ((XPathMatcher)(constructor.newInstance(new Object [] 387 { expression, listener }))); 388 } 389 catch (InvocationTargetException ex1) { 390 Throwable te = ex1.getTargetException(); 392 393 throw ((te instanceof JDOMException)? (JDOMException)te: 394 new JDOMException(te.toString(), te)); 395 } 396 catch (Exception ex3) { 397 throw (new JDOMException(ex3.toString(), ex3)); 399 } 400 } 401 } 402 403 | Popular Tags |