Home | History | Annotate | Download | only in extensions
      1 /*
      2  * Licensed to the Apache Software Foundation (ASF) under one
      3  * or more contributor license agreements. See the NOTICE file
      4  * distributed with this work for additional information
      5  * regarding copyright ownership. The ASF licenses this file
      6  * to you under the Apache License, Version 2.0 (the  "License");
      7  * you may not use this file except in compliance with the License.
      8  * You may obtain a copy of the License at
      9  *
     10  *     http://www.apache.org/licenses/LICENSE-2.0
     11  *
     12  * Unless required by applicable law or agreed to in writing, software
     13  * distributed under the License is distributed on an "AS IS" BASIS,
     14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15  * See the License for the specific language governing permissions and
     16  * limitations under the License.
     17  */
     18 /*
     19  * $Id: ObjectFactory.java 468637 2006-10-28 06:51:02Z minchau $
     20  */
     21 
     22 package org.apache.xalan.extensions;
     23 
     24 /**
     25  * This class is duplicated for each JAXP subpackage so keep it in sync.
     26  * It is package private and therefore is not exposed as part of the JAXP
     27  * API.
     28  * <p>
     29  * This code is designed to implement the JAXP 1.1 spec pluggability
     30  * feature and is designed to run on JDK version 1.1 and
     31  * later, and to compile on JDK 1.2 and onward.
     32  * The code also runs both as part of an unbundled jar file and
     33  * when bundled as part of the JDK.
     34  * <p>
     35  * This class was moved from the <code>javax.xml.parsers.ObjectFactory</code>
     36  * class and modified to be used as a general utility for creating objects
     37  * dynamically.
     38  *
     39  * @version $Id: ObjectFactory.java 468637 2006-10-28 06:51:02Z minchau $
     40  */
     41 class ObjectFactory {
     42 
     43     /**
     44      * Figure out which ClassLoader to use.  For JDK 1.2 and later use
     45      * the context ClassLoader.
     46      */
     47     static ClassLoader findClassLoader()
     48         throws ConfigurationError
     49     {
     50         // BEGIN android-changed
     51         //     the context class loader is always sufficient
     52         return Thread.currentThread().getContextClassLoader();
     53         // END android-changed
     54     } // findClassLoader():ClassLoader
     55 
     56     /**
     57      * Find a Class using the specified ClassLoader
     58      */
     59     static Class findProviderClass(String className, ClassLoader cl,
     60                                            boolean doFallback)
     61         throws ClassNotFoundException, ConfigurationError
     62     {
     63         //throw security exception if the calling thread is not allowed to access the
     64         //class. Restrict the access to the package classes as specified in java.security policy.
     65         SecurityManager security = System.getSecurityManager();
     66         try{
     67                 if (security != null){
     68                     final int lastDot = className.lastIndexOf(".");
     69                     String packageName = className;
     70                     if (lastDot != -1) packageName = className.substring(0, lastDot);
     71                     security.checkPackageAccess(packageName);
     72                  }
     73         }catch(SecurityException e){
     74             throw e;
     75         }
     76 
     77         Class providerClass;
     78         if (cl == null) {
     79             // XXX Use the bootstrap ClassLoader.  There is no way to
     80             // load a class using the bootstrap ClassLoader that works
     81             // in both JDK 1.1 and Java 2.  However, this should still
     82             // work b/c the following should be true:
     83             //
     84             // (cl == null) iff current ClassLoader == null
     85             //
     86             // Thus Class.forName(String) will use the current
     87             // ClassLoader which will be the bootstrap ClassLoader.
     88             providerClass = Class.forName(className);
     89         } else {
     90             try {
     91                 providerClass = cl.loadClass(className);
     92             } catch (ClassNotFoundException x) {
     93                 if (doFallback) {
     94                     // Fall back to current classloader
     95                     ClassLoader current = ObjectFactory.class.getClassLoader();
     96                     if (current == null) {
     97                         providerClass = Class.forName(className);
     98                     } else if (cl != current) {
     99                         cl = current;
    100                         providerClass = cl.loadClass(className);
    101                     } else {
    102                         throw x;
    103                     }
    104                 } else {
    105                     throw x;
    106                 }
    107             }
    108         }
    109 
    110         return providerClass;
    111     }
    112 
    113     //
    114     // Classes
    115     //
    116 
    117     /**
    118      * A configuration error.
    119      */
    120     static class ConfigurationError
    121         extends Error {
    122                 static final long serialVersionUID = 8564305128443551853L;
    123         //
    124         // Data
    125         //
    126 
    127         /** Exception. */
    128         private Exception exception;
    129 
    130         //
    131         // Constructors
    132         //
    133 
    134         /**
    135          * Construct a new instance with the specified detail string and
    136          * exception.
    137          */
    138         ConfigurationError(String msg, Exception x) {
    139             super(msg);
    140             this.exception = x;
    141         } // <init>(String,Exception)
    142 
    143         //
    144         // Public methods
    145         //
    146 
    147         /** Returns the exception associated to this error. */
    148         Exception getException() {
    149             return exception;
    150         } // getException():Exception
    151 
    152     } // class ConfigurationError
    153 
    154 } // class ObjectFactory
    155