1 16 17 package xni; 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 45 final class ObjectFactory { 46 47 51 private static final String DEFAULT_PROPERTIES_FILENAME = "xerces.properties"; 53 54 55 private static final boolean DEBUG = false; 56 57 60 private static final int DEFAULT_LINE_LENGTH = 80; 61 62 67 private static Properties fXercesProperties = null; 68 69 74 private static long fLastModified = -1; 75 76 80 98 static Object createObject(String factoryId, String fallbackClassName) 99 throws ConfigurationError { 100 return createObject(factoryId, null, fallbackClassName); 101 } 103 125 static Object createObject(String factoryId, 126 String propertiesFilename, 127 String fallbackClassName) 128 throws ConfigurationError 129 { 130 if (DEBUG) debugPrintln("debug is on"); 131 132 SecuritySupport ss = SecuritySupport.getInstance(); 133 ClassLoader cl = findClassLoader(); 134 135 try { 137 String systemProp = ss.getSystemProperty(factoryId); 138 if (systemProp != null) { 139 if (DEBUG) debugPrintln("found system property, value=" + systemProp); 140 return newInstance(systemProp, cl, true); 141 } 142 } catch (SecurityException se) { 143 } 145 146 String factoryClassName = null; 148 if (propertiesFilename == null) { 150 File propertiesFile = null; 151 boolean propertiesFileExists = false; 152 try { 153 String javah = ss.getSystemProperty("java.home"); 154 propertiesFilename = javah + File.separator + 155 "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME; 156 propertiesFile = new File (propertiesFilename); 157 propertiesFileExists = ss.getFileExists(propertiesFile); 158 } catch (SecurityException e) { 159 fLastModified = -1; 161 fXercesProperties = null; 162 } 163 164 synchronized (ObjectFactory.class) { 165 boolean loadProperties = false; 166 FileInputStream fis = null; 167 try { 168 if(fLastModified >= 0) { 170 if(propertiesFileExists && 171 (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) { 172 loadProperties = true; 173 } else { 174 if(!propertiesFileExists) { 176 fLastModified = -1; 177 fXercesProperties = null; 178 } } 180 } else { 181 if(propertiesFileExists) { 183 loadProperties = true; 184 fLastModified = ss.getLastModified(propertiesFile); 185 } } 187 if(loadProperties) { 188 fXercesProperties = new Properties (); 190 fis = ss.getFileInputStream(propertiesFile); 191 fXercesProperties.load(fis); 192 } 193 } catch (Exception x) { 194 fXercesProperties = null; 195 fLastModified = -1; 196 } 200 finally { 201 if (fis != null) { 203 try { 204 fis.close(); 205 } 206 catch (IOException exc) {} 208 } 209 } 210 } 211 if(fXercesProperties != null) { 212 factoryClassName = fXercesProperties.getProperty(factoryId); 213 } 214 } else { 215 FileInputStream fis = null; 216 try { 217 fis = ss.getFileInputStream(new File (propertiesFilename)); 218 Properties props = new Properties (); 219 props.load(fis); 220 factoryClassName = props.getProperty(factoryId); 221 } catch (Exception x) { 222 } 226 finally { 227 if (fis != null) { 229 try { 230 fis.close(); 231 } 232 catch (IOException exc) {} 234 } 235 } 236 } 237 if (factoryClassName != null) { 238 if (DEBUG) debugPrintln("found in " + propertiesFilename + ", value=" + factoryClassName); 239 return newInstance(factoryClassName, cl, true); 240 } 241 242 Object provider = findJarServiceProvider(factoryId); 244 if (provider != null) { 245 return provider; 246 } 247 248 if (fallbackClassName == null) { 249 throw new ConfigurationError( 250 "Provider for " + factoryId + " cannot be found", null); 251 } 252 253 if (DEBUG) debugPrintln("using fallback, value=" + fallbackClassName); 254 return newInstance(fallbackClassName, cl, true); 255 } 257 261 262 private static void debugPrintln(String msg) { 263 if (DEBUG) { 264 System.err.println("JAXP: " + msg); 265 } 266 } 268 272 static ClassLoader findClassLoader() 273 throws ConfigurationError 274 { 275 SecuritySupport ss = SecuritySupport.getInstance(); 276 277 ClassLoader context = ss.getContextClassLoader(); 280 ClassLoader system = ss.getSystemClassLoader(); 281 282 ClassLoader chain = system; 283 while (true) { 284 if (context == chain) { 285 ClassLoader current = ObjectFactory.class.getClassLoader(); 294 295 chain = system; 296 while (true) { 297 if (current == chain) { 298 return system; 301 } 302 if (chain == null) { 303 break; 304 } 305 chain = ss.getParentClassLoader(chain); 306 } 307 308 return current; 311 } 312 313 if (chain == null) { 314 break; 316 } 317 318 chain = ss.getParentClassLoader(chain); 321 }; 322 323 return context; 326 } 328 331 static Object newInstance(String className, ClassLoader cl, 332 boolean doFallback) 333 throws ConfigurationError 334 { 335 try{ 337 Class providerClass = findProviderClass(className, cl, doFallback); 338 Object instance = providerClass.newInstance(); 339 if (DEBUG) debugPrintln("created new instance of " + providerClass + 340 " using ClassLoader: " + cl); 341 return instance; 342 } catch (ClassNotFoundException x) { 343 throw new ConfigurationError( 344 "Provider " + className + " not found", x); 345 } catch (Exception x) { 346 throw new ConfigurationError( 347 "Provider " + className + " could not be instantiated: " + x, 348 x); 349 } 350 } 351 352 355 static Class findProviderClass(String className, ClassLoader cl, 356 boolean doFallback) 357 throws ClassNotFoundException , ConfigurationError 358 { 359 SecurityManager security = System.getSecurityManager(); 362 if (security != null) { 363 final int lastDot = className.lastIndexOf("."); 364 String packageName = className; 365 if (lastDot != -1) packageName = className.substring(0, lastDot); 366 security.checkPackageAccess(packageName); 367 } 368 Class providerClass; 369 if (cl == null) { 370 providerClass = Class.forName(className); 380 } else { 381 try { 382 providerClass = cl.loadClass(className); 383 } catch (ClassNotFoundException x) { 384 if (doFallback) { 385 ClassLoader current = ObjectFactory.class.getClassLoader(); 387 if (current == null) { 388 providerClass = Class.forName(className); 389 } else if (cl != current) { 390 cl = current; 391 providerClass = cl.loadClass(className); 392 } else { 393 throw x; 394 } 395 } else { 396 throw x; 397 } 398 } 399 } 400 401 return providerClass; 402 } 403 404 409 private static Object findJarServiceProvider(String factoryId) 410 throws ConfigurationError 411 { 412 SecuritySupport ss = SecuritySupport.getInstance(); 413 String serviceId = "META-INF/services/" + factoryId; 414 InputStream is = null; 415 416 ClassLoader cl = findClassLoader(); 418 419 is = ss.getResourceAsStream(cl, serviceId); 420 421 if (is == null) { 423 ClassLoader current = ObjectFactory.class.getClassLoader(); 424 if (cl != current) { 425 cl = current; 426 is = ss.getResourceAsStream(cl, serviceId); 427 } 428 } 429 430 if (is == null) { 431 return null; 433 } 434 435 if (DEBUG) debugPrintln("found jar resource=" + serviceId + 436 " using ClassLoader: " + cl); 437 438 BufferedReader rd; 455 try { 456 rd = new BufferedReader (new InputStreamReader (is, "UTF-8"), DEFAULT_LINE_LENGTH); 457 } catch (java.io.UnsupportedEncodingException e) { 458 rd = new BufferedReader (new InputStreamReader (is), DEFAULT_LINE_LENGTH); 459 } 460 461 String factoryClassName = null; 462 try { 463 factoryClassName = rd.readLine(); 466 } catch (IOException x) { 467 return null; 469 } 470 finally { 471 try { 472 rd.close(); 474 } 475 catch (IOException exc) {} 477 } 478 479 if (factoryClassName != null && 480 ! "".equals(factoryClassName)) { 481 if (DEBUG) debugPrintln("found in resource, value=" 482 + factoryClassName); 483 484 return newInstance(factoryClassName, cl, false); 489 } 490 491 return null; 493 } 494 495 499 502 static final class ConfigurationError 503 extends Error { 504 505 506 private static final long serialVersionUID = 3689636882459932976L; 507 508 512 513 private Exception exception; 514 515 519 523 ConfigurationError(String msg, Exception x) { 524 super(msg); 525 this.exception = x; 526 } 528 532 533 Exception getException() { 534 return exception; 535 } 537 } 539 } | Popular Tags |