1 16 17 package org.apache.xerces.impl.dv; 18 19 import java.io.InputStream ; 20 import java.io.IOException ; 21 import java.io.File ; 22 import java.io.FileInputStream ; 23 24 import java.util.Properties ; 25 import java.io.BufferedReader ; 26 import java.io.InputStreamReader ; 27 28 44 final class ObjectFactory { 45 46 50 private static final String DEFAULT_PROPERTIES_FILENAME = "xerces.properties"; 52 53 54 private static final boolean DEBUG = false; 55 56 59 private static final int DEFAULT_LINE_LENGTH = 80; 60 61 66 private static Properties fXercesProperties = null; 67 68 73 private static long fLastModified = -1; 74 75 79 97 static Object createObject(String factoryId, String fallbackClassName) 98 throws ConfigurationError { 99 return createObject(factoryId, null, fallbackClassName); 100 } 102 124 static Object createObject(String factoryId, 125 String propertiesFilename, 126 String fallbackClassName) 127 throws ConfigurationError 128 { 129 if (DEBUG) debugPrintln("debug is on"); 130 131 SecuritySupport ss = SecuritySupport.getInstance(); 132 ClassLoader cl = findClassLoader(); 133 134 try { 136 String systemProp = ss.getSystemProperty(factoryId); 137 if (systemProp != null) { 138 if (DEBUG) debugPrintln("found system property, value=" + systemProp); 139 return newInstance(systemProp, cl, true); 140 } 141 } catch (SecurityException se) { 142 } 144 145 String factoryClassName = null; 147 if (propertiesFilename == null) { 149 File propertiesFile = null; 150 boolean propertiesFileExists = false; 151 try { 152 String javah = ss.getSystemProperty("java.home"); 153 propertiesFilename = javah + File.separator + 154 "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME; 155 propertiesFile = new File (propertiesFilename); 156 propertiesFileExists = ss.getFileExists(propertiesFile); 157 } catch (SecurityException e) { 158 fLastModified = -1; 160 fXercesProperties = null; 161 } 162 163 synchronized (ObjectFactory.class) { 164 boolean loadProperties = false; 165 FileInputStream fis = null; 166 try { 167 if(fLastModified >= 0) { 169 if(propertiesFileExists && 170 (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) { 171 loadProperties = true; 172 } else { 173 if(!propertiesFileExists) { 175 fLastModified = -1; 176 fXercesProperties = null; 177 } } 179 } else { 180 if(propertiesFileExists) { 182 loadProperties = true; 183 fLastModified = ss.getLastModified(propertiesFile); 184 } } 186 if(loadProperties) { 187 fXercesProperties = new Properties (); 189 fis = ss.getFileInputStream(propertiesFile); 190 fXercesProperties.load(fis); 191 } 192 } catch (Exception x) { 193 fXercesProperties = null; 194 fLastModified = -1; 195 } 199 finally { 200 if (fis != null) { 202 try { 203 fis.close(); 204 } 205 catch (IOException exc) {} 207 } 208 } 209 } 210 if(fXercesProperties != null) { 211 factoryClassName = fXercesProperties.getProperty(factoryId); 212 } 213 } else { 214 FileInputStream fis = null; 215 try { 216 fis = ss.getFileInputStream(new File (propertiesFilename)); 217 Properties props = new Properties (); 218 props.load(fis); 219 factoryClassName = props.getProperty(factoryId); 220 } catch (Exception x) { 221 } 225 finally { 226 if (fis != null) { 228 try { 229 fis.close(); 230 } 231 catch (IOException exc) {} 233 } 234 } 235 } 236 if (factoryClassName != null) { 237 if (DEBUG) debugPrintln("found in " + propertiesFilename + ", value=" + factoryClassName); 238 return newInstance(factoryClassName, cl, true); 239 } 240 241 Object provider = findJarServiceProvider(factoryId); 243 if (provider != null) { 244 return provider; 245 } 246 247 if (fallbackClassName == null) { 248 throw new ConfigurationError( 249 "Provider for " + factoryId + " cannot be found", null); 250 } 251 252 if (DEBUG) debugPrintln("using fallback, value=" + fallbackClassName); 253 return newInstance(fallbackClassName, cl, true); 254 } 256 260 261 private static void debugPrintln(String msg) { 262 if (DEBUG) { 263 System.err.println("JAXP: " + msg); 264 } 265 } 267 271 static ClassLoader findClassLoader() 272 throws ConfigurationError 273 { 274 SecuritySupport ss = SecuritySupport.getInstance(); 275 276 ClassLoader context = ss.getContextClassLoader(); 279 ClassLoader system = ss.getSystemClassLoader(); 280 281 ClassLoader chain = system; 282 while (true) { 283 if (context == chain) { 284 ClassLoader current = ObjectFactory.class.getClassLoader(); 293 294 chain = system; 295 while (true) { 296 if (current == chain) { 297 return system; 300 } 301 if (chain == null) { 302 break; 303 } 304 chain = ss.getParentClassLoader(chain); 305 } 306 307 return current; 310 } 311 312 if (chain == null) { 313 break; 315 } 316 317 chain = ss.getParentClassLoader(chain); 320 }; 321 322 return context; 325 } 327 330 static Object newInstance(String className, ClassLoader cl, 331 boolean doFallback) 332 throws ConfigurationError 333 { 334 try{ 336 Class providerClass = findProviderClass(className, cl, doFallback); 337 Object instance = providerClass.newInstance(); 338 if (DEBUG) debugPrintln("created new instance of " + providerClass + 339 " using ClassLoader: " + cl); 340 return instance; 341 } catch (ClassNotFoundException x) { 342 throw new ConfigurationError( 343 "Provider " + className + " not found", x); 344 } catch (Exception x) { 345 throw new ConfigurationError( 346 "Provider " + className + " could not be instantiated: " + x, 347 x); 348 } 349 } 350 351 354 static Class findProviderClass(String className, ClassLoader cl, 355 boolean doFallback) 356 throws ClassNotFoundException , ConfigurationError 357 { 358 SecurityManager security = System.getSecurityManager(); 361 if (security != null) { 362 final int lastDot = className.lastIndexOf("."); 363 String packageName = className; 364 if (lastDot != -1) packageName = className.substring(0, lastDot); 365 security.checkPackageAccess(packageName); 366 } 367 Class providerClass; 368 if (cl == null) { 369 providerClass = Class.forName(className); 379 } else { 380 try { 381 providerClass = cl.loadClass(className); 382 } catch (ClassNotFoundException x) { 383 if (doFallback) { 384 ClassLoader current = ObjectFactory.class.getClassLoader(); 386 if (current == null) { 387 providerClass = Class.forName(className); 388 } else if (cl != current) { 389 cl = current; 390 providerClass = cl.loadClass(className); 391 } else { 392 throw x; 393 } 394 } else { 395 throw x; 396 } 397 } 398 } 399 400 return providerClass; 401 } 402 403 408 private static Object findJarServiceProvider(String factoryId) 409 throws ConfigurationError 410 { 411 SecuritySupport ss = SecuritySupport.getInstance(); 412 String serviceId = "META-INF/services/" + factoryId; 413 InputStream is = null; 414 415 ClassLoader cl = findClassLoader(); 417 418 is = ss.getResourceAsStream(cl, serviceId); 419 420 if (is == null) { 422 ClassLoader current = ObjectFactory.class.getClassLoader(); 423 if (cl != current) { 424 cl = current; 425 is = ss.getResourceAsStream(cl, serviceId); 426 } 427 } 428 429 if (is == null) { 430 return null; 432 } 433 434 if (DEBUG) debugPrintln("found jar resource=" + serviceId + 435 " using ClassLoader: " + cl); 436 437 BufferedReader rd; 454 try { 455 rd = new BufferedReader (new InputStreamReader (is, "UTF-8"), DEFAULT_LINE_LENGTH); 456 } catch (java.io.UnsupportedEncodingException e) { 457 rd = new BufferedReader (new InputStreamReader (is), DEFAULT_LINE_LENGTH); 458 } 459 460 String factoryClassName = null; 461 try { 462 factoryClassName = rd.readLine(); 465 } catch (IOException x) { 466 return null; 468 } 469 finally { 470 try { 471 rd.close(); 473 } 474 catch (IOException exc) {} 476 } 477 478 if (factoryClassName != null && 479 ! "".equals(factoryClassName)) { 480 if (DEBUG) debugPrintln("found in resource, value=" 481 + factoryClassName); 482 483 return newInstance(factoryClassName, cl, false); 488 } 489 490 return null; 492 } 493 494 498 501 static final class ConfigurationError 502 extends Error { 503 504 505 static final long serialVersionUID = 8521878292694272124L; 506 507 511 512 private Exception exception; 513 514 518 522 ConfigurationError(String msg, Exception x) { 523 super(msg); 524 this.exception = x; 525 } 527 531 532 Exception getException() { 533 return exception; 534 } 536 } 538 } | Popular Tags |