1 16 17 package org.apache.xerces.parsers; 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 42 final class ObjectFactory { 43 44 48 private static final String DEFAULT_PROPERTIES_FILENAME = "xerces.properties"; 50 51 52 private static final boolean DEBUG = false; 53 54 57 private static final int DEFAULT_LINE_LENGTH = 80; 58 59 64 private static Properties fXercesProperties = null; 65 66 71 private static long fLastModified = -1; 72 73 77 95 static Object createObject(String factoryId, String fallbackClassName) 96 throws ConfigurationError { 97 return createObject(factoryId, null, fallbackClassName); 98 } 100 122 static Object createObject(String factoryId, 123 String propertiesFilename, 124 String fallbackClassName) 125 throws ConfigurationError 126 { 127 if (DEBUG) debugPrintln("debug is on"); 128 129 SecuritySupport ss = SecuritySupport.getInstance(); 130 ClassLoader cl = findClassLoader(); 131 132 try { 134 String systemProp = ss.getSystemProperty(factoryId); 135 if (systemProp != null) { 136 if (DEBUG) debugPrintln("found system property, value=" + systemProp); 137 return newInstance(systemProp, cl, true); 138 } 139 } catch (SecurityException se) { 140 } 142 143 String factoryClassName = null; 145 if (propertiesFilename == null) { 147 File propertiesFile = null; 148 boolean propertiesFileExists = false; 149 try { 150 String javah = ss.getSystemProperty("java.home"); 151 propertiesFilename = javah + File.separator + 152 "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME; 153 propertiesFile = new File (propertiesFilename); 154 propertiesFileExists = ss.getFileExists(propertiesFile); 155 } catch (SecurityException e) { 156 fLastModified = -1; 158 fXercesProperties = null; 159 } 160 161 synchronized (ObjectFactory.class) { 162 boolean loadProperties = false; 163 FileInputStream fis = null; 164 try { 165 if(fLastModified >= 0) { 167 if(propertiesFileExists && 168 (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) { 169 loadProperties = true; 170 } else { 171 if(!propertiesFileExists) { 173 fLastModified = -1; 174 fXercesProperties = null; 175 } } 177 } else { 178 if(propertiesFileExists) { 180 loadProperties = true; 181 fLastModified = ss.getLastModified(propertiesFile); 182 } } 184 if(loadProperties) { 185 fXercesProperties = new Properties (); 187 fis = ss.getFileInputStream(propertiesFile); 188 fXercesProperties.load(fis); 189 } 190 } catch (Exception x) { 191 fXercesProperties = null; 192 fLastModified = -1; 193 } 197 finally { 198 if (fis != null) { 200 try { 201 fis.close(); 202 } 203 catch (IOException exc) {} 205 } 206 } 207 } 208 if(fXercesProperties != null) { 209 factoryClassName = fXercesProperties.getProperty(factoryId); 210 } 211 } else { 212 FileInputStream fis = null; 213 try { 214 fis = ss.getFileInputStream(new File (propertiesFilename)); 215 Properties props = new Properties (); 216 props.load(fis); 217 factoryClassName = props.getProperty(factoryId); 218 } catch (Exception x) { 219 } 223 finally { 224 if (fis != null) { 226 try { 227 fis.close(); 228 } 229 catch (IOException exc) {} 231 } 232 } 233 } 234 if (factoryClassName != null) { 235 if (DEBUG) debugPrintln("found in " + propertiesFilename + ", value=" + factoryClassName); 236 return newInstance(factoryClassName, cl, true); 237 } 238 239 Object provider = findJarServiceProvider(factoryId); 241 if (provider != null) { 242 return provider; 243 } 244 245 if (fallbackClassName == null) { 246 throw new ConfigurationError( 247 "Provider for " + factoryId + " cannot be found", null); 248 } 249 250 if (DEBUG) debugPrintln("using fallback, value=" + fallbackClassName); 251 return newInstance(fallbackClassName, cl, true); 252 } 254 258 259 private static void debugPrintln(String msg) { 260 if (DEBUG) { 261 System.err.println("JAXP: " + msg); 262 } 263 } 265 269 static ClassLoader findClassLoader() 270 throws ConfigurationError 271 { 272 SecuritySupport ss = SecuritySupport.getInstance(); 273 274 ClassLoader context = ss.getContextClassLoader(); 277 ClassLoader system = ss.getSystemClassLoader(); 278 279 ClassLoader chain = system; 280 while (true) { 281 if (context == chain) { 282 ClassLoader current = ObjectFactory.class.getClassLoader(); 291 292 chain = system; 293 while (true) { 294 if (current == chain) { 295 return system; 298 } 299 if (chain == null) { 300 break; 301 } 302 chain = ss.getParentClassLoader(chain); 303 } 304 305 return current; 308 } 309 310 if (chain == null) { 311 break; 313 } 314 315 chain = ss.getParentClassLoader(chain); 318 }; 319 320 return context; 323 } 325 328 static Object newInstance(String className, ClassLoader cl, 329 boolean doFallback) 330 throws ConfigurationError 331 { 332 try{ 334 Class providerClass = findProviderClass(className, cl, doFallback); 335 Object instance = providerClass.newInstance(); 336 if (DEBUG) debugPrintln("created new instance of " + providerClass + 337 " using ClassLoader: " + cl); 338 return instance; 339 } catch (ClassNotFoundException x) { 340 throw new ConfigurationError( 341 "Provider " + className + " not found", x); 342 } catch (Exception x) { 343 throw new ConfigurationError( 344 "Provider " + className + " could not be instantiated: " + x, 345 x); 346 } 347 } 348 349 352 static Class findProviderClass(String className, ClassLoader cl, 353 boolean doFallback) 354 throws ClassNotFoundException , ConfigurationError 355 { 356 SecurityManager security = System.getSecurityManager(); 359 if (security != null) { 360 final int lastDot = className.lastIndexOf("."); 361 String packageName = className; 362 if (lastDot != -1) packageName = className.substring(0, lastDot); 363 security.checkPackageAccess(packageName); 364 } 365 Class providerClass; 366 if (cl == null) { 367 providerClass = Class.forName(className); 377 } else { 378 try { 379 providerClass = cl.loadClass(className); 380 } catch (ClassNotFoundException x) { 381 if (doFallback) { 382 ClassLoader current = ObjectFactory.class.getClassLoader(); 384 if (current == null) { 385 providerClass = Class.forName(className); 386 } else if (cl != current) { 387 cl = current; 388 providerClass = cl.loadClass(className); 389 } else { 390 throw x; 391 } 392 } else { 393 throw x; 394 } 395 } 396 } 397 398 return providerClass; 399 } 400 401 406 private static Object findJarServiceProvider(String factoryId) 407 throws ConfigurationError 408 { 409 SecuritySupport ss = SecuritySupport.getInstance(); 410 String serviceId = "META-INF/services/" + factoryId; 411 InputStream is = null; 412 413 ClassLoader cl = findClassLoader(); 415 416 is = ss.getResourceAsStream(cl, serviceId); 417 418 if (is == null) { 420 ClassLoader current = ObjectFactory.class.getClassLoader(); 421 if (cl != current) { 422 cl = current; 423 is = ss.getResourceAsStream(cl, serviceId); 424 } 425 } 426 427 if (is == null) { 428 return null; 430 } 431 432 if (DEBUG) debugPrintln("found jar resource=" + serviceId + 433 " using ClassLoader: " + cl); 434 435 BufferedReader rd; 452 try { 453 rd = new BufferedReader (new InputStreamReader (is, "UTF-8"), DEFAULT_LINE_LENGTH); 454 } catch (java.io.UnsupportedEncodingException e) { 455 rd = new BufferedReader (new InputStreamReader (is), DEFAULT_LINE_LENGTH); 456 } 457 458 String factoryClassName = null; 459 try { 460 factoryClassName = rd.readLine(); 463 } catch (IOException x) { 464 return null; 466 } 467 finally { 468 try { 469 rd.close(); 471 } 472 catch (IOException exc) {} 474 } 475 476 if (factoryClassName != null && 477 ! "".equals(factoryClassName)) { 478 if (DEBUG) debugPrintln("found in resource, value=" 479 + factoryClassName); 480 481 return newInstance(factoryClassName, cl, false); 486 } 487 488 return null; 490 } 491 492 496 499 static final class ConfigurationError 500 extends Error { 501 502 503 static final long serialVersionUID = -7285495612271660427L; 504 505 509 510 private Exception exception; 511 512 516 520 ConfigurationError(String msg, Exception x) { 521 super(msg); 522 this.exception = x; 523 } 525 529 530 Exception getException() { 531 return exception; 532 } 534 } 536 } | Popular Tags |