You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commons-cvs@xml.apache.org by mr...@apache.org on 2005/06/17 21:26:53 UTC

cvs commit: xml-commons/java/external/src/javax/xml/datatype FactoryFinder.java

mrglavas    2005/06/17 12:26:53

  Modified:    java/external/src/javax/xml/parsers FactoryFinder.java
               java/external/src/javax/xml/transform FactoryFinder.java
               java/external/src/javax/xml/datatype FactoryFinder.java
  Log:
  Merge in Performance Fix from the tck-jaxp-1_2_0 branch:
  When reading the service provider name from a jar
  a BufferedReader is used to read the first line from the
  file. BufferedReader's default buffer size is 8K chars. Since
  we're only reading one line (the name of a class) this is pretty
  excessive. Reducing this size significantly to 80 chars.
  
  Revision  Changes    Path
  1.12      +317 -312  xml-commons/java/external/src/javax/xml/parsers/FactoryFinder.java
  
  Index: FactoryFinder.java
  ===================================================================
  RCS file: /home/cvs/xml-commons/java/external/src/javax/xml/parsers/FactoryFinder.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- FactoryFinder.java	8 Apr 2005 10:39:13 -0000	1.11
  +++ FactoryFinder.java	17 Jun 2005 19:26:53 -0000	1.12
  @@ -1,312 +1,317 @@
  -/*
  - * Copyright 2003-2004 The Apache Software Foundation.
  - *
  - * Licensed under the Apache License, Version 2.0 (the "License");
  - * you may not use this file except in compliance with the License.
  - * You may obtain a copy of the License at
  - *
  - *     http://www.apache.org/licenses/LICENSE-2.0
  - *
  - * Unless required by applicable law or agreed to in writing, software
  - * distributed under the License is distributed on an "AS IS" BASIS,
  - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  - * See the License for the specific language governing permissions and
  - * limitations under the License.
  - */
  -
  -// $Id$
  -
  -package javax.xml.parsers;
  -
  -import java.io.File;
  -import java.io.FileInputStream;
  -
  -import java.util.Properties;
  -import java.io.BufferedReader;
  -import java.io.IOException;
  -import java.io.InputStream;
  -import java.io.InputStreamReader;
  -import java.net.URL;
  -
  -/**
  - * This class is duplicated for each JAXP subpackage so keep it in
  - * sync.  It is package private.
  - *
  - * This code is designed to implement the JAXP 1.1 spec pluggability
  - * feature and is designed to run on JDK version 1.1 and later including
  - * JVMs that perform early linking like the Microsoft JVM in IE 5.  Note
  - * however that it must be compiled on a JDK version 1.2 or later system
  - * since it calls Thread#getContextClassLoader().  The code also runs both
  - * as part of an unbundled jar file and when bundled as part of the JDK.
  - */
  -class FactoryFinder {
  -    /** Temp debug code - this will be removed after we test everything
  -     */
  -    private static boolean debug = false;
  -    static Properties cacheProps= new Properties();
  -    static SecuritySupport ss = new SecuritySupport() ;
  -    static boolean firstTime = true;
  -
  -    // Define system property "jaxp.debug" to get output
  -    static {
  -        // Use try/catch block to support applets, which throws
  -        // SecurityException out of this code.
  -        try {
  -            String val = ss.getSystemProperty("jaxp.debug");
  -            // Allow simply setting the prop to turn on debug
  -            debug = val != null && (! "false".equals(val));
  -        } catch (SecurityException se) {
  -            debug = false;
  -        }
  -    }
  -    
  -
  -    private static void dPrint(String msg) {
  -        if (debug) {
  -            System.err.println("JAXP: " + msg);
  -        }
  -    }
  -    
  -    /**
  -     * Create an instance of a class using the specified ClassLoader and
  -     * optionally fall back to the current ClassLoader if not found.
  -     *
  -     * @param className Name of the concrete class corresponding to the
  -     * service provider
  -     *
  -     * @param cl ClassLoader to use to load the class, null means to use
  -     * the bootstrap ClassLoader
  -     *
  -     * @param doFallback true if the current ClassLoader should be tried as
  -     * a fallback if the class is not found using cl
  -     */
  -    private static Object newInstance(String className, ClassLoader cl,
  -                                      boolean doFallback)
  -        throws ConfigurationError
  -    {
  -        // assert(className != null);
  -
  -        try {
  -            Class providerClass;
  -            if (cl == null) {
  -                // If classloader is null Use the bootstrap ClassLoader.  
  -                // Thus Class.forName(String) will use the current
  -                // ClassLoader which will be the bootstrap ClassLoader.
  -                providerClass = Class.forName(className);
  -            } else {
  -                try {
  -                    providerClass = cl.loadClass(className);
  -                } catch (ClassNotFoundException x) {
  -                    if (doFallback) {
  -                        // Fall back to current classloader
  -                        cl = FactoryFinder.class.getClassLoader();
  -                        providerClass = cl.loadClass(className);
  -                    } else {
  -                        throw x;
  -                    }
  -                }
  -            }
  -                        
  -            Object instance = providerClass.newInstance();
  -            dPrint("created new instance of " + providerClass +
  -                   " using ClassLoader: " + cl);
  -            return instance;
  -        } catch (ClassNotFoundException x) {
  -            throw new ConfigurationError(
  -                "Provider " + className + " not found", x);
  -        } catch (Exception x) {
  -            throw new ConfigurationError(
  -                "Provider " + className + " could not be instantiated: " + x,
  -                x);
  -        }
  -    }
  -    
  -    /**
  -     * Finds the implementation Class object in the specified order.  Main
  -     * entry point.
  -     * @return Class object of factory, never null
  -     *
  -     * @param factoryId             Name of the factory to find, same as
  -     *                              a property name
  -     * @param fallbackClassName     Implementation class name, if nothing else
  -     *                              is found.  Use null to mean no fallback.
  -     *
  -     * Package private so this code can be shared.
  -     */
  -    static Object find(String factoryId, String fallbackClassName)
  -        throws ConfigurationError
  -    {        
  -
  -        // Figure out which ClassLoader to use for loading the provider
  -        // class.  If there is a Context ClassLoader then use it.
  -        
  -        ClassLoader classLoader = ss.getContextClassLoader();
  -        
  -        if (classLoader == null) {
  -            // if we have no Context ClassLoader
  -            // so use the current ClassLoader
  -            classLoader = FactoryFinder.class.getClassLoader();
  -        }
  -
  -        dPrint("find factoryId =" + factoryId);
  -        
  -        // Use the system property first
  -        try {
  -            String systemProp = ss.getSystemProperty(factoryId);
  -            if( systemProp!=null) {                
  -                dPrint("found system property, value=" + systemProp);
  -                return newInstance(systemProp, classLoader, true );
  -            }
  -        } catch (SecurityException se) {
  -            //if first option fails due to any reason we should try next option in the
  -            //look up algorithm.
  -        }
  -
  -        // try to read from $java.home/lib/jaxp.properties
  -        try {
  -            String javah = ss.getSystemProperty("java.home");
  -            String configFile = javah + File.separator +
  -                "lib" + File.separator + "jaxp.properties";
  -            String factoryClassName = null;
  -            if(firstTime){
  -                synchronized(cacheProps){
  -                    if(firstTime){
  -                        File f=new File( configFile );
  -                        firstTime = false;
  -                        if(ss.doesFileExist(f)){
  -                            dPrint("Read properties file "+f);
  -                            //cacheProps.load( new FileInputStream(f));
  -                            cacheProps.load(ss.getFileInputStream(f));
  -                        }
  -                    }
  -                }
  -            }
  -            factoryClassName = cacheProps.getProperty(factoryId);            
  -
  -            if(factoryClassName != null){
  -                dPrint("found in $java.home/jaxp.properties, value=" + factoryClassName);
  -                return newInstance(factoryClassName, classLoader, true);
  -            }
  -        } catch(Exception ex ) {
  -            if( debug ) ex.printStackTrace();
  -        }
  -
  -        // Try Jar Service Provider Mechanism
  -        Object provider = findJarServiceProvider(factoryId);
  -        if (provider != null) {
  -            return provider;
  -        }
  -        if (fallbackClassName == null) {
  -            throw new ConfigurationError(
  -                "Provider for " + factoryId + " cannot be found", null);
  -        }
  -
  -        dPrint("loaded from fallback value: " + fallbackClassName);
  -        return newInstance(fallbackClassName, classLoader, true);
  -    }
  -    
  -    /*
  -     * Try to find provider using Jar Service Provider Mechanism
  -     *
  -     * @return instance of provider class if found or null
  -     */
  -    private static Object findJarServiceProvider(String factoryId)
  -        throws ConfigurationError
  -    {
  -
  -        String serviceId = "META-INF/services/" + factoryId;
  -        InputStream is = null;
  -
  -        // First try the Context ClassLoader
  -        ClassLoader cl = ss.getContextClassLoader();
  -        if (cl != null) {
  -            is = ss.getResourceAsStream(cl, serviceId);
  -
  -            // If no provider found then try the current ClassLoader
  -            if (is == null) {
  -                cl = FactoryFinder.class.getClassLoader();
  -                is = ss.getResourceAsStream(cl, serviceId);
  -            }
  -        } else {
  -            // No Context ClassLoader, try the current
  -            // ClassLoader
  -            cl = FactoryFinder.class.getClassLoader();
  -            is = ss.getResourceAsStream(cl, serviceId);
  -        }
  -
  -        if (is == null) {
  -            // No provider found
  -            return null;
  -        }
  -
  -        dPrint("found jar resource=" + serviceId +
  -               " using ClassLoader: " + cl);
  -
  -        // Read the service provider name in UTF-8 as specified in
  -        // the jar spec.  Unfortunately this fails in Microsoft
  -        // VJ++, which does not implement the UTF-8
  -        // encoding. Theoretically, we should simply let it fail in
  -        // that case, since the JVM is obviously broken if it
  -        // doesn't support such a basic standard.  But since there
  -        // are still some users attempting to use VJ++ for
  -        // development, we have dropped in a fallback which makes a
  -        // second attempt using the platform's default encoding. In
  -        // VJ++ this is apparently ASCII, which is a subset of
  -        // UTF-8... and since the strings we'll be reading here are
  -        // also primarily limited to the 7-bit ASCII range (at
  -        // least, in English versions), this should work well
  -        // enough to keep us on the air until we're ready to
  -        // officially decommit from VJ++. [Edited comment from
  -        // jkesselm]
  -        BufferedReader rd;
  -        try {
  -            rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
  -        } catch (java.io.UnsupportedEncodingException e) {
  -            rd = new BufferedReader(new InputStreamReader(is));
  -        }
  -        
  -        String factoryClassName = null;
  -        try {
  -            // XXX Does not handle all possible input as specified by the
  -            // Jar Service Provider specification
  -            factoryClassName = rd.readLine();
  -            rd.close();
  -        } catch (IOException x) {
  -            // No provider found
  -            return null;
  -        }
  -
  -        if (factoryClassName != null &&
  -            ! "".equals(factoryClassName)) {
  -            dPrint("found in resource, value="
  -                   + factoryClassName);
  -
  -        // Note: here we do not want to fall back to the current
  -        // ClassLoader because we want to avoid the case where the
  -        // resource file was found using one ClassLoader and the
  -        // provider class was instantiated using a different one.
  -        return newInstance(factoryClassName, cl, false);
  -        }
  -
  -        // No provider found
  -        return null;
  -    }
  -
  -    static class ConfigurationError extends Error {
  -        private Exception exception;
  -
  -        /**
  -         * Construct a new instance with the specified detail string and
  -         * exception.
  -         */
  -        ConfigurationError(String msg, Exception x) {
  -            super(msg);
  -            this.exception = x;
  -        }
  -
  -        Exception getException() {
  -            return exception;
  -        }
  -    }
  -
  -}
  +/*
  + * Copyright 2003-2005 The Apache Software Foundation.
  + *
  + * Licensed under the Apache License, Version 2.0 (the "License");
  + * you may not use this file except in compliance with the License.
  + * You may obtain a copy of the License at
  + *
  + *     http://www.apache.org/licenses/LICENSE-2.0
  + *
  + * Unless required by applicable law or agreed to in writing, software
  + * distributed under the License is distributed on an "AS IS" BASIS,
  + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  + * See the License for the specific language governing permissions and
  + * limitations under the License.
  + */
  +
  +// $Id$
  +
  +package javax.xml.parsers;
  +
  +import java.io.File;
  +import java.io.FileInputStream;
  +
  +import java.util.Properties;
  +import java.io.BufferedReader;
  +import java.io.IOException;
  +import java.io.InputStream;
  +import java.io.InputStreamReader;
  +import java.net.URL;
  +
  +/**
  + * This class is duplicated for each JAXP subpackage so keep it in
  + * sync.  It is package private.
  + *
  + * This code is designed to implement the JAXP 1.1 spec pluggability
  + * feature and is designed to run on JDK version 1.1 and later including
  + * JVMs that perform early linking like the Microsoft JVM in IE 5.  Note
  + * however that it must be compiled on a JDK version 1.2 or later system
  + * since it calls Thread#getContextClassLoader().  The code also runs both
  + * as part of an unbundled jar file and when bundled as part of the JDK.
  + */
  +class FactoryFinder {
  +    /** Temp debug code - this will be removed after we test everything
  +     */
  +    private static boolean debug = false;
  +    static Properties cacheProps= new Properties();
  +    static SecuritySupport ss = new SecuritySupport() ;
  +    static boolean firstTime = true;
  +    
  +    /**
  +     * Default columns per line.
  +     */
  +    private static final int DEFAULT_LINE_LENGTH = 80;
  +
  +    // Define system property "jaxp.debug" to get output
  +    static {
  +        // Use try/catch block to support applets, which throws
  +        // SecurityException out of this code.
  +        try {
  +            String val = ss.getSystemProperty("jaxp.debug");
  +            // Allow simply setting the prop to turn on debug
  +            debug = val != null && (! "false".equals(val));
  +        } catch (SecurityException se) {
  +            debug = false;
  +        }
  +    }
  +    
  +
  +    private static void dPrint(String msg) {
  +        if (debug) {
  +            System.err.println("JAXP: " + msg);
  +        }
  +    }
  +    
  +    /**
  +     * Create an instance of a class using the specified ClassLoader and
  +     * optionally fall back to the current ClassLoader if not found.
  +     *
  +     * @param className Name of the concrete class corresponding to the
  +     * service provider
  +     *
  +     * @param cl ClassLoader to use to load the class, null means to use
  +     * the bootstrap ClassLoader
  +     *
  +     * @param doFallback true if the current ClassLoader should be tried as
  +     * a fallback if the class is not found using cl
  +     */
  +    private static Object newInstance(String className, ClassLoader cl,
  +                                      boolean doFallback)
  +        throws ConfigurationError
  +    {
  +        // assert(className != null);
  +
  +        try {
  +            Class providerClass;
  +            if (cl == null) {
  +                // If classloader is null Use the bootstrap ClassLoader.  
  +                // Thus Class.forName(String) will use the current
  +                // ClassLoader which will be the bootstrap ClassLoader.
  +                providerClass = Class.forName(className);
  +            } else {
  +                try {
  +                    providerClass = cl.loadClass(className);
  +                } catch (ClassNotFoundException x) {
  +                    if (doFallback) {
  +                        // Fall back to current classloader
  +                        cl = FactoryFinder.class.getClassLoader();
  +                        providerClass = cl.loadClass(className);
  +                    } else {
  +                        throw x;
  +                    }
  +                }
  +            }
  +                        
  +            Object instance = providerClass.newInstance();
  +            dPrint("created new instance of " + providerClass +
  +                   " using ClassLoader: " + cl);
  +            return instance;
  +        } catch (ClassNotFoundException x) {
  +            throw new ConfigurationError(
  +                "Provider " + className + " not found", x);
  +        } catch (Exception x) {
  +            throw new ConfigurationError(
  +                "Provider " + className + " could not be instantiated: " + x,
  +                x);
  +        }
  +    }
  +    
  +    /**
  +     * Finds the implementation Class object in the specified order.  Main
  +     * entry point.
  +     * @return Class object of factory, never null
  +     *
  +     * @param factoryId             Name of the factory to find, same as
  +     *                              a property name
  +     * @param fallbackClassName     Implementation class name, if nothing else
  +     *                              is found.  Use null to mean no fallback.
  +     *
  +     * Package private so this code can be shared.
  +     */
  +    static Object find(String factoryId, String fallbackClassName)
  +        throws ConfigurationError
  +    {        
  +
  +        // Figure out which ClassLoader to use for loading the provider
  +        // class.  If there is a Context ClassLoader then use it.
  +        
  +        ClassLoader classLoader = ss.getContextClassLoader();
  +        
  +        if (classLoader == null) {
  +            // if we have no Context ClassLoader
  +            // so use the current ClassLoader
  +            classLoader = FactoryFinder.class.getClassLoader();
  +        }
  +
  +        dPrint("find factoryId =" + factoryId);
  +        
  +        // Use the system property first
  +        try {
  +            String systemProp = ss.getSystemProperty(factoryId);
  +            if( systemProp!=null) {                
  +                dPrint("found system property, value=" + systemProp);
  +                return newInstance(systemProp, classLoader, true );
  +            }
  +        } catch (SecurityException se) {
  +            //if first option fails due to any reason we should try next option in the
  +            //look up algorithm.
  +        }
  +
  +        // try to read from $java.home/lib/jaxp.properties
  +        try {
  +            String javah = ss.getSystemProperty("java.home");
  +            String configFile = javah + File.separator +
  +                "lib" + File.separator + "jaxp.properties";
  +            String factoryClassName = null;
  +            if(firstTime){
  +                synchronized(cacheProps){
  +                    if(firstTime){
  +                        File f=new File( configFile );
  +                        firstTime = false;
  +                        if(ss.doesFileExist(f)){
  +                            dPrint("Read properties file "+f);
  +                            //cacheProps.load( new FileInputStream(f));
  +                            cacheProps.load(ss.getFileInputStream(f));
  +                        }
  +                    }
  +                }
  +            }
  +            factoryClassName = cacheProps.getProperty(factoryId);            
  +
  +            if(factoryClassName != null){
  +                dPrint("found in $java.home/jaxp.properties, value=" + factoryClassName);
  +                return newInstance(factoryClassName, classLoader, true);
  +            }
  +        } catch(Exception ex ) {
  +            if( debug ) ex.printStackTrace();
  +        }
  +
  +        // Try Jar Service Provider Mechanism
  +        Object provider = findJarServiceProvider(factoryId);
  +        if (provider != null) {
  +            return provider;
  +        }
  +        if (fallbackClassName == null) {
  +            throw new ConfigurationError(
  +                "Provider for " + factoryId + " cannot be found", null);
  +        }
  +
  +        dPrint("loaded from fallback value: " + fallbackClassName);
  +        return newInstance(fallbackClassName, classLoader, true);
  +    }
  +    
  +    /*
  +     * Try to find provider using Jar Service Provider Mechanism
  +     *
  +     * @return instance of provider class if found or null
  +     */
  +    private static Object findJarServiceProvider(String factoryId)
  +        throws ConfigurationError
  +    {
  +
  +        String serviceId = "META-INF/services/" + factoryId;
  +        InputStream is = null;
  +
  +        // First try the Context ClassLoader
  +        ClassLoader cl = ss.getContextClassLoader();
  +        if (cl != null) {
  +            is = ss.getResourceAsStream(cl, serviceId);
  +
  +            // If no provider found then try the current ClassLoader
  +            if (is == null) {
  +                cl = FactoryFinder.class.getClassLoader();
  +                is = ss.getResourceAsStream(cl, serviceId);
  +            }
  +        } else {
  +            // No Context ClassLoader, try the current
  +            // ClassLoader
  +            cl = FactoryFinder.class.getClassLoader();
  +            is = ss.getResourceAsStream(cl, serviceId);
  +        }
  +
  +        if (is == null) {
  +            // No provider found
  +            return null;
  +        }
  +
  +        dPrint("found jar resource=" + serviceId +
  +               " using ClassLoader: " + cl);
  +
  +        // Read the service provider name in UTF-8 as specified in
  +        // the jar spec.  Unfortunately this fails in Microsoft
  +        // VJ++, which does not implement the UTF-8
  +        // encoding. Theoretically, we should simply let it fail in
  +        // that case, since the JVM is obviously broken if it
  +        // doesn't support such a basic standard.  But since there
  +        // are still some users attempting to use VJ++ for
  +        // development, we have dropped in a fallback which makes a
  +        // second attempt using the platform's default encoding. In
  +        // VJ++ this is apparently ASCII, which is a subset of
  +        // UTF-8... and since the strings we'll be reading here are
  +        // also primarily limited to the 7-bit ASCII range (at
  +        // least, in English versions), this should work well
  +        // enough to keep us on the air until we're ready to
  +        // officially decommit from VJ++. [Edited comment from
  +        // jkesselm]
  +        BufferedReader rd;
  +        try {
  +            rd = new BufferedReader(new InputStreamReader(is, "UTF-8"), DEFAULT_LINE_LENGTH);
  +        } catch (java.io.UnsupportedEncodingException e) {
  +            rd = new BufferedReader(new InputStreamReader(is), DEFAULT_LINE_LENGTH);
  +        }
  +        
  +        String factoryClassName = null;
  +        try {
  +            // XXX Does not handle all possible input as specified by the
  +            // Jar Service Provider specification
  +            factoryClassName = rd.readLine();
  +            rd.close();
  +        } catch (IOException x) {
  +            // No provider found
  +            return null;
  +        }
  +
  +        if (factoryClassName != null &&
  +            ! "".equals(factoryClassName)) {
  +            dPrint("found in resource, value="
  +                   + factoryClassName);
  +
  +        // Note: here we do not want to fall back to the current
  +        // ClassLoader because we want to avoid the case where the
  +        // resource file was found using one ClassLoader and the
  +        // provider class was instantiated using a different one.
  +        return newInstance(factoryClassName, cl, false);
  +        }
  +
  +        // No provider found
  +        return null;
  +    }
  +
  +    static class ConfigurationError extends Error {
  +        private Exception exception;
  +
  +        /**
  +         * Construct a new instance with the specified detail string and
  +         * exception.
  +         */
  +        ConfigurationError(String msg, Exception x) {
  +            super(msg);
  +            this.exception = x;
  +        }
  +
  +        Exception getException() {
  +            return exception;
  +        }
  +    }
  +
  +}
  
  
  
  1.9       +317 -312  xml-commons/java/external/src/javax/xml/transform/FactoryFinder.java
  
  Index: FactoryFinder.java
  ===================================================================
  RCS file: /home/cvs/xml-commons/java/external/src/javax/xml/transform/FactoryFinder.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- FactoryFinder.java	8 Apr 2005 10:39:13 -0000	1.8
  +++ FactoryFinder.java	17 Jun 2005 19:26:53 -0000	1.9
  @@ -1,312 +1,317 @@
  -/*
  - * Copyright 2003-2004 The Apache Software Foundation.
  - *
  - * Licensed under the Apache License, Version 2.0 (the "License");
  - * you may not use this file except in compliance with the License.
  - * You may obtain a copy of the License at
  - *
  - *     http://www.apache.org/licenses/LICENSE-2.0
  - *
  - * Unless required by applicable law or agreed to in writing, software
  - * distributed under the License is distributed on an "AS IS" BASIS,
  - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  - * See the License for the specific language governing permissions and
  - * limitations under the License.
  - */
  -
  -// $Id$
  -
  -package javax.xml.transform;
  -
  -import java.io.File;
  -import java.io.FileInputStream;
  -
  -import java.util.Properties;
  -import java.io.BufferedReader;
  -import java.io.IOException;
  -import java.io.InputStream;
  -import java.io.InputStreamReader;
  -import java.net.URL;
  -
  -/**
  - * This class is duplicated for each JAXP subpackage so keep it in
  - * sync.  It is package private.
  - *
  - * This code is designed to implement the JAXP 1.1 spec pluggability
  - * feature and is designed to run on JDK version 1.1 and later including
  - * JVMs that perform early linking like the Microsoft JVM in IE 5.  Note
  - * however that it must be compiled on a JDK version 1.2 or later system
  - * since it calls Thread#getContextClassLoader().  The code also runs both
  - * as part of an unbundled jar file and when bundled as part of the JDK.
  - */
  -class FactoryFinder {
  -    /** Temp debug code - this will be removed after we test everything
  -     */
  -    private static boolean debug = false;
  -    static Properties cacheProps= new Properties();
  -    static SecuritySupport ss = new SecuritySupport() ;
  -    static boolean firstTime = true;
  -
  -    // Define system property "jaxp.debug" to get output
  -    static {
  -        // Use try/catch block to support applets, which throws
  -        // SecurityException out of this code.
  -        try {
  -            String val = ss.getSystemProperty("jaxp.debug");
  -            // Allow simply setting the prop to turn on debug
  -            debug = val != null && (! "false".equals(val));
  -        } catch (SecurityException se) {
  -            debug = false;
  -        }
  -    }
  -    
  -
  -    private static void dPrint(String msg) {
  -        if (debug) {
  -            System.err.println("JAXP: " + msg);
  -        }
  -    }
  -    
  -    /**
  -     * Create an instance of a class using the specified ClassLoader and
  -     * optionally fall back to the current ClassLoader if not found.
  -     *
  -     * @param className Name of the concrete class corresponding to the
  -     * service provider
  -     *
  -     * @param cl ClassLoader to use to load the class, null means to use
  -     * the bootstrap ClassLoader
  -     *
  -     * @param doFallback true if the current ClassLoader should be tried as
  -     * a fallback if the class is not found using cl
  -     */
  -    private static Object newInstance(String className, ClassLoader cl,
  -                                      boolean doFallback)
  -        throws ConfigurationError
  -    {
  -        // assert(className != null);
  -
  -        try {
  -            Class providerClass;
  -            if (cl == null) {
  -                // If classloader is null Use the bootstrap ClassLoader.  
  -                // Thus Class.forName(String) will use the current
  -                // ClassLoader which will be the bootstrap ClassLoader.
  -                providerClass = Class.forName(className);
  -            } else {
  -                try {
  -                    providerClass = cl.loadClass(className);
  -                } catch (ClassNotFoundException x) {
  -                    if (doFallback) {
  -                        // Fall back to current classloader
  -                        cl = FactoryFinder.class.getClassLoader();
  -                        providerClass = cl.loadClass(className);
  -                    } else {
  -                        throw x;
  -                    }
  -                }
  -            }
  -                        
  -            Object instance = providerClass.newInstance();
  -            dPrint("created new instance of " + providerClass +
  -                   " using ClassLoader: " + cl);
  -            return instance;
  -        } catch (ClassNotFoundException x) {
  -            throw new ConfigurationError(
  -                "Provider " + className + " not found", x);
  -        } catch (Exception x) {
  -            throw new ConfigurationError(
  -                "Provider " + className + " could not be instantiated: " + x,
  -                x);
  -        }
  -    }
  -    
  -    /**
  -     * Finds the implementation Class object in the specified order.  Main
  -     * entry point.
  -     * @return Class object of factory, never null
  -     *
  -     * @param factoryId             Name of the factory to find, same as
  -     *                              a property name
  -     * @param fallbackClassName     Implementation class name, if nothing else
  -     *                              is found.  Use null to mean no fallback.
  -     *
  -     * Package private so this code can be shared.
  -     */
  -    static Object find(String factoryId, String fallbackClassName)
  -        throws ConfigurationError
  -    {        
  -
  -        // Figure out which ClassLoader to use for loading the provider
  -        // class.  If there is a Context ClassLoader then use it.
  -        
  -        ClassLoader classLoader = ss.getContextClassLoader();
  -        
  -        if (classLoader == null) {
  -            // if we have no Context ClassLoader
  -            // so use the current ClassLoader
  -            classLoader = FactoryFinder.class.getClassLoader();
  -        }
  -
  -        dPrint("find factoryId =" + factoryId);
  -        
  -        // Use the system property first
  -        try {
  -            String systemProp = ss.getSystemProperty(factoryId);
  -            if( systemProp!=null) {                
  -                dPrint("found system property, value=" + systemProp);
  -                return newInstance(systemProp, classLoader, true );
  -            }
  -        } catch (SecurityException se) {
  -            //if first option fails due to any reason we should try next option in the
  -            //look up algorithm.
  -        }
  -
  -        // try to read from $java.home/lib/jaxp.properties
  -        try {
  -            String javah = ss.getSystemProperty("java.home");
  -            String configFile = javah + File.separator +
  -                "lib" + File.separator + "jaxp.properties";
  -            String factoryClassName = null;
  -            if(firstTime){
  -                synchronized(cacheProps){
  -                    if(firstTime){
  -                        File f=new File( configFile );
  -                        firstTime = false;
  -                        if(ss.doesFileExist(f)){
  -                            dPrint("Read properties file "+f);
  -                            //cacheProps.load( new FileInputStream(f));
  -                            cacheProps.load(ss.getFileInputStream(f));
  -                        }
  -                    }
  -                }
  -            }
  -            factoryClassName = cacheProps.getProperty(factoryId);            
  -
  -            if(factoryClassName != null){
  -                dPrint("found in $java.home/jaxp.properties, value=" + factoryClassName);
  -                return newInstance(factoryClassName, classLoader, true);
  -            }
  -        } catch(Exception ex ) {
  -            if( debug ) ex.printStackTrace();
  -        }
  -
  -        // Try Jar Service Provider Mechanism
  -        Object provider = findJarServiceProvider(factoryId);
  -        if (provider != null) {
  -            return provider;
  -        }
  -        if (fallbackClassName == null) {
  -            throw new ConfigurationError(
  -                "Provider for " + factoryId + " cannot be found", null);
  -        }
  -
  -        dPrint("loaded from fallback value: " + fallbackClassName);
  -        return newInstance(fallbackClassName, classLoader, true);
  -    }
  -    
  -    /*
  -     * Try to find provider using Jar Service Provider Mechanism
  -     *
  -     * @return instance of provider class if found or null
  -     */
  -    private static Object findJarServiceProvider(String factoryId)
  -        throws ConfigurationError
  -    {
  -
  -        String serviceId = "META-INF/services/" + factoryId;
  -        InputStream is = null;
  -
  -        // First try the Context ClassLoader
  -        ClassLoader cl = ss.getContextClassLoader();
  -        if (cl != null) {
  -            is = ss.getResourceAsStream(cl, serviceId);
  -
  -            // If no provider found then try the current ClassLoader
  -            if (is == null) {
  -                cl = FactoryFinder.class.getClassLoader();
  -                is = ss.getResourceAsStream(cl, serviceId);
  -            }
  -        } else {
  -            // No Context ClassLoader, try the current
  -            // ClassLoader
  -            cl = FactoryFinder.class.getClassLoader();
  -            is = ss.getResourceAsStream(cl, serviceId);
  -        }
  -
  -        if (is == null) {
  -            // No provider found
  -            return null;
  -        }
  -
  -        dPrint("found jar resource=" + serviceId +
  -               " using ClassLoader: " + cl);
  -
  -        // Read the service provider name in UTF-8 as specified in
  -        // the jar spec.  Unfortunately this fails in Microsoft
  -        // VJ++, which does not implement the UTF-8
  -        // encoding. Theoretically, we should simply let it fail in
  -        // that case, since the JVM is obviously broken if it
  -        // doesn't support such a basic standard.  But since there
  -        // are still some users attempting to use VJ++ for
  -        // development, we have dropped in a fallback which makes a
  -        // second attempt using the platform's default encoding. In
  -        // VJ++ this is apparently ASCII, which is a subset of
  -        // UTF-8... and since the strings we'll be reading here are
  -        // also primarily limited to the 7-bit ASCII range (at
  -        // least, in English versions), this should work well
  -        // enough to keep us on the air until we're ready to
  -        // officially decommit from VJ++. [Edited comment from
  -        // jkesselm]
  -        BufferedReader rd;
  -        try {
  -            rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
  -        } catch (java.io.UnsupportedEncodingException e) {
  -            rd = new BufferedReader(new InputStreamReader(is));
  -        }
  -        
  -        String factoryClassName = null;
  -        try {
  -            // XXX Does not handle all possible input as specified by the
  -            // Jar Service Provider specification
  -            factoryClassName = rd.readLine();
  -            rd.close();
  -        } catch (IOException x) {
  -            // No provider found
  -            return null;
  -        }
  -
  -        if (factoryClassName != null &&
  -            ! "".equals(factoryClassName)) {
  -            dPrint("found in resource, value="
  -                   + factoryClassName);
  -
  -        // Note: here we do not want to fall back to the current
  -        // ClassLoader because we want to avoid the case where the
  -        // resource file was found using one ClassLoader and the
  -        // provider class was instantiated using a different one.
  -        return newInstance(factoryClassName, cl, false);
  -        }
  -
  -        // No provider found
  -        return null;
  -    }
  -
  -    static class ConfigurationError extends Error {
  -        private Exception exception;
  -
  -        /**
  -         * Construct a new instance with the specified detail string and
  -         * exception.
  -         */
  -        ConfigurationError(String msg, Exception x) {
  -            super(msg);
  -            this.exception = x;
  -        }
  -
  -        Exception getException() {
  -            return exception;
  -        }
  -    }
  -
  -}
  +/*
  + * Copyright 2003-2005 The Apache Software Foundation.
  + *
  + * Licensed under the Apache License, Version 2.0 (the "License");
  + * you may not use this file except in compliance with the License.
  + * You may obtain a copy of the License at
  + *
  + *     http://www.apache.org/licenses/LICENSE-2.0
  + *
  + * Unless required by applicable law or agreed to in writing, software
  + * distributed under the License is distributed on an "AS IS" BASIS,
  + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  + * See the License for the specific language governing permissions and
  + * limitations under the License.
  + */
  +
  +// $Id$
  +
  +package javax.xml.transform;
  +
  +import java.io.File;
  +import java.io.FileInputStream;
  +
  +import java.util.Properties;
  +import java.io.BufferedReader;
  +import java.io.IOException;
  +import java.io.InputStream;
  +import java.io.InputStreamReader;
  +import java.net.URL;
  +
  +/**
  + * This class is duplicated for each JAXP subpackage so keep it in
  + * sync.  It is package private.
  + *
  + * This code is designed to implement the JAXP 1.1 spec pluggability
  + * feature and is designed to run on JDK version 1.1 and later including
  + * JVMs that perform early linking like the Microsoft JVM in IE 5.  Note
  + * however that it must be compiled on a JDK version 1.2 or later system
  + * since it calls Thread#getContextClassLoader().  The code also runs both
  + * as part of an unbundled jar file and when bundled as part of the JDK.
  + */
  +class FactoryFinder {
  +    /** Temp debug code - this will be removed after we test everything
  +     */
  +    private static boolean debug = false;
  +    static Properties cacheProps= new Properties();
  +    static SecuritySupport ss = new SecuritySupport() ;
  +    static boolean firstTime = true;
  +    
  +    /**
  +     * Default columns per line.
  +     */
  +    private static final int DEFAULT_LINE_LENGTH = 80;
  +
  +    // Define system property "jaxp.debug" to get output
  +    static {
  +        // Use try/catch block to support applets, which throws
  +        // SecurityException out of this code.
  +        try {
  +            String val = ss.getSystemProperty("jaxp.debug");
  +            // Allow simply setting the prop to turn on debug
  +            debug = val != null && (! "false".equals(val));
  +        } catch (SecurityException se) {
  +            debug = false;
  +        }
  +    }
  +    
  +
  +    private static void dPrint(String msg) {
  +        if (debug) {
  +            System.err.println("JAXP: " + msg);
  +        }
  +    }
  +    
  +    /**
  +     * Create an instance of a class using the specified ClassLoader and
  +     * optionally fall back to the current ClassLoader if not found.
  +     *
  +     * @param className Name of the concrete class corresponding to the
  +     * service provider
  +     *
  +     * @param cl ClassLoader to use to load the class, null means to use
  +     * the bootstrap ClassLoader
  +     *
  +     * @param doFallback true if the current ClassLoader should be tried as
  +     * a fallback if the class is not found using cl
  +     */
  +    private static Object newInstance(String className, ClassLoader cl,
  +                                      boolean doFallback)
  +        throws ConfigurationError
  +    {
  +        // assert(className != null);
  +
  +        try {
  +            Class providerClass;
  +            if (cl == null) {
  +                // If classloader is null Use the bootstrap ClassLoader.  
  +                // Thus Class.forName(String) will use the current
  +                // ClassLoader which will be the bootstrap ClassLoader.
  +                providerClass = Class.forName(className);
  +            } else {
  +                try {
  +                    providerClass = cl.loadClass(className);
  +                } catch (ClassNotFoundException x) {
  +                    if (doFallback) {
  +                        // Fall back to current classloader
  +                        cl = FactoryFinder.class.getClassLoader();
  +                        providerClass = cl.loadClass(className);
  +                    } else {
  +                        throw x;
  +                    }
  +                }
  +            }
  +                        
  +            Object instance = providerClass.newInstance();
  +            dPrint("created new instance of " + providerClass +
  +                   " using ClassLoader: " + cl);
  +            return instance;
  +        } catch (ClassNotFoundException x) {
  +            throw new ConfigurationError(
  +                "Provider " + className + " not found", x);
  +        } catch (Exception x) {
  +            throw new ConfigurationError(
  +                "Provider " + className + " could not be instantiated: " + x,
  +                x);
  +        }
  +    }
  +    
  +    /**
  +     * Finds the implementation Class object in the specified order.  Main
  +     * entry point.
  +     * @return Class object of factory, never null
  +     *
  +     * @param factoryId             Name of the factory to find, same as
  +     *                              a property name
  +     * @param fallbackClassName     Implementation class name, if nothing else
  +     *                              is found.  Use null to mean no fallback.
  +     *
  +     * Package private so this code can be shared.
  +     */
  +    static Object find(String factoryId, String fallbackClassName)
  +        throws ConfigurationError
  +    {        
  +
  +        // Figure out which ClassLoader to use for loading the provider
  +        // class.  If there is a Context ClassLoader then use it.
  +        
  +        ClassLoader classLoader = ss.getContextClassLoader();
  +        
  +        if (classLoader == null) {
  +            // if we have no Context ClassLoader
  +            // so use the current ClassLoader
  +            classLoader = FactoryFinder.class.getClassLoader();
  +        }
  +
  +        dPrint("find factoryId =" + factoryId);
  +        
  +        // Use the system property first
  +        try {
  +            String systemProp = ss.getSystemProperty(factoryId);
  +            if( systemProp!=null) {                
  +                dPrint("found system property, value=" + systemProp);
  +                return newInstance(systemProp, classLoader, true );
  +            }
  +        } catch (SecurityException se) {
  +            //if first option fails due to any reason we should try next option in the
  +            //look up algorithm.
  +        }
  +
  +        // try to read from $java.home/lib/jaxp.properties
  +        try {
  +            String javah = ss.getSystemProperty("java.home");
  +            String configFile = javah + File.separator +
  +                "lib" + File.separator + "jaxp.properties";
  +            String factoryClassName = null;
  +            if(firstTime){
  +                synchronized(cacheProps){
  +                    if(firstTime){
  +                        File f=new File( configFile );
  +                        firstTime = false;
  +                        if(ss.doesFileExist(f)){
  +                            dPrint("Read properties file "+f);
  +                            //cacheProps.load( new FileInputStream(f));
  +                            cacheProps.load(ss.getFileInputStream(f));
  +                        }
  +                    }
  +                }
  +            }
  +            factoryClassName = cacheProps.getProperty(factoryId);            
  +
  +            if(factoryClassName != null){
  +                dPrint("found in $java.home/jaxp.properties, value=" + factoryClassName);
  +                return newInstance(factoryClassName, classLoader, true);
  +            }
  +        } catch(Exception ex ) {
  +            if( debug ) ex.printStackTrace();
  +        }
  +
  +        // Try Jar Service Provider Mechanism
  +        Object provider = findJarServiceProvider(factoryId);
  +        if (provider != null) {
  +            return provider;
  +        }
  +        if (fallbackClassName == null) {
  +            throw new ConfigurationError(
  +                "Provider for " + factoryId + " cannot be found", null);
  +        }
  +
  +        dPrint("loaded from fallback value: " + fallbackClassName);
  +        return newInstance(fallbackClassName, classLoader, true);
  +    }
  +    
  +    /*
  +     * Try to find provider using Jar Service Provider Mechanism
  +     *
  +     * @return instance of provider class if found or null
  +     */
  +    private static Object findJarServiceProvider(String factoryId)
  +        throws ConfigurationError
  +    {
  +
  +        String serviceId = "META-INF/services/" + factoryId;
  +        InputStream is = null;
  +
  +        // First try the Context ClassLoader
  +        ClassLoader cl = ss.getContextClassLoader();
  +        if (cl != null) {
  +            is = ss.getResourceAsStream(cl, serviceId);
  +
  +            // If no provider found then try the current ClassLoader
  +            if (is == null) {
  +                cl = FactoryFinder.class.getClassLoader();
  +                is = ss.getResourceAsStream(cl, serviceId);
  +            }
  +        } else {
  +            // No Context ClassLoader, try the current
  +            // ClassLoader
  +            cl = FactoryFinder.class.getClassLoader();
  +            is = ss.getResourceAsStream(cl, serviceId);
  +        }
  +
  +        if (is == null) {
  +            // No provider found
  +            return null;
  +        }
  +
  +        dPrint("found jar resource=" + serviceId +
  +               " using ClassLoader: " + cl);
  +
  +        // Read the service provider name in UTF-8 as specified in
  +        // the jar spec.  Unfortunately this fails in Microsoft
  +        // VJ++, which does not implement the UTF-8
  +        // encoding. Theoretically, we should simply let it fail in
  +        // that case, since the JVM is obviously broken if it
  +        // doesn't support such a basic standard.  But since there
  +        // are still some users attempting to use VJ++ for
  +        // development, we have dropped in a fallback which makes a
  +        // second attempt using the platform's default encoding. In
  +        // VJ++ this is apparently ASCII, which is a subset of
  +        // UTF-8... and since the strings we'll be reading here are
  +        // also primarily limited to the 7-bit ASCII range (at
  +        // least, in English versions), this should work well
  +        // enough to keep us on the air until we're ready to
  +        // officially decommit from VJ++. [Edited comment from
  +        // jkesselm]
  +        BufferedReader rd;
  +        try {
  +            rd = new BufferedReader(new InputStreamReader(is, "UTF-8"), DEFAULT_LINE_LENGTH);
  +        } catch (java.io.UnsupportedEncodingException e) {
  +            rd = new BufferedReader(new InputStreamReader(is), DEFAULT_LINE_LENGTH);
  +        }
  +        
  +        String factoryClassName = null;
  +        try {
  +            // XXX Does not handle all possible input as specified by the
  +            // Jar Service Provider specification
  +            factoryClassName = rd.readLine();
  +            rd.close();
  +        } catch (IOException x) {
  +            // No provider found
  +            return null;
  +        }
  +
  +        if (factoryClassName != null &&
  +            ! "".equals(factoryClassName)) {
  +            dPrint("found in resource, value="
  +                   + factoryClassName);
  +
  +        // Note: here we do not want to fall back to the current
  +        // ClassLoader because we want to avoid the case where the
  +        // resource file was found using one ClassLoader and the
  +        // provider class was instantiated using a different one.
  +        return newInstance(factoryClassName, cl, false);
  +        }
  +
  +        // No provider found
  +        return null;
  +    }
  +
  +    static class ConfigurationError extends Error {
  +        private Exception exception;
  +
  +        /**
  +         * Construct a new instance with the specified detail string and
  +         * exception.
  +         */
  +        ConfigurationError(String msg, Exception x) {
  +            super(msg);
  +            this.exception = x;
  +        }
  +
  +        Exception getException() {
  +            return exception;
  +        }
  +    }
  +
  +}
  
  
  
  1.2       +410 -405  xml-commons/java/external/src/javax/xml/datatype/FactoryFinder.java
  
  Index: FactoryFinder.java
  ===================================================================
  RCS file: /home/cvs/xml-commons/java/external/src/javax/xml/datatype/FactoryFinder.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- FactoryFinder.java	11 Apr 2005 07:49:39 -0000	1.1
  +++ FactoryFinder.java	17 Jun 2005 19:26:53 -0000	1.2
  @@ -1,405 +1,410 @@
  -/*
  - * Copyright 2003-2004 The Apache Software Foundation.
  - *
  - * Licensed under the Apache License, Version 2.0 (the "License");
  - * you may not use this file except in compliance with the License.
  - * You may obtain a copy of the License at
  - *
  - *     http://www.apache.org/licenses/LICENSE-2.0
  - *
  - * Unless required by applicable law or agreed to in writing, software
  - * distributed under the License is distributed on an "AS IS" BASIS,
  - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  - * See the License for the specific language governing permissions and
  - * limitations under the License.
  - */
  -
  -// $Id$
  -
  -package javax.xml.datatype;
  -
  -import java.io.File;
  -import java.io.FileInputStream;
  -import java.io.IOException;
  -import java.io.InputStream;
  -
  -import java.util.Properties;
  -import java.io.BufferedReader;
  -import java.io.InputStreamReader;
  -import java.net.URL;
  -
  -/**
  - * <p>Implement pluggabile Datatypes.</p>
  - * 
  - * <p>This class is duplicated for each JAXP subpackage so keep it in
  - * sync.  It is package private for secure class loading.</p>
  - *
  - * @author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a>
  - * @version $Revision$, $Date$
  - * @since 1.5
  - */
  -class FactoryFinder {
  -	
  -	/**
  -	 * <p>Name of class to display in output messages.</p>
  -	 */
  -	private static final String CLASS_NAME = "javax.xml.datatype.FactoryFinder";
  -	
  -    /**
  -     * <p>Debug flag to trace loading process.</p>
  -     */
  -    private static boolean debug = false;
  -    
  -    /**
  -     * <p>Cache properties for performance.</p>
  -     */
  -	private static Properties cacheProps = new Properties();
  -	
  -	/**
  -	 * <p>First time requires initialization overhead.</p>
  -	 */
  -	private static boolean firstTime = true;
  -    
  -    /**
  -     *<p> Take care of restrictions imposed by java security model </p>
  -     */
  -    private static SecuritySupport ss = new SecuritySupport();
  -	
  -	/**
  -	 * <p>Check to see if debugging enabled by property.</p>
  -	 * 
  -	 * <p>Use try/catch block to support applets, which throws
  -     * SecurityException out of this code.</p>
  -	 * 
  -	 */
  -    static {
  -        try {
  -            debug = ss.getSystemProperty("jaxp.debug") != null;
  -        } catch (Exception x) {
  -        	; // NOP, ignore exception
  -        }
  -    }
  -
  -	/**
  -	 * <p>Output debugging messages.</p>
  -	 * 
  -	 * @param msg <code>String</code> to print to <code>stderr</code>.
  -	 */
  -    private static void debugPrintln(String msg) {
  -        if (debug) {
  -            System.err.println(
  -            	CLASS_NAME
  -            	+ ":"
  -            	+ msg);
  -        }
  -    }
  -
  -    /**
  -     * <p>Find the appropriate <code>ClassLoader</code> to use.</p>
  -     * 
  -     * <p>The context ClassLoader is prefered.</p>
  -     * 
  -     * @return <code>ClassLoader</code> to use.
  -     * 
  -     * @throws ConfigurationError If a valid <code>ClassLoader</code> cannot be identified. 
  -     */
  -    private static ClassLoader findClassLoader()
  -        throws ConfigurationError {
  -        ClassLoader classLoader;
  -
  -        // Figure out which ClassLoader to use for loading the provider
  -        // class.  If there is a Context ClassLoader then use it.
  -
  -        classLoader = ss.getContextClassLoader();            
  -
  -        debugPrintln(
  -            "Using context class loader: "
  -            + classLoader);
  -
  -        if (classLoader == null) {
  -            // if we have no Context ClassLoader
  -            // so use the current ClassLoader
  -            classLoader = FactoryFinder.class.getClassLoader();
  -            debugPrintln(
  -                "Using the class loader of FactoryFinder: "
  -                + classLoader);                
  -        }
  -                    
  -        return classLoader;
  -    }
  -
  -    /**
  -     * <p>Create an instance of a class using the specified ClassLoader.</p>
  -     * 
  -     * @param className Name of class to create.
  -     * @param classLoader ClassLoader to use to create named class.
  -     * 
  -     * @return New instance of specified class created using the specified ClassLoader.
  -     * 
  -     * @throws ConfigurationError If class could not be created.
  -     */
  -    private static Object newInstance(
  -    	String className,
  -        ClassLoader classLoader)
  -        throws ConfigurationError {
  -        	
  -        try {
  -            Class spiClass;
  -            if (classLoader == null) {
  -                spiClass = Class.forName(className);
  -            } else {
  -                spiClass = classLoader.loadClass(className);
  -            }
  -            
  -            if (debug) {
  -            	debugPrintln("Loaded " + className + " from " + which(spiClass));
  -            }
  -             
  -            return spiClass.newInstance();
  -        } catch (ClassNotFoundException x) {
  -            throw new ConfigurationError(
  -                "Provider " + className + " not found", x);
  -        } catch (Exception x) {
  -            throw new ConfigurationError(
  -                "Provider " + className + " could not be instantiated: " + x,
  -                x);
  -        }
  -    }
  -
  -    /**
  -     * Finds the implementation Class object in the specified order.  Main
  -     * entry point.
  -     * Package private so this code can be shared.
  -     *
  -     * @param factoryId Name of the factory to find, same as a property name
  -     * @param fallbackClassName Implementation class name, if nothing else is found.  Use null to mean no fallback.
  -     *
  -     * @return Class Object of factory, never null
  -     * 
  -     * @throws ConfigurationError If Class cannot be found.
  -     */
  -    static Object find(String factoryId, String fallbackClassName)
  -        throws ConfigurationError {
  -        	
  -        ClassLoader classLoader = findClassLoader();
  -
  -        // Use the system property first
  -        try {
  -            String systemProp = ss.getSystemProperty(factoryId);
  -            if (systemProp != null) {
  -                debugPrintln("found " + systemProp + " in the system property " + factoryId);
  -                return newInstance(systemProp, classLoader);
  -            }
  -        } catch (SecurityException se) {
  -        	; // NOP, explicitly ignore SecurityException
  -        }
  -
  -        // try to read from $java.home/lib/jaxp.properties
  -        try {
  -            String javah = ss.getSystemProperty("java.home");
  -            String configFile = javah + File.separator + "lib" + File.separator + "jaxp.properties";
  -			String factoryClassName = null;
  -			if (firstTime) {
  -				synchronized (cacheProps) {
  -					if (firstTime) {
  -						File f = new File(configFile);
  -						firstTime = false;
  -						if (ss.doesFileExist(f)) {
  -							debugPrintln("Read properties file " + f);
  -							cacheProps.load(ss.getFileInputStream(f));
  -						}
  -					}
  -				}
  -			}
  -			factoryClassName = cacheProps.getProperty(factoryId);
  -            debugPrintln("found " + factoryClassName + " in $java.home/jaxp.properties"); 
  -			
  -			if (factoryClassName != null) {
  -				return newInstance(factoryClassName, classLoader);
  -			}
  -        } catch (Exception ex) {
  -            if (debug) {
  -            	ex.printStackTrace();
  -            } 
  -        }
  -        
  -        // Try Jar Service Provider Mechanism
  -        Object provider = findJarServiceProvider(factoryId);
  -        if (provider != null) {
  -            return provider;
  -        }
  -
  -        if (fallbackClassName == null) {
  -            throw new ConfigurationError(
  -                "Provider for " + factoryId + " cannot be found", null);
  -        }
  -
  -        debugPrintln("loaded from fallback value: " + fallbackClassName);
  -        return newInstance(fallbackClassName, classLoader);
  -    }
  -
  -    /*
  -     * Try to find provider using Jar Service Provider Mechanism
  -     *
  -     * @return instance of provider class if found or null
  -     */
  -    private static Object findJarServiceProvider(String factoryId)
  -        throws ConfigurationError
  -    {
  -
  -        String serviceId = "META-INF/services/" + factoryId;
  -        InputStream is = null;
  -
  -        // First try the Context ClassLoader
  -        ClassLoader cl = ss.getContextClassLoader();
  -        if (cl != null) {
  -            is = ss.getResourceAsStream(cl, serviceId);
  -
  -            // If no provider found then try the current ClassLoader
  -            if (is == null) {
  -                cl = FactoryFinder.class.getClassLoader();
  -                is = ss.getResourceAsStream(cl, serviceId);
  -            }
  -        } else {
  -            // No Context ClassLoader, try the current
  -            // ClassLoader
  -            cl = FactoryFinder.class.getClassLoader();
  -            is = ss.getResourceAsStream(cl, serviceId);
  -        }
  -
  -        if (is == null) {
  -            // No provider found
  -            return null;
  -        }
  -
  -        debugPrintln("found jar resource=" + serviceId +
  -               " using ClassLoader: " + cl);
  -
  -        BufferedReader rd;
  -        try {
  -            rd = new BufferedReader(new InputStreamReader(is, "UTF-8"));
  -        } catch (java.io.UnsupportedEncodingException e) {
  -            rd = new BufferedReader(new InputStreamReader(is));
  -        }
  -        
  -        String factoryClassName = null;
  -        try {
  -            // XXX Does not handle all possible input as specified by the
  -            // Jar Service Provider specification
  -            factoryClassName = rd.readLine();
  -            rd.close();
  -        } catch (IOException x) {
  -            // No provider found
  -            return null;
  -        }
  -
  -        if (factoryClassName != null &&
  -            ! "".equals(factoryClassName)) {
  -            debugPrintln("found in resource, value="
  -                   + factoryClassName);
  -
  -            return newInstance(factoryClassName, cl);
  -        }
  -
  -        // No provider found
  -        return null;
  -    }
  -    
  -	/**
  -	 * <p>Configuration Error.</p>
  -	 */
  -    static class ConfigurationError extends Error {
  -    	
  -    	/**
  -    	 * <p>Exception that caused the error.</p>
  -    	 */
  -        private Exception exception;
  -
  -        /**
  -         * <p>Construct a new instance with the specified detail string and
  -         * exception.</p>
  -         * 
  -         * @param msg Detail message for this error.
  -         * @param x Exception that caused the error.
  -         */
  -        ConfigurationError(String msg, Exception x) {
  -            super(msg);
  -            this.exception = x;
  -        }
  -
  -		/**
  -		 * <p>Get the Exception that caused the error.</p>
  -		 * 
  -		 * @return Exception that caused the error.
  -		 */
  -        Exception getException() {
  -            return exception;
  -        }
  -    }
  -
  -
  -
  -    /**
  -     * Returns the location where the given Class is loaded from.
  -     * 
  -     * @param clazz Class to find load location.
  -     * 
  -     * @return Location where class would be loaded from.
  -     */
  -    private static String which(Class clazz) {
  -        try {
  -            String classnameAsResource = clazz.getName().replace('.', '/') + ".class";
  -    
  -            ClassLoader loader = clazz.getClassLoader();
  -            
  -            URL it;
  -    
  -            if (loader != null) {
  -            	it = loader.getResource(classnameAsResource);
  -            } else {
  -            	it = ClassLoader.getSystemResource(classnameAsResource);
  -            } 
  -    
  -            if (it != null) {
  -            	return it.toString();
  -            } 
  -        } catch (Throwable t) {
  -            // work defensively.
  -            if (debug) {
  -            	t.printStackTrace();
  -            } 
  -        }
  -        return "unknown location";
  -    }
  -
  -
  -
  -    /**
  -     * The following nested classes allow getContextClassLoader() to be
  -     * called only on JDK 1.2 and yet run in older JDK 1.1 JVMs
  -     */
  -    private abstract static class ClassLoaderFinder {
  -    	
  -    	/**
  -    	 * <p>Get Context Class loader.</p>
  -    	 * 
  -    	 * @return Context class loader.
  -    	 */
  -        abstract ClassLoader getContextClassLoader();
  -    }
  -
  -	/**
  -	 * <p>Actual ClassLoader finder implementation.</p>
  -	 */
  -    static class ClassLoaderFinderConcrete extends ClassLoaderFinder {
  -    	
  -    	/**
  -    	 * <p>Get Context Class loader.</p>
  -    	 * 
  -    	 * @return Context class loader.
  -    	 */
  -        ClassLoader getContextClassLoader() {
  -            return Thread.currentThread().getContextClassLoader();
  -        }
  -    }
  -}
  +/*
  + * Copyright 2003-2005 The Apache Software Foundation.
  + *
  + * Licensed under the Apache License, Version 2.0 (the "License");
  + * you may not use this file except in compliance with the License.
  + * You may obtain a copy of the License at
  + *
  + *     http://www.apache.org/licenses/LICENSE-2.0
  + *
  + * Unless required by applicable law or agreed to in writing, software
  + * distributed under the License is distributed on an "AS IS" BASIS,
  + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  + * See the License for the specific language governing permissions and
  + * limitations under the License.
  + */
  +
  +// $Id$
  +
  +package javax.xml.datatype;
  +
  +import java.io.File;
  +import java.io.FileInputStream;
  +import java.io.IOException;
  +import java.io.InputStream;
  +
  +import java.util.Properties;
  +import java.io.BufferedReader;
  +import java.io.InputStreamReader;
  +import java.net.URL;
  +
  +/**
  + * <p>Implement pluggabile Datatypes.</p>
  + * 
  + * <p>This class is duplicated for each JAXP subpackage so keep it in
  + * sync.  It is package private for secure class loading.</p>
  + *
  + * @author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a>
  + * @version $Revision$, $Date$
  + * @since 1.5
  + */
  +class FactoryFinder {
  +	
  +	/**
  +	 * <p>Name of class to display in output messages.</p>
  +	 */
  +	private static final String CLASS_NAME = "javax.xml.datatype.FactoryFinder";
  +	
  +    /**
  +     * <p>Debug flag to trace loading process.</p>
  +     */
  +    private static boolean debug = false;
  +    
  +    /**
  +     * <p>Cache properties for performance.</p>
  +     */
  +	private static Properties cacheProps = new Properties();
  +	
  +	/**
  +	 * <p>First time requires initialization overhead.</p>
  +	 */
  +	private static boolean firstTime = true;
  +    
  +    /**
  +     *<p> Take care of restrictions imposed by java security model </p>
  +     */
  +    private static SecuritySupport ss = new SecuritySupport();
  +    
  +    /**
  +     * Default columns per line.
  +     */
  +    private static final int DEFAULT_LINE_LENGTH = 80;
  +	
  +	/**
  +	 * <p>Check to see if debugging enabled by property.</p>
  +	 * 
  +	 * <p>Use try/catch block to support applets, which throws
  +     * SecurityException out of this code.</p>
  +	 * 
  +	 */
  +    static {
  +        try {
  +            debug = ss.getSystemProperty("jaxp.debug") != null;
  +        } catch (Exception x) {
  +        	; // NOP, ignore exception
  +        }
  +    }
  +
  +	/**
  +	 * <p>Output debugging messages.</p>
  +	 * 
  +	 * @param msg <code>String</code> to print to <code>stderr</code>.
  +	 */
  +    private static void debugPrintln(String msg) {
  +        if (debug) {
  +            System.err.println(
  +            	CLASS_NAME
  +            	+ ":"
  +            	+ msg);
  +        }
  +    }
  +
  +    /**
  +     * <p>Find the appropriate <code>ClassLoader</code> to use.</p>
  +     * 
  +     * <p>The context ClassLoader is prefered.</p>
  +     * 
  +     * @return <code>ClassLoader</code> to use.
  +     * 
  +     * @throws ConfigurationError If a valid <code>ClassLoader</code> cannot be identified. 
  +     */
  +    private static ClassLoader findClassLoader()
  +        throws ConfigurationError {
  +        ClassLoader classLoader;
  +
  +        // Figure out which ClassLoader to use for loading the provider
  +        // class.  If there is a Context ClassLoader then use it.
  +
  +        classLoader = ss.getContextClassLoader();            
  +
  +        debugPrintln(
  +            "Using context class loader: "
  +            + classLoader);
  +
  +        if (classLoader == null) {
  +            // if we have no Context ClassLoader
  +            // so use the current ClassLoader
  +            classLoader = FactoryFinder.class.getClassLoader();
  +            debugPrintln(
  +                "Using the class loader of FactoryFinder: "
  +                + classLoader);                
  +        }
  +                    
  +        return classLoader;
  +    }
  +
  +    /**
  +     * <p>Create an instance of a class using the specified ClassLoader.</p>
  +     * 
  +     * @param className Name of class to create.
  +     * @param classLoader ClassLoader to use to create named class.
  +     * 
  +     * @return New instance of specified class created using the specified ClassLoader.
  +     * 
  +     * @throws ConfigurationError If class could not be created.
  +     */
  +    private static Object newInstance(
  +    	String className,
  +        ClassLoader classLoader)
  +        throws ConfigurationError {
  +        	
  +        try {
  +            Class spiClass;
  +            if (classLoader == null) {
  +                spiClass = Class.forName(className);
  +            } else {
  +                spiClass = classLoader.loadClass(className);
  +            }
  +            
  +            if (debug) {
  +            	debugPrintln("Loaded " + className + " from " + which(spiClass));
  +            }
  +             
  +            return spiClass.newInstance();
  +        } catch (ClassNotFoundException x) {
  +            throw new ConfigurationError(
  +                "Provider " + className + " not found", x);
  +        } catch (Exception x) {
  +            throw new ConfigurationError(
  +                "Provider " + className + " could not be instantiated: " + x,
  +                x);
  +        }
  +    }
  +
  +    /**
  +     * Finds the implementation Class object in the specified order.  Main
  +     * entry point.
  +     * Package private so this code can be shared.
  +     *
  +     * @param factoryId Name of the factory to find, same as a property name
  +     * @param fallbackClassName Implementation class name, if nothing else is found.  Use null to mean no fallback.
  +     *
  +     * @return Class Object of factory, never null
  +     * 
  +     * @throws ConfigurationError If Class cannot be found.
  +     */
  +    static Object find(String factoryId, String fallbackClassName)
  +        throws ConfigurationError {
  +        	
  +        ClassLoader classLoader = findClassLoader();
  +
  +        // Use the system property first
  +        try {
  +            String systemProp = ss.getSystemProperty(factoryId);
  +            if (systemProp != null) {
  +                debugPrintln("found " + systemProp + " in the system property " + factoryId);
  +                return newInstance(systemProp, classLoader);
  +            }
  +        } catch (SecurityException se) {
  +        	; // NOP, explicitly ignore SecurityException
  +        }
  +
  +        // try to read from $java.home/lib/jaxp.properties
  +        try {
  +            String javah = ss.getSystemProperty("java.home");
  +            String configFile = javah + File.separator + "lib" + File.separator + "jaxp.properties";
  +			String factoryClassName = null;
  +			if (firstTime) {
  +				synchronized (cacheProps) {
  +					if (firstTime) {
  +						File f = new File(configFile);
  +						firstTime = false;
  +						if (ss.doesFileExist(f)) {
  +							debugPrintln("Read properties file " + f);
  +							cacheProps.load(ss.getFileInputStream(f));
  +						}
  +					}
  +				}
  +			}
  +			factoryClassName = cacheProps.getProperty(factoryId);
  +            debugPrintln("found " + factoryClassName + " in $java.home/jaxp.properties"); 
  +			
  +			if (factoryClassName != null) {
  +				return newInstance(factoryClassName, classLoader);
  +			}
  +        } catch (Exception ex) {
  +            if (debug) {
  +            	ex.printStackTrace();
  +            } 
  +        }
  +        
  +        // Try Jar Service Provider Mechanism
  +        Object provider = findJarServiceProvider(factoryId);
  +        if (provider != null) {
  +            return provider;
  +        }
  +
  +        if (fallbackClassName == null) {
  +            throw new ConfigurationError(
  +                "Provider for " + factoryId + " cannot be found", null);
  +        }
  +
  +        debugPrintln("loaded from fallback value: " + fallbackClassName);
  +        return newInstance(fallbackClassName, classLoader);
  +    }
  +
  +    /*
  +     * Try to find provider using Jar Service Provider Mechanism
  +     *
  +     * @return instance of provider class if found or null
  +     */
  +    private static Object findJarServiceProvider(String factoryId)
  +        throws ConfigurationError
  +    {
  +
  +        String serviceId = "META-INF/services/" + factoryId;
  +        InputStream is = null;
  +
  +        // First try the Context ClassLoader
  +        ClassLoader cl = ss.getContextClassLoader();
  +        if (cl != null) {
  +            is = ss.getResourceAsStream(cl, serviceId);
  +
  +            // If no provider found then try the current ClassLoader
  +            if (is == null) {
  +                cl = FactoryFinder.class.getClassLoader();
  +                is = ss.getResourceAsStream(cl, serviceId);
  +            }
  +        } else {
  +            // No Context ClassLoader, try the current
  +            // ClassLoader
  +            cl = FactoryFinder.class.getClassLoader();
  +            is = ss.getResourceAsStream(cl, serviceId);
  +        }
  +
  +        if (is == null) {
  +            // No provider found
  +            return null;
  +        }
  +
  +        debugPrintln("found jar resource=" + serviceId +
  +               " using ClassLoader: " + cl);
  +
  +        BufferedReader rd;
  +        try {
  +            rd = new BufferedReader(new InputStreamReader(is, "UTF-8"), DEFAULT_LINE_LENGTH);
  +        } catch (java.io.UnsupportedEncodingException e) {
  +            rd = new BufferedReader(new InputStreamReader(is), DEFAULT_LINE_LENGTH);
  +        }
  +        
  +        String factoryClassName = null;
  +        try {
  +            // XXX Does not handle all possible input as specified by the
  +            // Jar Service Provider specification
  +            factoryClassName = rd.readLine();
  +            rd.close();
  +        } catch (IOException x) {
  +            // No provider found
  +            return null;
  +        }
  +
  +        if (factoryClassName != null &&
  +            ! "".equals(factoryClassName)) {
  +            debugPrintln("found in resource, value="
  +                   + factoryClassName);
  +
  +            return newInstance(factoryClassName, cl);
  +        }
  +
  +        // No provider found
  +        return null;
  +    }
  +    
  +	/**
  +	 * <p>Configuration Error.</p>
  +	 */
  +    static class ConfigurationError extends Error {
  +    	
  +    	/**
  +    	 * <p>Exception that caused the error.</p>
  +    	 */
  +        private Exception exception;
  +
  +        /**
  +         * <p>Construct a new instance with the specified detail string and
  +         * exception.</p>
  +         * 
  +         * @param msg Detail message for this error.
  +         * @param x Exception that caused the error.
  +         */
  +        ConfigurationError(String msg, Exception x) {
  +            super(msg);
  +            this.exception = x;
  +        }
  +
  +		/**
  +		 * <p>Get the Exception that caused the error.</p>
  +		 * 
  +		 * @return Exception that caused the error.
  +		 */
  +        Exception getException() {
  +            return exception;
  +        }
  +    }
  +
  +
  +
  +    /**
  +     * Returns the location where the given Class is loaded from.
  +     * 
  +     * @param clazz Class to find load location.
  +     * 
  +     * @return Location where class would be loaded from.
  +     */
  +    private static String which(Class clazz) {
  +        try {
  +            String classnameAsResource = clazz.getName().replace('.', '/') + ".class";
  +    
  +            ClassLoader loader = clazz.getClassLoader();
  +            
  +            URL it;
  +    
  +            if (loader != null) {
  +            	it = loader.getResource(classnameAsResource);
  +            } else {
  +            	it = ClassLoader.getSystemResource(classnameAsResource);
  +            } 
  +    
  +            if (it != null) {
  +            	return it.toString();
  +            } 
  +        } catch (Throwable t) {
  +            // work defensively.
  +            if (debug) {
  +            	t.printStackTrace();
  +            } 
  +        }
  +        return "unknown location";
  +    }
  +
  +
  +
  +    /**
  +     * The following nested classes allow getContextClassLoader() to be
  +     * called only on JDK 1.2 and yet run in older JDK 1.1 JVMs
  +     */
  +    private abstract static class ClassLoaderFinder {
  +    	
  +    	/**
  +    	 * <p>Get Context Class loader.</p>
  +    	 * 
  +    	 * @return Context class loader.
  +    	 */
  +        abstract ClassLoader getContextClassLoader();
  +    }
  +
  +	/**
  +	 * <p>Actual ClassLoader finder implementation.</p>
  +	 */
  +    static class ClassLoaderFinderConcrete extends ClassLoaderFinder {
  +    	
  +    	/**
  +    	 * <p>Get Context Class loader.</p>
  +    	 * 
  +    	 * @return Context class loader.
  +    	 */
  +        ClassLoader getContextClassLoader() {
  +            return Thread.currentThread().getContextClassLoader();
  +        }
  +    }
  +}