1 2 4 10 11 package javax.xml.xpath; 12 13 import java.io.File ; 14 import java.io.FileInputStream ; 15 import java.io.IOException ; 16 import java.io.InputStream ; 17 import java.net.URL ; 18 import java.util.ArrayList ; 19 import java.util.Enumeration ; 20 import java.util.Iterator ; 21 import java.util.NoSuchElementException ; 22 import java.util.Properties ; 23 24 31 class XPathFactoryFinder { 32 33 private static SecuritySupport ss = new SecuritySupport () ; 34 35 private static boolean debug = false; 36 static { 37 try { 39 debug = ss.getSystemProperty("jaxp.debug") != null; 40 } catch (Exception _) { 41 debug = false; 42 } 43 } 44 45 48 private static Properties cacheProps = new Properties (); 49 50 53 private static boolean firstTime = true; 54 55 60 private static void debugPrintln(String msg) { 61 if (debug) { 62 System.err.println("JAXP: " + msg); 63 } 64 } 65 66 69 private final ClassLoader classLoader; 70 71 82 public XPathFactoryFinder(ClassLoader loader) { 83 this.classLoader = loader; 84 if( debug ) { 85 debugDisplayClassLoader(); 86 } 87 } 88 89 private void debugDisplayClassLoader() { 90 try { 91 if( classLoader == ss.getContextClassLoader() ) { 92 debugPrintln("using thread context class loader ("+classLoader+") for search"); 93 return; 94 } 95 } catch( Throwable _ ) { 96 ; } 98 99 if( classLoader==ClassLoader.getSystemClassLoader() ) { 100 debugPrintln("using system class loader ("+classLoader+") for search"); 101 return; 102 } 103 104 debugPrintln("using class loader ("+classLoader+") for search"); 105 } 106 107 119 public XPathFactory newFactory(String uri) { 120 if(uri==null) throw new NullPointerException (); 121 XPathFactory f = _newFactory(uri); 122 if (f != null) { 123 debugPrintln("factory '" + f.getClass().getName() + "' was found for " + uri); 124 } else { 125 debugPrintln("unable to find a factory for " + uri); 126 } 127 return f; 128 } 129 130 137 private XPathFactory _newFactory(String uri) { 138 XPathFactory sf; 139 140 String propertyName = SERVICE_CLASS.getName() + ":" + uri; 141 142 try { 144 debugPrintln("Looking up system property '"+propertyName+"'" ); 145 String r = ss.getSystemProperty(propertyName); 146 if(r!=null) { 147 debugPrintln("The value is '"+r+"'"); 148 sf = createInstance(r); 149 if(sf!=null) return sf; 150 } else 151 debugPrintln("The property is undefined."); 152 } catch( Throwable t ) { 153 if( debug ) { 154 debugPrintln("failed to look up system property '"+propertyName+"'" ); 155 t.printStackTrace(); 156 } 157 } 158 159 String javah = ss.getSystemProperty( "java.home" ); 160 String configFile = javah + File.separator + 161 "lib" + File.separator + "jaxp.properties"; 162 163 String factoryClassName = null ; 164 165 try { 167 if(firstTime){ 168 synchronized(cacheProps){ 169 if(firstTime){ 170 File f=new File ( configFile ); 171 firstTime = false; 172 if(ss.doesFileExist(f)){ 173 debugPrintln("Read properties file " + f); 174 cacheProps.load(ss.getFileInputStream(f)); 175 } 176 } 177 } 178 } 179 factoryClassName = cacheProps.getProperty(propertyName); 180 debugPrintln("found " + factoryClassName + " in $java.home/jaxp.properties"); 181 182 if (factoryClassName != null) { 183 sf = createInstance(factoryClassName); 184 if(sf != null){ 185 return sf; 186 } 187 } 188 } catch (Exception ex) { 189 if (debug) { 190 ex.printStackTrace(); 191 } 192 } 193 194 Iterator sitr = createServiceFileIterator(); 196 while(sitr.hasNext()) { 197 URL resource = (URL )sitr.next(); 198 debugPrintln("looking into " + resource); 199 try { 200 sf = loadFromProperty(uri,resource.toExternalForm(),ss.getURLInputStream(resource)); 202 if(sf!=null) return sf; 203 } catch(IOException e) { 204 if( debug ) { 205 debugPrintln("failed to read "+resource); 206 e.printStackTrace(); 207 } 208 } 209 } 210 211 if(uri.equals(XPathFactory.DEFAULT_OBJECT_MODEL_URI)) { 213 debugPrintln("attempting to use the platform default W3C DOM XPath lib"); 214 return createInstance("com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl"); 215 } 216 217 debugPrintln("all things were tried, but none was found. bailing out."); 218 return null; 219 } 220 221 230 private XPathFactory createInstance( String className ) { 231 try { 232 debugPrintln("instanciating "+className); 233 Class clazz; 234 if( classLoader!=null ) 235 clazz = classLoader.loadClass(className); 236 else 237 clazz = Class.forName(className); 238 if(debug) debugPrintln("loaded it from "+which(clazz)); 239 Object o = clazz.newInstance(); 240 241 if( o instanceof XPathFactory ) 242 return (XPathFactory )o; 243 244 debugPrintln(className+" is not assignable to "+SERVICE_CLASS.getName()); 245 } catch( Throwable t ) { 246 debugPrintln("failed to instanciate "+className); 247 if(debug) t.printStackTrace(); 248 } 249 return null; 250 } 251 252 253 private static abstract class SingleIterator implements Iterator { 254 private boolean seen = false; 255 256 public final void remove() { throw new UnsupportedOperationException (); } 257 public final boolean hasNext() { return !seen; } 258 public final Object next() { 259 if(seen) throw new NoSuchElementException (); 260 seen = true; 261 return value(); 262 } 263 264 protected abstract Object value(); 265 } 266 267 274 private XPathFactory loadFromProperty( String keyName, String resourceName, InputStream in ) 275 throws IOException { 276 debugPrintln("Reading "+resourceName ); 277 278 Properties props = new Properties (); 279 props.load(in); 280 in.close(); 281 String factoryClassName = props.getProperty(keyName); 282 if(factoryClassName != null){ 283 debugPrintln("found "+keyName+" = " + factoryClassName); 284 return createInstance(factoryClassName); 285 } else { 286 debugPrintln(keyName+" is not in the property file"); 287 return null; 288 } 289 } 290 291 295 private Iterator createServiceFileIterator() { 296 if (classLoader == null) { 297 return new SingleIterator() { 298 protected Object value() { 299 ClassLoader classLoader = XPathFactoryFinder .class.getClassLoader(); 300 return ss.getResourceAsURL(classLoader, SERVICE_ID); 301 } 303 }; 304 } else { 305 try { 306 final Enumeration e = ss.getResources(classLoader, SERVICE_ID); 308 if(!e.hasMoreElements()) { 309 debugPrintln("no "+SERVICE_ID+" file was found"); 310 } 311 312 return new Iterator () { 314 public void remove() { 315 throw new UnsupportedOperationException (); 316 } 317 318 public boolean hasNext() { 319 return e.hasMoreElements(); 320 } 321 322 public Object next() { 323 return e.nextElement(); 324 } 325 }; 326 } catch (IOException e) { 327 debugPrintln("failed to enumerate resources "+SERVICE_ID); 328 if(debug) e.printStackTrace(); 329 return new ArrayList ().iterator(); } 331 } 332 } 333 334 private static final Class SERVICE_CLASS = XPathFactory .class; 335 private static final String SERVICE_ID = "META-INF/services/" + SERVICE_CLASS.getName(); 336 337 338 339 private static String which( Class clazz ) { 340 return which( clazz.getName(), clazz.getClassLoader() ); 341 } 342 343 351 private static String which(String classname, ClassLoader loader) { 352 353 String classnameAsResource = classname.replace('.', '/') + ".class"; 354 355 if( loader==null ) loader = ClassLoader.getSystemClassLoader(); 356 357 URL it = ss.getResourceAsURL(loader, classnameAsResource); 359 if (it != null) { 360 return it.toString(); 361 } else { 362 return null; 363 } 364 } 365 } 366 | Popular Tags |