1 16 17 package org.cyberneko.html; 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 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 try { 164 if(fLastModified >= 0) { 166 if(propertiesFileExists && 167 (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) { 168 loadProperties = true; 169 } else { 170 if(!propertiesFileExists) { 172 fLastModified = -1; 173 fXercesProperties = null; 174 } } 176 } else { 177 if(propertiesFileExists) { 179 loadProperties = true; 180 fLastModified = ss.getLastModified(propertiesFile); 181 } } 183 if(loadProperties) { 184 fXercesProperties = new Properties (); 186 FileInputStream fis = ss.getFileInputStream(propertiesFile); 187 fXercesProperties.load(fis); 188 fis.close(); 189 } 190 } catch (Exception x) { 191 fXercesProperties = null; 192 fLastModified = -1; 193 } 197 } 198 if(fXercesProperties != null) { 199 factoryClassName = fXercesProperties.getProperty(factoryId); 200 } 201 } else { 202 try { 203 FileInputStream fis = ss.getFileInputStream(new File (propertiesFilename)); 204 Properties props = new Properties (); 205 props.load(fis); 206 fis.close(); 207 factoryClassName = props.getProperty(factoryId); 208 } catch (Exception x) { 209 } 213 } 214 if (factoryClassName != null) { 215 if (DEBUG) debugPrintln("found in " + propertiesFilename + ", value=" + factoryClassName); 216 return newInstance(factoryClassName, cl, true); 217 } 218 219 Object provider = findJarServiceProvider(factoryId); 221 if (provider != null) { 222 return provider; 223 } 224 225 if (fallbackClassName == null) { 226 throw new ConfigurationError( 227 "Provider for " + factoryId + " cannot be found", null); 228 } 229 230 if (DEBUG) debugPrintln("using fallback, value=" + fallbackClassName); 231 return newInstance(fallbackClassName, cl, true); 232 } 234 238 239 private static void debugPrintln(String msg) { 240 if (DEBUG) { 241 System.err.println("JAXP: " + msg); 242 } 243 } 245 249 static ClassLoader findClassLoader() 250 throws ConfigurationError 251 { 252 SecuritySupport ss = SecuritySupport.getInstance(); 253 254 ClassLoader context = ss.getContextClassLoader(); 257 ClassLoader system = ss.getSystemClassLoader(); 258 259 ClassLoader chain = system; 260 while (true) { 261 if (context == chain) { 262 ClassLoader current = ObjectFactory.class.getClassLoader(); 271 272 chain = system; 273 while (true) { 274 if (current == chain) { 275 return system; 278 } 279 if (chain == null) { 280 break; 281 } 282 chain = ss.getParentClassLoader(chain); 283 } 284 285 return current; 288 } 289 290 if (chain == null) { 291 break; 293 } 294 295 chain = ss.getParentClassLoader(chain); 298 }; 299 300 return context; 303 } 305 308 static Object newInstance(String className, ClassLoader cl, 309 boolean doFallback) 310 throws ConfigurationError 311 { 312 try{ 314 Class providerClass = findProviderClass(className, cl, doFallback); 315 Object instance = providerClass.newInstance(); 316 if (DEBUG) debugPrintln("created new instance of " + providerClass + 317 " using ClassLoader: " + cl); 318 return instance; 319 } catch (ClassNotFoundException x) { 320 throw new ConfigurationError( 321 "Provider " + className + " not found", x); 322 } catch (Exception x) { 323 throw new ConfigurationError( 324 "Provider " + className + " could not be instantiated: " + x, 325 x); 326 } 327 } 328 329 332 static Class findProviderClass(String className, ClassLoader cl, 333 boolean doFallback) 334 throws ClassNotFoundException , ConfigurationError 335 { 336 SecurityManager security = System.getSecurityManager(); 339 try{ 340 if (security != null) { 341 final int lastDot = className.lastIndexOf("."); 342 String packageName = className; 343 if (lastDot != -1) packageName = className.substring(0, lastDot); 344 security.checkPackageAccess(packageName); 345 } 346 }catch(SecurityException e){ 347 throw e ; 348 } 349 Class providerClass; 350 if (cl == null) { 351 providerClass = Class.forName(className); 361 } else { 362 try { 363 providerClass = cl.loadClass(className); 364 } catch (ClassNotFoundException x) { 365 if (doFallback) { 366 ClassLoader current = ObjectFactory.class.getClassLoader(); 368 if (current == null) { 369 providerClass = Class.forName(className); 370 } else if (cl != current) { 371 cl = current; 372 providerClass = cl.loadClass(className); 373 } else { 374 throw x; 375 } 376 } else { 377 throw x; 378 } 379 } 380 } 381 382 return providerClass; 383 } 384 385 390 private static Object findJarServiceProvider(String factoryId) 391 throws ConfigurationError 392 { 393 SecuritySupport ss = SecuritySupport.getInstance(); 394 String serviceId = "META-INF/services/" + factoryId; 395 InputStream is = null; 396 397 ClassLoader cl = findClassLoader(); 399 400 is = ss.getResourceAsStream(cl, serviceId); 401 402 if (is == null) { 404 ClassLoader current = ObjectFactory.class.getClassLoader(); 405 if (cl != current) { 406 cl = current; 407 is = ss.getResourceAsStream(cl, serviceId); 408 } 409 } 410 411 if (is == null) { 412 return null; 414 } 415 416 if (DEBUG) debugPrintln("found jar resource=" + serviceId + 417 " using ClassLoader: " + cl); 418 419 BufferedReader rd; 436 try { 437 rd = new BufferedReader (new InputStreamReader (is, "UTF-8"), DEFAULT_LINE_LENGTH); 438 } catch (java.io.UnsupportedEncodingException e) { 439 rd = new BufferedReader (new InputStreamReader (is), DEFAULT_LINE_LENGTH); 440 } 441 442 String factoryClassName = null; 443 try { 444 factoryClassName = rd.readLine(); 447 rd.close(); 448 } catch (IOException x) { 449 return null; 451 } 452 453 if (factoryClassName != null && 454 ! "".equals(factoryClassName)) { 455 if (DEBUG) debugPrintln("found in resource, value=" 456 + factoryClassName); 457 458 return newInstance(factoryClassName, cl, false); 463 } 464 465 return null; 467 } 468 469 473 476 static class ConfigurationError 477 extends Error { 478 479 483 484 private Exception exception; 485 486 490 494 ConfigurationError(String msg, Exception x) { 495 super(msg); 496 this.exception = x; 497 } 499 503 504 Exception getException() { 505 return exception; 506 } 508 } 510 } | Popular Tags |