src/com/sun/org/apache/xalan/internal/utils/ObjectFactory.java

Print this page




   6  * Copyright 2001-2004 The Apache Software Foundation.
   7  *
   8  * Licensed under the Apache License, Version 2.0 (the "License");
   9  * you may not use this file except in compliance with the License.
  10  * You may obtain a copy of the License at
  11  *
  12  *     http://www.apache.org/licenses/LICENSE-2.0
  13  *
  14  * Unless required by applicable law or agreed to in writing, software
  15  * distributed under the License is distributed on an "AS IS" BASIS,
  16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17  * See the License for the specific language governing permissions and
  18  * limitations under the License.
  19  */
  20 /*
  21  * $Id: ObjectFactory.java,v 1.2.4.1 2005/09/15 02:39:54 jeffsuttor Exp $
  22  */
  23 
  24 package com.sun.org.apache.xalan.internal.utils;
  25 
  26 import java.io.InputStream;
  27 import java.io.IOException;
  28 import java.io.File;
  29 import java.io.FileInputStream;
  30 
  31 import java.util.Properties;
  32 import java.io.BufferedReader;
  33 import java.io.InputStreamReader;
  34 
  35 /**
  36  * This class is duplicated for each JAXP subpackage so keep it in sync.
  37  * It is package private and therefore is not exposed as part of the JAXP
  38  * API.
  39  * <p>
  40  * This code is designed to implement the JAXP 1.1 spec pluggability
  41  * feature and is designed to run on JDK version 1.1 and
  42  * later, and to compile on JDK 1.2 and onward.
  43  * The code also runs both as part of an unbundled jar file and
  44  * when bundled as part of the JDK.
  45  * <p>
  46  * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
  47  * class and modified to be used as a general utility for creating objects
  48  * dynamically.
  49  *
  50  * @version $Id: ObjectFactory.java,v 1.11 2010-11-01 04:34:25 joehw Exp $
  51  */
  52 public class ObjectFactory {
  53 
  54     //
  55     // Constants
  56     //
  57      private static final String XALAN_INTERNAL = "com.sun.org.apache.xalan.internal";
  58      private static final String XERCES_INTERNAL = "com.sun.org.apache.xerces.internal";
  59 
  60     // name of default properties file to look for in JDK's jre/lib directory
  61     private static final String DEFAULT_PROPERTIES_FILENAME =
  62                                                      "xalan.properties";
  63 
  64     private static final String SERVICES_PATH = "META-INF/services/";
  65 
  66     /** Set to true for debugging */
  67     private static final boolean DEBUG = false;
  68 
  69     /** cache the contents of the xalan.properties file.
  70      *  Until an attempt has been made to read this file, this will
  71      * be null; if the file does not exist or we encounter some other error
  72      * during the read, this will be empty.
  73      */
  74     private static Properties fXalanProperties = null;
  75 
  76     /***
  77      * Cache the time stamp of the xalan.properties file so
  78      * that we know if it's been modified and can invalidate
  79      * the cache when necessary.
  80      */
  81     private static long fLastModified = -1;
  82 
  83     //
  84     // Public static methods
  85     //
  86 
  87     /**
  88      * Finds the implementation Class object in the specified order.  The
  89      * specified order is the following:
  90      * <ol>
  91      *  <li>query the system property using <code>System.getProperty</code>
  92      *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
  93      *  <li>use fallback classname
  94      * </ol>
  95      *
  96      * @return instance of factory, never null
  97      *
  98      * @param factoryId             Name of the factory to find, same as
  99      *                              a property name
 100      * @param fallbackClassName     Implementation class name, if nothing else
 101      *                              is found.  Use null to mean no fallback.
 102      *
 103      * @exception ObjectFactory.ConfigurationError
 104      */
 105     public static Object createObject(String factoryId, String fallbackClassName)
 106         throws ConfigurationError {
 107         return createObject(factoryId, null, fallbackClassName);
 108     } // createObject(String,String):Object
 109 
 110     /**
 111      * Finds the implementation Class object in the specified order.  The
 112      * specified order is the following:
 113      * <ol>
 114      *  <li>query the system property using <code>System.getProperty</code>
 115      *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
 116      *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
 117      *  <li>use fallback classname
 118      * </ol>
 119      *
 120      * @return instance of factory, never null
 121      *
 122      * @param factoryId             Name of the factory to find, same as
 123      *                              a property name
 124      * @param propertiesFilename The filename in the $java.home/lib directory
 125      *                           of the properties file.  If none specified,
 126      *                           ${java.home}/lib/xalan.properties will be used.
 127      * @param fallbackClassName     Implementation class name, if nothing else
 128      *                              is found.  Use null to mean no fallback.
 129      *
 130      * @exception ObjectFactory.ConfigurationError
 131      */
 132     static Object createObject(String factoryId,
 133                                       String propertiesFilename,
 134                                       String fallbackClassName)
 135         throws ConfigurationError
 136     {
 137         Class factoryClass = lookUpFactoryClass(factoryId,
 138                                                 propertiesFilename,
 139                                                 fallbackClassName);
 140 
 141         if (factoryClass == null) {
 142             throw new ConfigurationError(
 143                 "Provider for " + factoryId + " cannot be found", null);
 144         }
 145 
 146         try{
 147             Object instance = factoryClass.newInstance();
 148             if (DEBUG) debugPrintln("created new instance of factory " + factoryId);
 149             return instance;
 150         } catch (Exception x) {
 151             throw new ConfigurationError(
 152                 "Provider for factory " + factoryId
 153                     + " could not be instantiated: " + x, x);
 154         }
 155     } // createObject(String,String,String):Object
 156 
 157     /**
 158      * Finds the implementation Class object in the specified order.  The
 159      * specified order is the following:
 160      * <ol>
 161      *  <li>query the system property using <code>System.getProperty</code>
 162      *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
 163      *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
 164      *  <li>use fallback classname
 165      * </ol>
 166      *
 167      * @return Class object of factory, never null
 168      *
 169      * @param factoryId             Name of the factory to find, same as
 170      *                              a property name
 171      * @param propertiesFilename The filename in the $java.home/lib directory
 172      *                           of the properties file.  If none specified,
 173      *                           ${java.home}/lib/xalan.properties will be used.
 174      * @param fallbackClassName     Implementation class name, if nothing else
 175      *                              is found.  Use null to mean no fallback.
 176      *
 177      * @exception ObjectFactory.ConfigurationError
 178      */
 179     public static Class lookUpFactoryClass(String factoryId)
 180         throws ConfigurationError
 181     {
 182         return lookUpFactoryClass(factoryId, null, null);
 183     } // lookUpFactoryClass(String):Class
 184 
 185     /**
 186      * Finds the implementation Class object in the specified order.  The
 187      * specified order is the following:
 188      * <ol>
 189      *  <li>query the system property using <code>System.getProperty</code>
 190      *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
 191      *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
 192      *  <li>use fallback classname
 193      * </ol>
 194      *
 195      * @return Class object that provides factory service, never null
 196      *
 197      * @param factoryId             Name of the factory to find, same as
 198      *                              a property name
 199      * @param propertiesFilename The filename in the $java.home/lib directory
 200      *                           of the properties file.  If none specified,
 201      *                           ${java.home}/lib/xalan.properties will be used.
 202      * @param fallbackClassName     Implementation class name, if nothing else
 203      *                              is found.  Use null to mean no fallback.
 204      *
 205      * @exception ObjectFactory.ConfigurationError
 206      */
 207     public static Class lookUpFactoryClass(String factoryId,
 208                                            String propertiesFilename,
 209                                            String fallbackClassName)
 210         throws ConfigurationError
 211     {
 212         String factoryClassName = lookUpFactoryClassName(factoryId,
 213                                                          propertiesFilename,
 214                                                          fallbackClassName);
 215         ClassLoader cl = findClassLoader();
 216 
 217         if (factoryClassName == null) {
 218             factoryClassName = fallbackClassName;
 219         }
 220 
 221         // assert(className != null);
 222         try{
 223             Class providerClass = findProviderClass(factoryClassName,
 224                                                     cl,
 225                                                     true);
 226             if (DEBUG) debugPrintln("created new instance of " + providerClass +
 227                    " using ClassLoader: " + cl);
 228             return providerClass;
 229         } catch (ClassNotFoundException x) {
 230             throw new ConfigurationError(
 231                 "Provider " + factoryClassName + " not found", x);
 232         } catch (Exception x) {
 233             throw new ConfigurationError(
 234                 "Provider "+factoryClassName+" could not be instantiated: "+x,
 235                 x);
 236         }
 237     } // lookUpFactoryClass(String,String,String):Class
 238 
 239     /**
 240      * Finds the name of the required implementation class in the specified
 241      * order.  The specified order is the following:
 242      * <ol>
 243      *  <li>query the system property using <code>System.getProperty</code>
 244      *  <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file
 245      *  <li>read <code>META-INF/services/<i>factoryId</i></code> file
 246      *  <li>use fallback classname
 247      * </ol>
 248      *
 249      * @return name of class that provides factory service, never null
 250      *
 251      * @param factoryId             Name of the factory to find, same as
 252      *                              a property name
 253      * @param propertiesFilename The filename in the $java.home/lib directory
 254      *                           of the properties file.  If none specified,
 255      *                           ${java.home}/lib/xalan.properties will be used.
 256      * @param fallbackClassName     Implementation class name, if nothing else
 257      *                              is found.  Use null to mean no fallback.
 258      *
 259      * @exception ObjectFactory.ConfigurationError
 260      */
 261     static String lookUpFactoryClassName(String factoryId,
 262                                                 String propertiesFilename,
 263                                                 String fallbackClassName)
 264     {
 265         // Use the system property first
 266         try {
 267             String systemProp = SecuritySupport.getSystemProperty(factoryId);
 268             if (systemProp != null) {
 269                 if (DEBUG) debugPrintln("found system property, value=" + systemProp);
 270                 return systemProp;
 271             }
 272         } catch (SecurityException se) {
 273             // Ignore and continue w/ next location
 274         }
 275 
 276         // Try to read from propertiesFilename, or
 277         // $java.home/lib/xalan.properties
 278         String factoryClassName = null;
 279         // no properties file name specified; use
 280         // $JAVA_HOME/lib/xalan.properties:
 281         if (propertiesFilename == null) {
 282             File propertiesFile = null;
 283             boolean propertiesFileExists = false;
 284             try {
 285                 String javah = SecuritySupport.getSystemProperty("java.home");
 286                 propertiesFilename = javah + File.separator +
 287                     "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
 288                 propertiesFile = new File(propertiesFilename);
 289                 propertiesFileExists = SecuritySupport.getFileExists(propertiesFile);
 290             } catch (SecurityException e) {
 291                 // try again...
 292                 fLastModified = -1;
 293                 fXalanProperties = null;
 294             }
 295 
 296             synchronized (ObjectFactory.class) {
 297                 boolean loadProperties = false;
 298                 FileInputStream fis = null;
 299                 try {
 300                     // file existed last time
 301                     if(fLastModified >= 0) {
 302                         if(propertiesFileExists &&
 303                                 (fLastModified < (fLastModified = SecuritySupport.getLastModified(propertiesFile)))) {
 304                             loadProperties = true;
 305                         } else {
 306                             // file has stopped existing...
 307                             if(!propertiesFileExists) {
 308                                 fLastModified = -1;
 309                                 fXalanProperties = null;
 310                             } // else, file wasn't modified!
 311                         }
 312                     } else {
 313                         // file has started to exist:
 314                         if(propertiesFileExists) {
 315                             loadProperties = true;
 316                             fLastModified = SecuritySupport.getLastModified(propertiesFile);
 317                         } // else, nothing's changed
 318                     }
 319                     if(loadProperties) {
 320                         // must never have attempted to read xalan.properties
 321                         // before (or it's outdeated)
 322                         fXalanProperties = new Properties();
 323                         fis = SecuritySupport.getFileInputStream(propertiesFile);
 324                         fXalanProperties.load(fis);
 325                     }
 326                 } catch (Exception x) {
 327                     fXalanProperties = null;
 328                     fLastModified = -1;
 329                     // assert(x instanceof FileNotFoundException
 330                     //        || x instanceof SecurityException)
 331                     // In both cases, ignore and continue w/ next location
 332                 }
 333                 finally {
 334                     // try to close the input stream if one was opened.
 335                     if (fis != null) {
 336                         try {
 337                             fis.close();
 338                         }
 339                         // Ignore the exception.
 340                         catch (IOException exc) {}
 341                     }
 342                 }
 343             }
 344             if(fXalanProperties != null) {
 345                 factoryClassName = fXalanProperties.getProperty(factoryId);
 346             }
 347         } else {
 348             FileInputStream fis = null;
 349             try {
 350                 fis = SecuritySupport.getFileInputStream(new File(propertiesFilename));
 351                 Properties props = new Properties();
 352                 props.load(fis);
 353                 factoryClassName = props.getProperty(factoryId);
 354             } catch (Exception x) {
 355                 // assert(x instanceof FileNotFoundException
 356                 //        || x instanceof SecurityException)
 357                 // In both cases, ignore and continue w/ next location
 358             }
 359             finally {
 360                 // try to close the input stream if one was opened.
 361                 if (fis != null) {
 362                     try {
 363                         fis.close();
 364                     }
 365                     // Ignore the exception.
 366                     catch (IOException exc) {}
 367                 }
 368             }
 369         }
 370         if (factoryClassName != null) {
 371             if (DEBUG) debugPrintln("found in " + propertiesFilename + ", value="
 372                           + factoryClassName);
 373             return factoryClassName;
 374         }
 375 
 376         // Try Jar Service Provider Mechanism
 377         return findJarServiceProviderName(factoryId);
 378     } // lookUpFactoryClass(String,String):String
 379 
 380     //
 381     // Private static methods
 382     //
 383 
 384     /** Prints a message to standard error if debugging is enabled. */
 385     private static void debugPrintln(String msg) {
 386         if (DEBUG) {
 387             System.err.println("JAXP: " + msg);
 388         }
 389     } // debugPrintln(String)
 390 
 391     /**
 392      * Figure out which ClassLoader to use.  For JDK 1.2 and later use
 393      * the context ClassLoader.
 394      */
 395     public static ClassLoader findClassLoader()
 396         throws ConfigurationError
 397     {
 398         if (System.getSecurityManager()!=null) {
 399             //this will ensure bootclassloader is used
 400             return null;
 401         }
 402 
 403         // Figure out which ClassLoader to use for loading the provider
 404         // class.  If there is a Context ClassLoader then use it.
 405         ClassLoader context = SecuritySupport.getContextClassLoader();
 406         ClassLoader system = SecuritySupport.getSystemClassLoader();
 407 
 408         ClassLoader chain = system;
 409         while (true) {
 410             if (context == chain) {
 411                 // Assert: we are on JDK 1.1 or we have no Context ClassLoader
 412                 // or any Context ClassLoader in chain of system classloader
 413                 // (including extension ClassLoader) so extend to widest
 414                 // ClassLoader (always look in system ClassLoader if Xalan
 415                 // is in boot/extension/system classpath and in current
 416                 // ClassLoader otherwise); normal classloaders delegate


 435                 // boot/extension/system ClassLoaders
 436                 return current;
 437             }
 438 
 439             if (chain == null) {
 440                 // boot ClassLoader reached
 441                 break;
 442             }
 443 
 444             // Check for any extension ClassLoaders in chain up to
 445             // boot ClassLoader
 446             chain = SecuritySupport.getParentClassLoader(chain);
 447         }
 448 
 449         // Assert: Context ClassLoader not in chain of
 450         // boot/extension/system ClassLoaders
 451         return context;
 452     } // findClassLoader():ClassLoader
 453 
 454     /**
 455      * Create an instance of a class using the same classloader for the ObjectFactory by default
 456      * or bootclassloader when Security Manager is in place
 457      */
 458     public static Object newInstance(String className, boolean doFallback)
 459         throws ConfigurationError
 460     {
 461         if (System.getSecurityManager()!=null) {
 462             return newInstance(className, null, doFallback);
 463         } else {
 464             return newInstance(className,
 465                 findClassLoader (), doFallback);
 466         }
 467     }
 468 
 469     /**
 470      * Create an instance of a class using the specified ClassLoader
 471      */
 472     static Object newInstance(String className, ClassLoader cl,
 473                                       boolean doFallback)
 474         throws ConfigurationError
 475     {
 476         // assert(className != null);
 477         try{
 478             Class providerClass = findProviderClass(className, cl, doFallback);
 479             Object instance = providerClass.newInstance();
 480             if (DEBUG) debugPrintln("created new instance of " + providerClass +
 481                    " using ClassLoader: " + cl);
 482             return instance;
 483         } catch (ClassNotFoundException x) {
 484             throw new ConfigurationError(
 485                 "Provider " + className + " not found", x);
 486         } catch (Exception x) {
 487             throw new ConfigurationError(
 488                 "Provider " + className + " could not be instantiated: " + x,
 489                 x);
 490         }
 491     }
 492 
 493     /**
 494      * Find a Class using the same classloader for the ObjectFactory by default
 495      * or bootclassloader when Security Manager is in place
 496      */
 497     public static Class findProviderClass(String className, boolean doFallback)
 498         throws ClassNotFoundException, ConfigurationError
 499     {
 500         if (System.getSecurityManager()!=null) {
 501             return Class.forName(className);
 502         } else {
 503             return findProviderClass (className,
 504                 findClassLoader (), doFallback);
 505         }
 506     }
 507 
 508     /**
 509      * Find a Class using the specified ClassLoader
 510      */
 511     static Class findProviderClass(String className, ClassLoader cl,
 512                                            boolean doFallback)
 513         throws ClassNotFoundException, ConfigurationError
 514     {
 515         //throw security exception if the calling thread is not allowed to access the
 516         //class. Restrict the access to the package classes as specified in java.security policy.
 517         SecurityManager security = System.getSecurityManager();
 518         try{
 519             if (security != null){
 520                 if (className.startsWith(XALAN_INTERNAL) ||
 521                     className.startsWith(XERCES_INTERNAL)) {
 522                     cl = null;
 523                 } else {
 524                     final int lastDot = className.lastIndexOf(".");
 525                     String packageName = className;
 526                     if (lastDot != -1) packageName = className.substring(0, lastDot);
 527                     security.checkPackageAccess(packageName);
 528                 }
 529              }
 530         }catch(SecurityException e){
 531             throw e;
 532         }
 533 
 534         Class providerClass;
 535         if (cl == null) {
 536             // XXX Use the bootstrap ClassLoader.  There is no way to
 537             // load a class using the bootstrap ClassLoader that works
 538             // in both JDK 1.1 and Java 2.  However, this should still
 539             // work b/c the following should be true:
 540             //
 541             // (cl == null) iff current ClassLoader == null
 542             //
 543             // Thus Class.forName(String) will use the current
 544             // ClassLoader which will be the bootstrap ClassLoader.
 545             providerClass = Class.forName(className);
 546         } else {
 547             try {
 548                 providerClass = cl.loadClass(className);
 549             } catch (ClassNotFoundException x) {
 550                 if (doFallback) {
 551                     // Fall back to current classloader
 552                     ClassLoader current = ObjectFactory.class.getClassLoader();
 553                     if (current == null) {
 554                         providerClass = Class.forName(className);
 555                     } else if (cl != current) {
 556                         cl = current;
 557                         providerClass = cl.loadClass(className);
 558                     } else {
 559                         throw x;
 560                     }
 561                 } else {
 562                     throw x;
 563                 }
 564             }
 565         }
 566 
 567         return providerClass;
 568     }
 569 
 570     /**
 571      * Find the name of service provider using Jar Service Provider Mechanism
 572      *
 573      * @return instance of provider class if found or null
 574      */
 575     private static String findJarServiceProviderName(String factoryId)
 576     {
 577         String serviceId = SERVICES_PATH + factoryId;
 578         InputStream is = null;
 579 
 580         // First try the Context ClassLoader
 581         ClassLoader cl = findClassLoader();
 582 
 583         is = SecuritySupport.getResourceAsStream(cl, serviceId);
 584 
 585         // If no provider found then try the current ClassLoader
 586         if (is == null) {
 587             ClassLoader current = ObjectFactory.class.getClassLoader();
 588             if (cl != current) {
 589                 cl = current;
 590                 is = SecuritySupport.getResourceAsStream(cl, serviceId);
 591             }
 592         }
 593 
 594         if (is == null) {
 595             // No provider found
 596             return null;
 597         }
 598 
 599         if (DEBUG) debugPrintln("found jar resource=" + serviceId +
 600                " using ClassLoader: " + cl);
 601 
 602         // Read the service provider name in UTF-8 as specified in
 603         // the jar spec.  Unfortunately this fails in Microsoft
 604         // VJ++, which does not implement the UTF-8
 605         // encoding. Theoretically, we should simply let it fail in
 606         // that case, since the JVM is obviously broken if it
 607         // doesn't support such a basic standard.  But since there
 608         // are still some users attempting to use VJ++ for
 609         // development, we have dropped in a fallback which makes a
 610         // second attempt using the platform's default encoding. In
 611         // VJ++ this is apparently ASCII, which is a subset of
 612         // UTF-8... and since the strings we'll be reading here are
 613         // also primarily limited to the 7-bit ASCII range (at
 614         // least, in English versions), this should work well
 615         // enough to keep us on the air until we're ready to
 616         // officially decommit from VJ++. [Edited comment from
 617         // jkesselm]
 618         BufferedReader rd;
 619         try {
 620             rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
 621         } catch (java.io.UnsupportedEncodingException e) {
 622             rd = new BufferedReader(new InputStreamReader(is));
 623         }
 624 
 625         String factoryClassName = null;
 626         try {
 627             // XXX Does not handle all possible input as specified by the
 628             // Jar Service Provider specification
 629             factoryClassName = rd.readLine();
 630         } catch (IOException x) {
 631             // No provider found
 632             return null;
 633         }
 634         finally {
 635             try {
 636                 // try to close the reader.
 637                 rd.close();
 638             }
 639             // Ignore the exception.
 640             catch (IOException exc) {}
 641         }
 642 
 643         if (factoryClassName != null &&
 644             ! "".equals(factoryClassName)) {
 645             if (DEBUG) debugPrintln("found in resource, value="
 646                    + factoryClassName);
 647 
 648             // Note: here we do not want to fall back to the current
 649             // ClassLoader because we want to avoid the case where the
 650             // resource file was found using one ClassLoader and the
 651             // provider class was instantiated using a different one.
 652             return factoryClassName;
 653         }
 654 
 655         // No provider found
 656         return null;
 657     }
 658 
 659 } // class ObjectFactory


   6  * Copyright 2001-2004 The Apache Software Foundation.
   7  *
   8  * Licensed under the Apache License, Version 2.0 (the "License");
   9  * you may not use this file except in compliance with the License.
  10  * You may obtain a copy of the License at
  11  *
  12  *     http://www.apache.org/licenses/LICENSE-2.0
  13  *
  14  * Unless required by applicable law or agreed to in writing, software
  15  * distributed under the License is distributed on an "AS IS" BASIS,
  16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17  * See the License for the specific language governing permissions and
  18  * limitations under the License.
  19  */
  20 /*
  21  * $Id: ObjectFactory.java,v 1.2.4.1 2005/09/15 02:39:54 jeffsuttor Exp $
  22  */
  23 
  24 package com.sun.org.apache.xalan.internal.utils;
  25 









  26 /**
  27  * This class is duplicated for each JAXP subpackage so keep it in sync.
  28  * It is package private and therefore is not exposed as part of the JAXP
  29  * API.
  30  * <p>






  31  * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
  32  * class and modified to be used as a general utility for creating objects
  33  * dynamically.
  34  *
  35  * @version $Id: ObjectFactory.java,v 1.11 2010-11-01 04:34:25 joehw Exp $
  36  */
  37 public class ObjectFactory {
  38 
  39     //
  40     // Constants
  41     //
  42      private static final String XALAN_INTERNAL = "com.sun.org.apache.xalan.internal";
  43      private static final String XERCES_INTERNAL = "com.sun.org.apache.xerces.internal";
  44 






  45     /** Set to true for debugging */
  46     private static final boolean DEBUG = false;
  47 


























































































































































































































































































































  48 
  49     /** Prints a message to standard error if debugging is enabled. */
  50     private static void debugPrintln(String msg) {
  51         if (DEBUG) {
  52             System.err.println("JAXP: " + msg);
  53         }
  54     } // debugPrintln(String)
  55 
  56     /**
  57      * Figure out which ClassLoader to use.  For JDK 1.2 and later use
  58      * the context ClassLoader.
  59      */
  60     public static ClassLoader findClassLoader()

  61     {
  62         if (System.getSecurityManager()!=null) {
  63             //this will ensure bootclassloader is used
  64             return null;
  65         }
  66 
  67         // Figure out which ClassLoader to use for loading the provider
  68         // class.  If there is a Context ClassLoader then use it.
  69         ClassLoader context = SecuritySupport.getContextClassLoader();
  70         ClassLoader system = SecuritySupport.getSystemClassLoader();
  71 
  72         ClassLoader chain = system;
  73         while (true) {
  74             if (context == chain) {
  75                 // Assert: we are on JDK 1.1 or we have no Context ClassLoader
  76                 // or any Context ClassLoader in chain of system classloader
  77                 // (including extension ClassLoader) so extend to widest
  78                 // ClassLoader (always look in system ClassLoader if Xalan
  79                 // is in boot/extension/system classpath and in current
  80                 // ClassLoader otherwise); normal classloaders delegate


  99                 // boot/extension/system ClassLoaders
 100                 return current;
 101             }
 102 
 103             if (chain == null) {
 104                 // boot ClassLoader reached
 105                 break;
 106             }
 107 
 108             // Check for any extension ClassLoaders in chain up to
 109             // boot ClassLoader
 110             chain = SecuritySupport.getParentClassLoader(chain);
 111         }
 112 
 113         // Assert: Context ClassLoader not in chain of
 114         // boot/extension/system ClassLoaders
 115         return context;
 116     } // findClassLoader():ClassLoader
 117 
 118     /**
 119      * Create an instance of a class using the same class loader for the ObjectFactory by default
 120      * or boot class loader when Security Manager is in place
 121      */
 122     public static Object newInstance(String className, boolean doFallback)
 123         throws ConfigurationError
 124     {
 125         if (System.getSecurityManager()!=null) {
 126             return newInstance(className, null, doFallback);
 127         } else {
 128             return newInstance(className,
 129                 findClassLoader (), doFallback);
 130         }
 131     }
 132 
 133     /**
 134      * Create an instance of a class using the specified ClassLoader
 135      */
 136     static Object newInstance(String className, ClassLoader cl,
 137                                       boolean doFallback)
 138         throws ConfigurationError
 139     {
 140         // assert(className != null);
 141         try{
 142             Class providerClass = findProviderClass(className, cl, doFallback);
 143             Object instance = providerClass.newInstance();
 144             if (DEBUG) debugPrintln("created new instance of " + providerClass +
 145                    " using ClassLoader: " + cl);
 146             return instance;
 147         } catch (ClassNotFoundException x) {
 148             throw new ConfigurationError(
 149                 "Provider " + className + " not found", x);
 150         } catch (Exception x) {
 151             throw new ConfigurationError(
 152                 "Provider " + className + " could not be instantiated: " + x,
 153                 x);
 154         }
 155     }
 156 
 157     /**
 158      * Find a Class using the same class loader for the ObjectFactory by default
 159      * or boot class loader when Security Manager is in place
 160      */
 161     public static Class<?> findProviderClass(String className, boolean doFallback)
 162         throws ClassNotFoundException, ConfigurationError
 163     {
 164         if (System.getSecurityManager()!=null) {
 165             return Class.forName(className);
 166         } else {
 167             return findProviderClass (className,
 168                 findClassLoader (), doFallback);
 169         }
 170     }
 171 
 172     /**
 173      * Find a Class using the specified ClassLoader
 174      */
 175     private static Class<?> findProviderClass(String className, ClassLoader cl,
 176                                            boolean doFallback)
 177         throws ClassNotFoundException, ConfigurationError
 178     {
 179         //throw security exception if the calling thread is not allowed to access the
 180         //class. Restrict the access to the package classes as specified in java.security policy.
 181         SecurityManager security = System.getSecurityManager();
 182         try{
 183             if (security != null){
 184                 if (className.startsWith(XALAN_INTERNAL) ||
 185                     className.startsWith(XERCES_INTERNAL)) {
 186                     cl = null;
 187                 } else {
 188                     final int lastDot = className.lastIndexOf(".");
 189                     String packageName = className;
 190                     if (lastDot != -1) packageName = className.substring(0, lastDot);
 191                     security.checkPackageAccess(packageName);
 192                 }
 193              }
 194         }catch(SecurityException e){
 195             throw e;
 196         }
 197 
 198         Class<?> providerClass;
 199         if (cl == null) {
 200             // XXX Use the bootstrap ClassLoader.  There is no way to
 201             // load a class using the bootstrap ClassLoader that works
 202             // in both JDK 1.1 and Java 2.  However, this should still
 203             // work b/c the following should be true:
 204             //
 205             // (cl == null) iff current ClassLoader == null
 206             //
 207             // Thus Class.forName(String) will use the current
 208             // ClassLoader which will be the bootstrap ClassLoader.
 209             providerClass = Class.forName(className);
 210         } else {
 211             try {
 212                 providerClass = cl.loadClass(className);
 213             } catch (ClassNotFoundException x) {
 214                 if (doFallback) {
 215                     // Fall back to current classloader
 216                     ClassLoader current = ObjectFactory.class.getClassLoader();
 217                     if (current == null) {
 218                         providerClass = Class.forName(className);
 219                     } else if (cl != current) {
 220                         cl = current;
 221                         providerClass = cl.loadClass(className);
 222                     } else {
 223                         throw x;
 224                     }
 225                 } else {
 226                     throw x;
 227                 }
 228             }
 229         }
 230 
 231         return providerClass;
 232     }
 233 

























































































 234 } // class ObjectFactory