1 2 4 11 12 package javax.xml.validation; 13 14 import java.io.File ; 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 SchemaFactoryFinder { 32 33 34 private static boolean debug = false; 35 38 private static SecuritySupport ss = new SecuritySupport (); 39 42 private static Properties cacheProps = new Properties (); 43 44 47 private static boolean firstTime = true; 48 49 static { 50 try { 52 debug = ss.getSystemProperty("jaxp.debug") != null; 53 } catch (Exception _) { 54 debug = false; 55 } 56 } 57 58 63 private static void debugPrintln(String msg) { 64 if (debug) { 65 System.err.println("JAXP: " + msg); 66 } 67 } 68 69 72 private final ClassLoader classLoader; 73 74 85 public SchemaFactoryFinder(ClassLoader loader) { 86 this.classLoader = loader; 87 if( debug ) { 88 debugDisplayClassLoader(); 89 } 90 } 91 92 private void debugDisplayClassLoader() { 93 try { 94 if( classLoader == ss.getContextClassLoader() ) { 95 debugPrintln("using thread context class loader ("+classLoader+") for search"); 96 return; 97 } 98 } catch( Throwable _ ) { 99 ; } 101 102 if( classLoader==ClassLoader.getSystemClassLoader() ) { 103 debugPrintln("using system class loader ("+classLoader+") for search"); 104 return; 105 } 106 107 debugPrintln("using class loader ("+classLoader+") for search"); 108 } 109 110 123 public SchemaFactory newFactory(String schemaLanguage) { 124 if(schemaLanguage==null) throw new NullPointerException (); 125 SchemaFactory f = _newFactory(schemaLanguage); 126 if (f != null) { 127 debugPrintln("factory '" + f.getClass().getName() + "' was found for " + schemaLanguage); 128 } else { 129 debugPrintln("unable to find a factory for " + schemaLanguage); 130 } 131 return f; 132 } 133 134 141 private SchemaFactory _newFactory(String schemaLanguage) { 142 SchemaFactory sf; 143 144 String propertyName = SERVICE_CLASS.getName() + ":" + schemaLanguage; 145 146 try { 148 debugPrintln("Looking up system property '"+propertyName+"'" ); 149 String r = ss.getSystemProperty(propertyName); 150 if(r!=null) { 151 debugPrintln("The value is '"+r+"'"); 152 sf = createInstance(r); 153 if(sf!=null) return sf; 154 } else 155 debugPrintln("The property is undefined."); 156 } catch( Throwable t ) { 157 if( debug ) { 158 debugPrintln("failed to look up system property '"+propertyName+"'" ); 159 t.printStackTrace(); 160 } 161 } 162 163 String javah = ss.getSystemProperty( "java.home" ); 164 String configFile = javah + File.separator + 165 "lib" + File.separator + "jaxp.properties"; 166 167 String factoryClassName = null ; 168 169 try { 171 if(firstTime){ 172 synchronized(cacheProps){ 173 if(firstTime){ 174 File f=new File ( configFile ); 175 firstTime = false; 176 if(ss.doesFileExist(f)){ 177 debugPrintln("Read properties file " + f); 178 cacheProps.load(ss.getFileInputStream(f)); 179 } 180 } 181 } 182 } 183 factoryClassName = cacheProps.getProperty(propertyName); 184 debugPrintln("found " + factoryClassName + " in $java.home/jaxp.properties"); 185 186 if (factoryClassName != null) { 187 sf = createInstance(factoryClassName); 188 if(sf != null){ 189 return sf; 190 } 191 } 192 } catch (Exception ex) { 193 if (debug) { 194 ex.printStackTrace(); 195 } 196 } 197 198 219 220 Iterator sitr = createServiceFileIterator(); 222 while(sitr.hasNext()) { 223 URL resource = (URL )sitr.next(); 224 debugPrintln("looking into " + resource); 225 try { 226 sf = loadFromProperty(schemaLanguage,resource.toExternalForm(),ss.getURLInputStream(resource)); 228 if(sf!=null) return sf; 229 } catch(IOException e) { 230 if( debug ) { 231 debugPrintln("failed to read "+resource); 232 e.printStackTrace(); 233 } 234 } 235 } 236 237 if(schemaLanguage.equals("http://www.w3.org/2001/XMLSchema")) { 239 debugPrintln("attempting to use the platform default XML Schema validator"); 240 return createInstance("com.sun.org.apache.xerces.internal.jaxp.validation.xs.SchemaFactoryImpl"); 241 } 242 243 debugPrintln("all things were tried, but none was found. bailing out."); 244 return null; 245 } 246 247 256 private SchemaFactory createInstance( String className ) { 257 try { 258 debugPrintln("instanciating "+className); 259 Class clazz; 260 if( classLoader!=null ) 261 clazz = classLoader.loadClass(className); 262 else 263 clazz = Class.forName(className); 264 if(debug) debugPrintln("loaded it from "+which(clazz)); 265 Object o = clazz.newInstance(); 266 267 if( o instanceof SchemaFactory ) 268 return (SchemaFactory )o; 269 270 debugPrintln(className+" is not assignable to "+SERVICE_CLASS.getName()); 271 } catch( Throwable t ) { 272 debugPrintln("failed to instanciate "+className); 273 if(debug) t.printStackTrace(); 274 } 275 return null; 276 } 277 278 279 private static abstract class SingleIterator implements Iterator { 280 private boolean seen = false; 281 282 public final void remove() { throw new UnsupportedOperationException (); } 283 public final boolean hasNext() { return !seen; } 284 public final Object next() { 285 if(seen) throw new NoSuchElementException (); 286 seen = true; 287 return value(); 288 } 289 290 protected abstract Object value(); 291 } 292 293 300 private SchemaFactory loadFromProperty( String keyName, String resourceName, InputStream in ) 301 throws IOException { 302 debugPrintln("Reading "+resourceName ); 303 304 Properties props=new Properties (); 305 props.load(in); 306 in.close(); 307 String factoryClassName = props.getProperty(keyName); 308 if(factoryClassName != null){ 309 debugPrintln("found "+keyName+" = " + factoryClassName); 310 return createInstance(factoryClassName); 311 } else { 312 debugPrintln(keyName+" is not in the property file"); 313 return null; 314 } 315 } 316 317 321 private Iterator createServiceFileIterator() { 322 if (classLoader == null) { 323 return new SingleIterator() { 324 protected Object value() { 325 ClassLoader classLoader = SchemaFactoryFinder .class.getClassLoader(); 326 return ss.getResourceAsURL(classLoader, SERVICE_ID); 328 } 329 }; 330 } else { 331 try { 332 final Enumeration e = ss.getResources(classLoader, SERVICE_ID); 334 if(!e.hasMoreElements()) { 335 debugPrintln("no "+SERVICE_ID+" file was found"); 336 } 337 338 return new Iterator () { 340 public void remove() { 341 throw new UnsupportedOperationException (); 342 } 343 344 public boolean hasNext() { 345 return e.hasMoreElements(); 346 } 347 348 public Object next() { 349 return e.nextElement(); 350 } 351 }; 352 } catch (IOException e) { 353 debugPrintln("failed to enumerate resources "+SERVICE_ID); 354 if(debug) e.printStackTrace(); 355 return new ArrayList ().iterator(); } 357 } 358 } 359 360 private static final Class SERVICE_CLASS = SchemaFactory .class; 361 private static final String SERVICE_ID = "META-INF/services/" + SERVICE_CLASS.getName(); 362 363 364 365 private static String which( Class clazz ) { 366 return which( clazz.getName(), clazz.getClassLoader() ); 367 } 368 369 377 private static String which(String classname, ClassLoader loader) { 378 379 String classnameAsResource = classname.replace('.', '/') + ".class"; 380 381 if( loader==null ) loader = ClassLoader.getSystemClassLoader(); 382 383 URL it = ss.getResourceAsURL(loader, classnameAsResource); 385 if (it != null) { 386 return it.toString(); 387 } else { 388 return null; 389 } 390 } 391 } 392 | Popular Tags |