FileDocCategorySizeDatePackage
XPathFactoryFinder.javaAPI DocJava SE 6 API18498Tue Jun 10 00:27:16 BST 2008javax.xml.xpath

XPathFactoryFinder

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

Fields Summary
private static SecuritySupport
ss
private static boolean
debug
debug support code.
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 XPathFactory.

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

Constructor that specifies ClassLoader to use to find XPathFactory.

param
loader to be used to load resource, {@link XPathFactory}, 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.xpath.XPathFactory_newFactory(java.lang.String uri)

Lookup a {@link XPathFactory} for the given object model.

param
uri identifies the object model.
return
{@link XPathFactory} for the given object model.

        XPathFactory xpathFactory;
        
        String propertyName = SERVICE_CLASS.getName() + ":" + uri;
        
        // system property look up
        try {
            debugPrintln("Looking up system property '"+propertyName+"'" );
            String r = ss.getSystemProperty(propertyName);
            if(r!=null) {
                debugPrintln("The value is '"+r+"'");
                xpathFactory = createInstance(r);
                if(xpathFactory != null)    return xpathFactory;
            } 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) {
                xpathFactory = createInstance(factoryClassName);
                if(xpathFactory != null){
                    return xpathFactory;
                }
            }
        } catch (Exception ex) {
            if (debug) {
                ex.printStackTrace();
            } 
        }
                    
        // try META-INF/services files
        Iterator sitr = createServiceFileIterator();
        while(sitr.hasNext()) {
            URL resource = (URL)sitr.next();
            debugPrintln("looking into " + resource);
            try {
                xpathFactory = loadFromService(uri, resource.toExternalForm(),
						ss.getURLInputStream(resource));
		if (xpathFactory != null) {
                    return xpathFactory;
		} 
            } catch(IOException e) {
                if( debug ) {
                    debugPrintln("failed to read "+resource);
                    e.printStackTrace();
                }
            }
        }
        
        // platform default
        if(uri.equals(XPathFactory.DEFAULT_OBJECT_MODEL_URI)) {
            debugPrintln("attempting to use the platform default W3C DOM XPath lib");
            return createInstance("com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl");
        }
        
        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.xpath.XPathFactorycreateInstance(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.

        XPathFactory xPathFactory = 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 XPathFactory
        try {
                xPathFactory = (XPathFactory) 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 xPathFactory;
    
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 = XPathFactoryFinder.class.getClassLoader();
                    return ss.getResourceAsURL(classLoader, SERVICE_ID);
                    //return (ClassLoader.getSystemResource( 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

    
                 
         
        if (debug) {
            System.err.println("JAXP: " + msg);
        }
    
private javax.xml.xpath.XPathFactoryloadFromProperty(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.xpath.XPathFactoryloadFromService(java.lang.String objectModel, 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
objectModel URI of object model to support.
param
inputName Name of InputStream.
param
in InputStream of properties.
return
XPathFactory as determined by keyName value or null if there was an error.
throws
IOException If IO error reading from in.


            XPathFactory xPathFactory = null;
            final Class[] stringClassArray = {"".getClass()};
            final Object[] objectModelObjectArray = {objectModel};
            final String isObjectModelSupportedMethod = "isObjectModelSupported";

            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 {
                            xPathFactory = (XPathFactory) clazz.newInstance();
                    } catch (ClassCastException classCastExcpetion) {
                            xPathFactory = null;
                            continue;
                    } catch (InstantiationException instantiationException) {
                            xPathFactory = null;
                            continue;
                    } catch (IllegalAccessException illegalAccessException) {
                            xPathFactory = null;
                            continue;
                    }
                                     
                    // does this Class support desired object model?
                    try {
                            Method isObjectModelSupported = clazz.getMethod(isObjectModelSupportedMethod, stringClassArray);
                            Boolean supported = (Boolean) isObjectModelSupported.invoke(xPathFactory, objectModelObjectArray);
                            if (supported.booleanValue()) {
                                    break;
                            }
                            
                    } catch (NoSuchMethodException noSuchMethodException) {
                           
                    } catch (IllegalAccessException illegalAccessException) {
                            
                    } catch (InvocationTargetException invocationTargetException) {
                            
                    }
                    xPathFactory = null;				
            }

            // clean up
            configFile.close();

            // return new instance of XPathFactory or null
            return xPathFactory;
    
public javax.xml.xpath.XPathFactorynewFactory(java.lang.String uri)

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

param
uri Identifies the underlying object model.
return
null if the callee fails to create one.
throws
NullPointerException If the parameter is null.

        if(uri==null)        throw new NullPointerException();
        XPathFactory f = _newFactory(uri);
        if (f != null) {
            debugPrintln("factory '" + f.getClass().getName() + "' was found for " + uri);
        } else {
            debugPrintln("unable to find a factory for " + uri);
        }
        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;
        }