KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > xml > validation > SchemaFactoryFinder


1
2 // $Id: SchemaFactoryFinder.java,v 1.14 2004/11/24 23:32:37 jsuttor Exp $
3

4 /*
5  * @(#)SchemaFactoryFinder.java 1.12 05/01/04
6  *
7  * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
8  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
9  *
10  */

11
12 package javax.xml.validation;
13
14 import java.io.File JavaDoc;
15 import java.io.IOException JavaDoc;
16 import java.io.InputStream JavaDoc;
17 import java.net.URL JavaDoc;
18 import java.util.ArrayList JavaDoc;
19 import java.util.Enumeration JavaDoc;
20 import java.util.Iterator JavaDoc;
21 import java.util.NoSuchElementException JavaDoc;
22 import java.util.Properties JavaDoc;
23
24 /**
25  * Implementation of {@link SchemaFactory#newInstance(String)}.
26  *
27  * @author <a HREF="Kohsuke.Kawaguchi@Sun.com">Kohsuke Kawaguchi</a>
28  * @version $Revision: 1.14 $, $Date: 2004/11/24 23:32:37 $
29  * @since 1.5
30  */

31 class SchemaFactoryFinder {
32
33     /** debug support code. */
34     private static boolean debug = false;
35     /**
36      *<p> Take care of restrictions imposed by java security model </p>
37      */

38     private static SecuritySupport JavaDoc ss = new SecuritySupport JavaDoc();
39     /**
40      * <p>Cache properties for performance.</p>
41      */

42     private static Properties JavaDoc cacheProps = new Properties JavaDoc();
43     
44     /**
45      * <p>First time requires initialization overhead.</p>
46      */

47     private static boolean firstTime = true;
48     
49     static {
50         // Use try/catch block to support applets
51
try {
52             debug = ss.getSystemProperty("jaxp.debug") != null;
53         } catch (Exception JavaDoc _) {
54             debug = false;
55         }
56     }
57
58     /**
59      * <p>Conditional debug printing.</p>
60      *
61      * @param msg to print
62      */

63     private static void debugPrintln(String JavaDoc msg) {
64         if (debug) {
65             System.err.println("JAXP: " + msg);
66         }
67     }
68     
69     /**
70      * <p><code>ClassLoader</code> to use to find <code>SchemaFactory</code>.</p>
71      */

72     private final ClassLoader JavaDoc classLoader;
73     
74     /**
75      * <p>Constructor that specifies <code>ClassLoader</code> to use
76      * to find <code>SchemaFactory</code>.</p>
77      *
78      * @param loader
79      * to be used to load resource, {@link SchemaFactory}, and
80      * {@link SchemaFactoryLoader} implementations during
81      * the resolution process.
82      * If this parameter is null, the default system class loader
83      * will be used.
84      */

85     public SchemaFactoryFinder(ClassLoader JavaDoc loader) {
86         this.classLoader = loader;
87         if( debug ) {
88             debugDisplayClassLoader();
89         }
90     }
91     
92     private void debugDisplayClassLoader() {
93         try {
94             if( classLoader == ss.getContextClassLoader() ) {
95                 debugPrintln("using thread context class loader ("+classLoader+") for search");
96                 return;
97             }
98         } catch( Throwable JavaDoc _ ) {
99             ; // getContextClassLoader() undefined in JDK1.1
100
}
101         
102         if( classLoader==ClassLoader.getSystemClassLoader() ) {
103             debugPrintln("using system class loader ("+classLoader+") for search");
104             return;
105         }
106
107         debugPrintln("using class loader ("+classLoader+") for search");
108     }
109     
110     /**
111      * <p>Creates a new {@link SchemaFactory} object for the specified
112      * schema language.</p>
113      *
114      * @param schemaLanguage
115      * See {@link SchemaFactory Schema Language} table in <code>SchemaFactory</code>
116      * for the list of available schema languages.
117      *
118      * @return <code>null</code> if the callee fails to create one.
119      *
120      * @throws NullPointerException
121      * If the <tt>schemaLanguage</tt> parameter is null.
122      */

123     public SchemaFactory JavaDoc newFactory(String JavaDoc schemaLanguage) {
124         if(schemaLanguage==null) throw new NullPointerException JavaDoc();
125         SchemaFactory JavaDoc f = _newFactory(schemaLanguage);
126         if (f != null) {
127             debugPrintln("factory '" + f.getClass().getName() + "' was found for " + schemaLanguage);
128         } else {
129             debugPrintln("unable to find a factory for " + schemaLanguage);
130         }
131         return f;
132     }
133     
134     /**
135      * <p>Lookup a <code>SchemaFactory</code> for the given <code>schemaLanguage</code>.</p>
136      *
137      * @param schemaLanguage Schema language to lookup <code>SchemaFactory</code> for.
138      *
139      * @return <code>SchemaFactory</code> for the given <code>schemaLanguage</code>.
140      */

141     private SchemaFactory JavaDoc _newFactory(String JavaDoc schemaLanguage) {
142         SchemaFactory JavaDoc sf;
143         
144         String JavaDoc propertyName = SERVICE_CLASS.getName() + ":" + schemaLanguage;
145         
146         // system property look up
147
try {
148             debugPrintln("Looking up system property '"+propertyName+"'" );
149             String JavaDoc r = ss.getSystemProperty(propertyName);
150             if(r!=null) {
151                 debugPrintln("The value is '"+r+"'");
152                 sf = createInstance(r);
153                 if(sf!=null) return sf;
154             } else
155                 debugPrintln("The property is undefined.");
156         } catch( Throwable JavaDoc t ) {
157             if( debug ) {
158                 debugPrintln("failed to look up system property '"+propertyName+"'" );
159                 t.printStackTrace();
160             }
161         }
162
163         String JavaDoc javah = ss.getSystemProperty( "java.home" );
164         String JavaDoc configFile = javah + File.separator +
165         "lib" + File.separator + "jaxp.properties";
166
167         String JavaDoc factoryClassName = null ;
168
169         // try to read from $java.home/lib/jaxp.properties
170
try {
171             if(firstTime){
172                 synchronized(cacheProps){
173                     if(firstTime){
174                         File JavaDoc f=new File JavaDoc( configFile );
175                         firstTime = false;
176                         if(ss.doesFileExist(f)){
177                             debugPrintln("Read properties file " + f);
178                             cacheProps.load(ss.getFileInputStream(f));
179                         }
180                     }
181                 }
182             }
183             factoryClassName = cacheProps.getProperty(propertyName);
184             debugPrintln("found " + factoryClassName + " in $java.home/jaxp.properties");
185
186             if (factoryClassName != null) {
187                 sf = createInstance(factoryClassName);
188                 if(sf != null){
189                     return sf;
190                 }
191             }
192         } catch (Exception JavaDoc ex) {
193             if (debug) {
194                 ex.printStackTrace();
195             }
196         }
197
198         /**
199         // try to read from $java.home/lib/jaxp.properties
200         try {
201             String javah = ss.getSystemProperty( "java.home" );
202             String configFile = javah + File.separator +
203             "lib" + File.separator + "jaxp.properties";
204             File f = new File( configFile );
205             if( ss.doesFileExist(f)) {
206                 sf = loadFromProperty(
207                         propertyName,f.getAbsolutePath(), new FileInputStream(f));
208                 if(sf!=null) return sf;
209             } else {
210                 debugPrintln("Tried to read "+ f.getAbsolutePath()+", but it doesn't exist.");
211             }
212         } catch(Throwable e) {
213             if( debug ) {
214                 debugPrintln("failed to read $java.home/lib/jaxp.properties");
215                 e.printStackTrace();
216             }
217         }
218          */

219         
220         // try META-INF/services files
221
Iterator JavaDoc sitr = createServiceFileIterator();
222         while(sitr.hasNext()) {
223             URL JavaDoc resource = (URL JavaDoc)sitr.next();
224             debugPrintln("looking into " + resource);
225             try {
226                 //sf = loadFromProperty(schemaLanguage,resource.toExternalForm(),resource.openStream());
227
sf = loadFromProperty(schemaLanguage,resource.toExternalForm(),ss.getURLInputStream(resource));
228                 if(sf!=null) return sf;
229             } catch(IOException JavaDoc e) {
230                 if( debug ) {
231                     debugPrintln("failed to read "+resource);
232                     e.printStackTrace();
233                 }
234             }
235         }
236         
237         // platform default
238
if(schemaLanguage.equals("http://www.w3.org/2001/XMLSchema")) {
239             debugPrintln("attempting to use the platform default XML Schema validator");
240             return createInstance("com.sun.org.apache.xerces.internal.jaxp.validation.xs.SchemaFactoryImpl");
241         }
242         
243         debugPrintln("all things were tried, but none was found. bailing out.");
244         return null;
245     }
246     
247     /**
248      * <p>Creates an instance of the specified and returns it.</p>
249      *
250      * @param className
251      * fully qualified class name to be instanciated.
252      *
253      * @return null
254      * if it fails. Error messages will be printed by this method.
255      */

256     private SchemaFactory JavaDoc createInstance( String JavaDoc className ) {
257         try {
258             debugPrintln("instanciating "+className);
259             Class JavaDoc clazz;
260             if( classLoader!=null )
261                 clazz = classLoader.loadClass(className);
262             else
263                 clazz = Class.forName(className);
264             if(debug) debugPrintln("loaded it from "+which(clazz));
265             Object JavaDoc o = clazz.newInstance();
266             
267             if( o instanceof SchemaFactory JavaDoc )
268                 return (SchemaFactory JavaDoc)o;
269             
270             debugPrintln(className+" is not assignable to "+SERVICE_CLASS.getName());
271         } catch( Throwable JavaDoc t ) {
272             debugPrintln("failed to instanciate "+className);
273             if(debug) t.printStackTrace();
274         }
275         return null;
276     }
277     
278     /** Iterator that lazily computes one value and returns it. */
279     private static abstract class SingleIterator implements Iterator JavaDoc {
280         private boolean seen = false;
281         
282         public final void remove() { throw new UnsupportedOperationException JavaDoc(); }
283         public final boolean hasNext() { return !seen; }
284         public final Object JavaDoc next() {
285             if(seen) throw new NoSuchElementException JavaDoc();
286             seen = true;
287             return value();
288         }
289         
290         protected abstract Object JavaDoc value();
291     }
292     
293     /**
294      * Looks up a value in a property file
295      * while producing all sorts of debug messages.
296      *
297      * @return null
298      * if there was an error.
299      */

300     private SchemaFactory JavaDoc loadFromProperty( String JavaDoc keyName, String JavaDoc resourceName, InputStream JavaDoc in )
301         throws IOException JavaDoc {
302         debugPrintln("Reading "+resourceName );
303         
304         Properties JavaDoc props=new Properties JavaDoc();
305         props.load(in);
306         in.close();
307         String JavaDoc factoryClassName = props.getProperty(keyName);
308         if(factoryClassName != null){
309             debugPrintln("found "+keyName+" = " + factoryClassName);
310             return createInstance(factoryClassName);
311         } else {
312             debugPrintln(keyName+" is not in the property file");
313             return null;
314         }
315     }
316     
317     /**
318      * Returns an {@link Iterator} that enumerates all
319      * the META-INF/services files that we care.
320      */

321     private Iterator JavaDoc createServiceFileIterator() {
322         if (classLoader == null) {
323             return new SingleIterator() {
324                 protected Object JavaDoc value() {
325                     ClassLoader JavaDoc classLoader = SchemaFactoryFinder JavaDoc.class.getClassLoader();
326                     //return (ClassLoader.getSystemResource( SERVICE_ID ));
327
return ss.getResourceAsURL(classLoader, SERVICE_ID);
328                 }
329             };
330         } else {
331             try {
332                 //final Enumeration e = classLoader.getResources(SERVICE_ID);
333
final Enumeration JavaDoc e = ss.getResources(classLoader, SERVICE_ID);
334                 if(!e.hasMoreElements()) {
335                     debugPrintln("no "+SERVICE_ID+" file was found");
336                 }
337                 
338                 // wrap it into an Iterator.
339
return new Iterator JavaDoc() {
340                     public void remove() {
341                         throw new UnsupportedOperationException JavaDoc();
342                     }
343
344                     public boolean hasNext() {
345                         return e.hasMoreElements();
346                     }
347
348                     public Object JavaDoc next() {
349                         return e.nextElement();
350                     }
351                 };
352             } catch (IOException JavaDoc e) {
353                 debugPrintln("failed to enumerate resources "+SERVICE_ID);
354                 if(debug) e.printStackTrace();
355                 return new ArrayList JavaDoc().iterator(); // empty iterator
356
}
357         }
358     }
359     
360     private static final Class JavaDoc SERVICE_CLASS = SchemaFactory JavaDoc.class;
361     private static final String JavaDoc SERVICE_ID = "META-INF/services/" + SERVICE_CLASS.getName();
362     
363     
364     
365     private static String JavaDoc which( Class JavaDoc clazz ) {
366         return which( clazz.getName(), clazz.getClassLoader() );
367     }
368
369     /**
370      * <p>Search the specified classloader for the given classname.</p>
371      *
372      * @param classname the fully qualified name of the class to search for
373      * @param loader the classloader to search
374      *
375      * @return the source location of the resource, or null if it wasn't found
376      */

377     private static String JavaDoc which(String JavaDoc classname, ClassLoader JavaDoc loader) {
378
379         String JavaDoc classnameAsResource = classname.replace('.', '/') + ".class";
380         
381         if( loader==null ) loader = ClassLoader.getSystemClassLoader();
382         
383         //URL it = loader.getResource(classnameAsResource);
384
URL JavaDoc it = ss.getResourceAsURL(loader, classnameAsResource);
385         if (it != null) {
386             return it.toString();
387         } else {
388             return null;
389         }
390     }
391 }
392
Popular Tags