FileDocCategorySizeDatePackage
SchemaFactoryFinder.javaAPI DocJava SE 6 API19585Tue Jun 10 00:27:14 BST 2008javax.xml.validation

SchemaFactoryFinder

public class SchemaFactoryFinder extends Object
Implementation of {@link SchemaFactory#newInstance(String)}.
author
Kohsuke Kawaguchi
version
$Revision: 1.5 $, $Date: 2005/10/06 05:39:24 $
since
1.5

Fields Summary
private static boolean
debug
debug support code.
private static SecuritySupport
ss

Take care of restrictions imposed by java security model

private static Properties
cacheProps

Cache properties for performance.

private static boolean
firstTime

First time requires initialization overhead.

private final ClassLoader
classLoader

ClassLoader to use to find SchemaFactory.

private static final Class
SERVICE_CLASS
private static final String
SERVICE_ID
Constructors Summary
public SchemaFactoryFinder(ClassLoader loader)

Constructor that specifies ClassLoader to use to find SchemaFactory.

param
loader to be used to load resource, {@link SchemaFactory}, and {@link SchemaFactoryLoader} implementations during the resolution process. If this parameter is null, the default system class loader will be used.

        this.classLoader = loader;
        if( debug ) {
            debugDisplayClassLoader();
        }
    
Methods Summary
private javax.xml.validation.SchemaFactory_newFactory(java.lang.String schemaLanguage)

Lookup a SchemaFactory for the given schemaLanguage.

param
schemaLanguage Schema language to lookup SchemaFactory for.
return
SchemaFactory for the given schemaLanguage.

        SchemaFactory sf;
        
        String propertyName = SERVICE_CLASS.getName() + ":" + schemaLanguage;
        
        // system property look up
        try {
            debugPrintln("Looking up system property '"+propertyName+"'" );
            String r = ss.getSystemProperty(propertyName);
            if(r!=null) {
                debugPrintln("The value is '"+r+"'");
                sf = createInstance(r);
                if(sf!=null)    return sf;
            } else
                debugPrintln("The property is undefined.");
        } catch( Throwable t ) {
            if( debug ) {
                debugPrintln("failed to look up system property '"+propertyName+"'" );
                t.printStackTrace();
            }
        }

        String javah = ss.getSystemProperty( "java.home" );
        String configFile = javah + File.separator +
        "lib" + File.separator + "jaxp.properties";

        String factoryClassName = null ;

        // try to read from $java.home/lib/jaxp.properties
        try {
            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(propertyName);            
            debugPrintln("found " + factoryClassName + " in $java.home/jaxp.properties"); 

            if (factoryClassName != null) {
                sf = createInstance(factoryClassName);
                if(sf != null){
                    return sf;
                }
            }
        } catch (Exception ex) {
            if (debug) {
                ex.printStackTrace();
            } 
        }

        /**
        // 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";
            File f = new File( configFile );
            if( ss.doesFileExist(f)) {
                sf = loadFromProperty(
                        propertyName,f.getAbsolutePath(), new FileInputStream(f));
                if(sf!=null)    return sf;
            } else {
                debugPrintln("Tried to read "+ f.getAbsolutePath()+", but it doesn't exist.");
            }
        } catch(Throwable e) {
            if( debug ) {
                debugPrintln("failed to read $java.home/lib/jaxp.properties");
                e.printStackTrace();
            }
        }
         */
        
        // try META-INF/services files
        Iterator sitr = createServiceFileIterator();
        while(sitr.hasNext()) {
            URL resource = (URL)sitr.next();
            debugPrintln("looking into " + resource);
            try {
                sf = loadFromService(schemaLanguage,resource.toExternalForm(),
						ss.getURLInputStream(resource));
                if(sf!=null)    return sf;
            } catch(IOException e) {
                if( debug ) {
                    debugPrintln("failed to read "+resource);
                    e.printStackTrace();
                }
            }
        }
        
        // platform default
        if(schemaLanguage.equals("http://www.w3.org/2001/XMLSchema")) {
            debugPrintln("attempting to use the platform default XML Schema validator");
            return createInstance("com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory");
        }
        
        debugPrintln("all things were tried, but none was found. bailing out.");
        return null;
    
private java.lang.ClasscreateClass(java.lang.String className)

Create class using appropriate ClassLoader.

param
className Name of class to create.
return
Created class or null.

            Class clazz;

            // use approprite ClassLoader
            try {
                    if (classLoader != null) {
                            clazz = classLoader.loadClass(className);
                    } else {
                            clazz = Class.forName(className);
                    }
            } catch (Throwable t) {
                if(debug)   t.printStackTrace();
                    return null;
            }

            return clazz;
    
javax.xml.validation.SchemaFactorycreateInstance(java.lang.String className)

Creates an instance of the specified and returns it.

param
className fully qualified class name to be instanciated.
return
null if it fails. Error messages will be printed by this method.

        SchemaFactory schemaFactory = null;
		
        debugPrintln("createInstance(" + className + ")");

        // get Class from className		
        Class clazz = createClass(className);
        if (clazz == null) {
                debugPrintln("failed to getClass(" + className + ")");
                return null;	
        }
        debugPrintln("loaded " + className + " from " + which(clazz));

        // instantiate Class as a SchemaFactory
        try {
                schemaFactory = (SchemaFactory) clazz.newInstance();
        } catch (ClassCastException classCastException) {
                debugPrintln("could not instantiate " + clazz.getName());
                if (debug) {
                        classCastException.printStackTrace();
                }
                return null;
        } catch (IllegalAccessException illegalAccessException) {
                debugPrintln("could not instantiate " + clazz.getName());
                if (debug) {
                        illegalAccessException.printStackTrace();
                }
                return null;
        } catch (InstantiationException instantiationException) {
                debugPrintln("could not instantiate " + clazz.getName());
                if (debug) {
                        instantiationException.printStackTrace();
                }
                return null;
        }

        return schemaFactory;
    
private java.util.IteratorcreateServiceFileIterator()
Returns an {@link Iterator} that enumerates all the META-INF/services files that we care.

        if (classLoader == null) {
            return new SingleIterator() {
                protected Object value() {
                    ClassLoader classLoader = SchemaFactoryFinder.class.getClassLoader();
                    //return (ClassLoader.getSystemResource( SERVICE_ID ));
                    return ss.getResourceAsURL(classLoader, SERVICE_ID);
                }
            };
        } else {
            try {
                //final Enumeration e = classLoader.getResources(SERVICE_ID);
                final Enumeration e = ss.getResources(classLoader, SERVICE_ID);
                if(!e.hasMoreElements()) {
                    debugPrintln("no "+SERVICE_ID+" file was found");
                }
                
                // wrap it into an Iterator.
                return new Iterator() {
                    public void remove() {
                        throw new UnsupportedOperationException();
                    }

                    public boolean hasNext() {
                        return e.hasMoreElements();
                    }

                    public Object next() {
                        return e.nextElement();
                    }
                };
            } catch (IOException e) {
                debugPrintln("failed to enumerate resources "+SERVICE_ID);
                if(debug)   e.printStackTrace();
                return new ArrayList().iterator();  // empty iterator
            }
        }
    
private voiddebugDisplayClassLoader()

        try {
            if( classLoader == ss.getContextClassLoader() ) {
                debugPrintln("using thread context class loader ("+classLoader+") for search");
                return;
            }
        } catch( Throwable _ ) {
            ; // getContextClassLoader() undefined in JDK1.1 
        }
        
        if( classLoader==ClassLoader.getSystemClassLoader() ) {
            debugPrintln("using system class loader ("+classLoader+") for search");
            return;
        }

        debugPrintln("using class loader ("+classLoader+") for search");
    
private static voiddebugPrintln(java.lang.String msg)

Conditional debug printing.

param
msg to print

    
     
        // Use try/catch block to support applets
        try {
            debug = ss.getSystemProperty("jaxp.debug") != null;
        } catch (Exception _) {
            debug = false;
        }
    
        if (debug) {
            System.err.println("JAXP: " + msg);
        }
    
private javax.xml.validation.SchemaFactoryloadFromProperty(java.lang.String keyName, java.lang.String resourceName, java.io.InputStream in)
Looks up a value in a property file while producing all sorts of debug messages.

return
null if there was an error.

        debugPrintln("Reading "+resourceName );
        
        Properties props=new Properties();
        props.load(in);
        in.close();
        String factoryClassName = props.getProperty(keyName);
        if(factoryClassName != null){
            debugPrintln("found "+keyName+" = " + factoryClassName);
            return createInstance(factoryClassName);
        } else {
            debugPrintln(keyName+" is not in the property file");
            return null;
        }
    
private javax.xml.validation.SchemaFactoryloadFromService(java.lang.String schemaLanguage, java.lang.String inputName, java.io.InputStream in)

Look up a value in a property file.

Set debug to true to trace property evaluation.

param
schemaLanguage Schema Language to support.
param
inputName Name of InputStream.
param
in InputStream of properties.
return
SchemaFactory as determined by keyName value or null if there was an error.
throws
IOException If IO error reading from in.


            SchemaFactory schemaFactory = null;
            final Class[] stringClassArray = {"".getClass()};
            final Object[] schemaLanguageObjectArray = {schemaLanguage};
            final String isSchemaLanguageSupportedMethod = "isSchemaLanguageSupported";

            debugPrintln("Reading " + inputName);

            // read from InputStream until a match is found
            BufferedReader configFile = new BufferedReader(new InputStreamReader(in));
            String line = null;
            while ((line = configFile.readLine()) != null) {
                    // '#' is comment char
                    int comment = line.indexOf("#");
                    switch (comment) {
                            case -1: break; // no comment
                            case 0: line = ""; break; // entire line is a comment
                            default: line = line.substring(0, comment); break; // trim comment
                    }

                    // trim whitespace
                    line = line.trim();

                    // any content left on line?
                    if (line.length() == 0) {
                            continue;
                    }

                    // line content is now the name of the class
                    Class clazz = createClass(line);
                    if (clazz == null) {
                            continue;
                    } 

                    // create an instance of the Class
                    try {
                            schemaFactory = (SchemaFactory) clazz.newInstance();
                    } catch (ClassCastException classCastExcpetion) {
                            schemaFactory = null;
                            continue;
                    } catch (InstantiationException instantiationException) {
                            schemaFactory = null;
                            continue;
                    } catch (IllegalAccessException illegalAccessException) {
                            schemaFactory = null;
                            continue;
                    }
                    
                    // does this Class support desired Schema?
                    try {
                            Method isSchemaLanguageSupported = clazz.getMethod(isSchemaLanguageSupportedMethod, stringClassArray);
                            Boolean supported = (Boolean) isSchemaLanguageSupported.invoke(schemaFactory, schemaLanguageObjectArray);
                            if (supported.booleanValue()) {
                                    break;
                            }
                    } catch (NoSuchMethodException noSuchMethodException) {
                           
                    } catch (IllegalAccessException illegalAccessException) {
                            
                    } catch (InvocationTargetException invocationTargetException) {
                            
                    }
                    schemaFactory = null;						
            }

            // clean up
            configFile.close();

            // return new instance of SchemaFactory or null
            return schemaFactory;
    
public javax.xml.validation.SchemaFactorynewFactory(java.lang.String schemaLanguage)

Creates a new {@link SchemaFactory} object for the specified schema language.

param
schemaLanguage See {@link SchemaFactory Schema Language} table in SchemaFactory for the list of available schema languages.
return
null if the callee fails to create one.
throws
NullPointerException If the schemaLanguage parameter is null.

        if(schemaLanguage==null)        throw new NullPointerException();
        SchemaFactory f = _newFactory(schemaLanguage);
        if (f != null) {
            debugPrintln("factory '" + f.getClass().getName() + "' was found for " + schemaLanguage);
        } else {
            debugPrintln("unable to find a factory for " + schemaLanguage);
        }
        return f;
    
private static java.lang.Stringwhich(java.lang.Class clazz)

    
    
    
           
        return which( clazz.getName(), clazz.getClassLoader() );
    
private static java.lang.Stringwhich(java.lang.String classname, java.lang.ClassLoader loader)

Search the specified classloader for the given classname.

param
classname the fully qualified name of the class to search for
param
loader the classloader to search
return
the source location of the resource, or null if it wasn't found


        String classnameAsResource = classname.replace('.", '/") + ".class";
        
        if( loader==null )  loader = ClassLoader.getSystemClassLoader();
        
        //URL it = loader.getResource(classnameAsResource);
        URL it = ss.getResourceAsURL(loader, classnameAsResource);
        if (it != null) {
            return it.toString();
        } else {
            return null;
        }