KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > xquark > schema > SchemaManager


1 /*
2  * This file belongs to the XQuark distribution.
3  * Copyright (C) 2003 Universite de Versailles Saint-Quentin.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307.
18  * You can also get it at http://www.gnu.org/licenses/lgpl.html
19  *
20  * For more information on this software, see http://www.xquark.org.
21  */

22
23 package org.xquark.schema;
24
25 import java.io.IOException JavaDoc;
26 import java.net.MalformedURLException JavaDoc;
27 import java.net.URL JavaDoc;
28 import java.util.Collection JavaDoc;
29 import java.util.HashMap JavaDoc;
30 import java.util.Iterator JavaDoc;
31
32 import org.xml.sax.InputSource JavaDoc;
33 import org.xml.sax.SAXException JavaDoc;
34 import org.xml.sax.SAXParseException JavaDoc;
35 import org.xquark.schema.datatypes.PrimitiveType;
36 import org.xquark.schema.loader.Loader;
37
38 public class SchemaManager extends DefaultSchemaLocator
39 implements SchemaConstants {
40     private static final String JavaDoc RCSRevision = "$Revision: 1.1 $";
41     private static final String JavaDoc RCSName = "$Name: $";
42     
43     // Predefined schemas
44
private static SchemaManager predefined = null;
45     // Schema cache based on URLs, shared by all managers
46
private static HashMap JavaDoc loadedURLs = null;
47     
48     private static SimpleType IDType = null;
49     private static SimpleType IDREFType = null;
50     private static SimpleType IDREFSType = null;
51     private static SimpleType QNameType = null;
52     private static SimpleType NCNameType = null;
53     private static SimpleType timeType = null;
54     private static SimpleType dateType = null;
55     private static SimpleType dateTimeType = null;
56     private static SimpleType decimalType = null;
57     private static SimpleType integerType = null;
58     private static SimpleType doubleType = null;
59     private static SimpleType floatType = null;
60     private static SimpleType booleanType = null;
61     private static SimpleType stringType = null;
62     private static SimpleType anySimpleType = null;
63     
64     private static HashMap JavaDoc loadedFiles = new HashMap JavaDoc();
65     
66     static {
67         predefined = new SchemaManager();
68         loadedURLs = new HashMap JavaDoc();
69         try {
70             predefined.loadSimpleDataTypes();
71             // then, load schema for schemas
72
predefined.loadSchemaForSchemas();
73             predefined.loadSchemaForInstance();
74         }
75         catch ( SAXException JavaDoc e ) {
76             predefined = null;
77             if ( e instanceof SAXParseException JavaDoc ) {
78                 SAXParseException JavaDoc ex = (SAXParseException JavaDoc)e;
79                 System.out.println("Error at line "+ex.getLineNumber()+" in "+ex.getSystemId());
80             }
81             e.getException().printStackTrace();
82             throw new RuntimeException JavaDoc(e.getMessage());
83         }
84         IDType = (SimpleType)predefined.getType(XMLSCHEMA_URI, "ID");
85         IDREFType = (SimpleType)predefined.getType(XMLSCHEMA_URI, "IDREF");
86         IDREFSType = (SimpleType)predefined.getType(XMLSCHEMA_URI, "IDREFS");
87         QNameType = (SimpleType)predefined.getType(XMLSCHEMA_URI, "QName");
88         NCNameType = (SimpleType)predefined.getType(XMLSCHEMA_URI, "NCName");
89         timeType = (SimpleType)predefined.getType(XMLSCHEMA_URI, "time");
90         dateType = (SimpleType)predefined.getType(XMLSCHEMA_URI, "date");
91         dateTimeType = (SimpleType)predefined.getType(XMLSCHEMA_URI, "dateTime");
92         decimalType = (SimpleType)predefined.getType(XMLSCHEMA_URI, "decimal");
93         integerType = (SimpleType)predefined.getType(XMLSCHEMA_URI, "integer");
94         doubleType = (SimpleType)predefined.getType(XMLSCHEMA_URI, "double");
95         floatType = (SimpleType)predefined.getType(XMLSCHEMA_URI, "float");
96         booleanType = (SimpleType)predefined.getType(XMLSCHEMA_URI, "boolean");
97         stringType = (SimpleType)predefined.getType(XMLSCHEMA_URI, "string");
98         anySimpleType = new SimpleType(predefined.getSchema(XMLSCHEMA_URI), "anySimpleType", null);
99         anySimpleType.setPrimitive(PrimitiveType.createType("anySimpleType"));
100     }
101     
102     // Schema cache based on namespaces
103
private HashMap JavaDoc schemas = new HashMap JavaDoc();
104     private boolean useCache = true;
105     
106     public SchemaManager() {
107         this(predefined, true);
108     }
109     
110     public SchemaManager(boolean useCache) {
111         this(predefined, useCache);
112     }
113     
114     public SchemaManager(SchemaManager parent) {
115         this(parent, true);
116     }
117     
118     public SchemaManager(SchemaManager parent, boolean useCache) {
119         this.useCache = useCache;
120         if (parent == null) parent = predefined;
121         if (parent != null) {
122             Iterator JavaDoc it = parent.getSchemas().iterator();
123             while (it.hasNext()) {
124                 Schema s = (Schema)it.next();
125 // start add temporary
126
if (s != null)
127 // end add temporary
128
schemas.put(s.getNamespace(), s);
129             }
130         }
131     }
132     
133     private Schema loadSimpleDataTypes() throws SAXException JavaDoc {
134         Schema result = null;
135         try {
136             URL JavaDoc url = getClass().getResource("resources/simpleDatatypes.xsd");
137             Loader loader = new Loader(this);
138             result = loader.load(url);
139             schemas.put(result.getNamespace(), result);
140         }
141         catch (SAXException JavaDoc ex) {
142             throw ex;
143         }
144         catch ( Exception JavaDoc ex ) {
145             throw new SAXException JavaDoc(ex);
146         }
147         return result;
148     }
149     
150     // history
151
// created
152
//
153
private Schema loadSchemaForSchemas() throws SAXException JavaDoc {
154         Schema result = null;
155         try {
156             URL JavaDoc url = getClass().getResource("resources/XMLSchema.xsd");
157             Loader loader = new Loader(this);
158             result = loader.load(url);
159             schemas.put(result.getNamespace(), result);
160         }
161         catch (SAXException JavaDoc ex) {
162             throw ex;
163         }
164         catch ( Exception JavaDoc ex ) {
165             throw new SAXException JavaDoc(ex);
166         }
167         
168         return result;
169     }
170     
171     private Schema loadSchemaForInstance() throws SAXException JavaDoc {
172         Schema result = null;
173         try {
174             URL JavaDoc url = getClass().getResource("resources/XMLSchema-instance.xsd");
175             Loader loader = new Loader(this);
176             result = loader.load(url);
177             schemas.put(result.getNamespace(), result);
178         }
179         catch (SAXException JavaDoc ex) {
180             throw ex;
181         }
182         catch ( Exception JavaDoc ex ) {
183             throw new SAXException JavaDoc(ex);
184         }
185         
186         return result;
187     }
188     
189     public SimpleType getIDType() {
190         return IDType;
191     }
192     
193     public SimpleType getIDREFType() {
194         return IDREFType;
195     }
196     
197     public SimpleType getIDREFSType() {
198         return IDREFSType;
199     }
200     
201     public SimpleType getQNameType() {
202         return QNameType;
203     }
204     
205     public SimpleType getNCNameType() {
206         return NCNameType;
207     }
208     
209     public SimpleType getTimeType() {
210         return timeType;
211     }
212     
213     public SimpleType getDateType() {
214         return dateType;
215     }
216     
217     public SimpleType getDateTimeType() {
218         return dateTimeType;
219     }
220     
221     public SimpleType getIntegerType() {
222         return integerType;
223     }
224     
225     public SimpleType getDecimalType() {
226         return decimalType;
227     }
228     
229     public SimpleType getDoubleType() {
230         return doubleType;
231     }
232
233     public SimpleType getFloatType() {
234         return floatType;
235     }
236
237     public SimpleType getBooleanType() {
238         return booleanType;
239     }
240
241     public SimpleType getAnySimpleType() {
242         return anySimpleType;
243     }
244
245     public SimpleType getStringType() {
246         return stringType;
247     }
248
249     public ElementDeclaration getElementDeclaration(String JavaDoc namespace,
250     String JavaDoc localName) {
251         Schema schema = getSchema(namespace);
252         if (schema == null) return null;
253         return schema.getElementDeclaration(localName);
254     }
255     
256     public AttributeDeclaration getAttributeDeclaration(String JavaDoc namespace,
257     String JavaDoc localName) {
258         Schema schema = getSchema(namespace);
259         if (schema == null) return null;
260         return schema.getAttributeDeclaration(localName);
261     }
262     
263     public Type getType(String JavaDoc namespace, String JavaDoc localName) {
264         Schema schema = getSchema(namespace);
265         if (schema == null) return null;
266         return schema.getType(localName);
267     }
268     
269     public boolean isRegistered(String JavaDoc namespace) {
270         return schemas.containsKey(namespace);
271     }
272     
273     public Schema getSchema(String JavaDoc namespace) {
274         return (Schema)schemas.get(namespace);
275     }
276     
277     public Collection JavaDoc getSchemas() {
278         return schemas.values();
279     }
280     
281     public Schema removeSchema(String JavaDoc namespace) {
282         return (Schema)schemas.remove(namespace);
283     }
284     
285     private void checkNamespace(String JavaDoc ns, Schema schema)
286     throws SAXException JavaDoc {
287         if ( (ns != null && !ns.equals(schema.getNamespace()))
288         || (ns == null && schema.getNamespace() != null) )
289             throw new SAXException JavaDoc("Loaded schema target namespace "
290             + schema.getNamespace()
291             + " does not match expected URI: " + ns);
292     }
293     
294     public Schema loadSchema(String JavaDoc namespace)
295     throws SAXException JavaDoc {
296         return loadSchema(this, namespace);
297     }
298     
299     public Schema loadSchema(SchemaLocator locator, String JavaDoc namespace)
300     throws SAXException JavaDoc {
301         // Look into schema cache
302
if (isRegistered(namespace)) return getSchema(namespace);
303         
304         Schema result = null;
305         InputSource JavaDoc source = null;
306         // Load schema from its locations as strings
307
Iterator JavaDoc it1 = locator.getSchemaLocations(namespace);
308         if (it1 != null) {
309             while (it1.hasNext()) {
310                 source = locator.resolveLocation(namespace, (String JavaDoc)it1.next());
311                 if (source != null) result = loadSchema(locator, namespace, source);
312                 if (result != null) return result;
313             }
314         }
315         
316         // Load schema from its URI as string
317
source = locator.resolveLocation(namespace, namespace);
318         if (source != null) result = loadSchema(locator, namespace, source);
319         if (result != null) return result;
320         
321         // Load schema from its locations as URLs
322
Iterator JavaDoc it2 = locator.getSchemaLocations(namespace);
323         if (it2 != null) {
324             while (it2.hasNext()) {
325                 try {
326                     URL JavaDoc url = new URL JavaDoc((String JavaDoc)it2.next());
327                     source = locator.resolveLocation(namespace, url);
328                     if (source != null) result = loadSchema(locator, namespace, source);
329                     if (result != null) return result;
330                 } catch (MalformedURLException JavaDoc ex) {
331                     // continue
332
}
333             }
334         }
335         
336         // Load schema from its URI as URL
337
/* try {
338             URL url = new URL(namespace);
339             source = locator.resolveLocation(namespace, url);
340             if (source != null) result = loadSchema(locator, namespace, source);
341             if (result != null) return result;
342         } catch (MalformedURLException ex) {
343             // continue
344         }
345 */

346         // result is null
347
schemas.put(namespace, result);
348         return result;
349     }
350     
351     private Schema loadSchema(SchemaLocator locator, String JavaDoc namespace, InputSource JavaDoc source)
352     throws SAXException JavaDoc {
353         Schema result = null;
354         // Look into schema cache
355
if (isRegistered(namespace)) return getSchema(namespace);
356         
357         if (source == null) return null;
358         // Look into URL cache
359
String JavaDoc systemId = source.getSystemId();
360         if (systemId != null && useCache) result = (Schema)loadedURLs.get(systemId);
361         
362         // look if this file is loading ...
363
// Algorithm :
364
// 1. if this file is first to load, save it and current time to loadedFiles
365
// 2. if this file isn't first to load, get its last loading time.
366
// 3. if the difference of current time and last loading time is less than 5 millisecond,
367
// it's a "File Loading-Loop" problem.
368
// 4. else, save this file and current time to loadedFiles
369
//
370
// Why this algorithm:
371
// 1. User may load a alread loadded file, it's not a "File Loading-Loop"
372
// 2. User's schema file may has a problem, so the first schema file loading doesn't work,
373
// but User may reload corrected schema file later. It's not a "File Loading-Loop"
374
//
375
// Potential problems :
376
// 1. In multithread, two thread try to load the same file nearly the same time
377
// 2. In monothread or multithread, the schema file loading time is very long
378
//
379
// noted Fev 21, 2002
380
/* if ( systemId != null && loadedURLs.get(systemId) == null ) {
381             Long currentLoadingTime = new Long(System.currentTimeMillis());
382             if ( loadedFiles.get(systemId) != null ) {
383                 Long lastLoadingTime = (Long)loadedFiles.get(systemId);
384                 if ( currentLoadingTime.longValue() - lastLoadingTime.longValue() < 500 )
385                     throw new SAXException("File loading-loop : " + systemId);
386             }
387             loadedFiles.put(systemId, currentLoadingTime);
388         }
389 */

390         try {
391             if (result == null) {
392                 Loader loader = new Loader(this, locator);
393                 result = loader.load(source);
394                 checkNamespace(namespace, result);
395                 // Add schema to URL cache
396
if (systemId != null && useCache) loadedURLs.put(systemId, result);
397             }
398         } catch (IOException JavaDoc ex) {
399             throw new SAXException JavaDoc(ex);
400         } finally {
401             // Add schema to namespace cache
402
schemas.put(namespace, result);
403         }
404         return result;
405     }
406     
407     public Schema loadSchema(String JavaDoc namespace, InputSource JavaDoc source)
408     throws SAXException JavaDoc {
409         return loadSchema(this, namespace, source);
410     }
411     
412     public Schema loadSchema(SchemaLocator locator, String JavaDoc namespace, URL JavaDoc location)
413     throws SAXException JavaDoc {
414         return loadSchema(locator, namespace, locator.resolveLocation(namespace, location));
415     }
416     
417     public Schema loadSchema(String JavaDoc namespace, URL JavaDoc location)
418     throws SAXException JavaDoc {
419         return loadSchema(this, namespace, location);
420     }
421     
422     public Schema loadSchema(SchemaLocator locator, String JavaDoc namespace, String JavaDoc location)
423     throws SAXException JavaDoc {
424         return loadSchema(locator, namespace, locator.resolveLocation(namespace, location));
425     }
426     
427     public Schema loadSchema(String JavaDoc namespace, String JavaDoc location)
428     throws SAXException JavaDoc {
429         return loadSchema(this, namespace, location);
430     }
431     
432     public Schema loadSchema(SchemaLocator locator, InputSource JavaDoc source)
433     throws SAXException JavaDoc {
434         Schema result = null;
435         if (source == null) return null;
436         
437         // Look into URL cache
438
//String systemId = source.getSystemId(); @@@AM: Disabled for the time being
439
//if (systemId != null) result = (Schema)loadedURLs.get(systemId);
440

441         if (result == null) {
442             Loader loader = new Loader(this, locator);
443             try {
444                 result = loader.load(source);
445                 // Add schema to URL cache
446
//if (systemId != null) loadedURLs.put(systemId, result);
447
} catch (IOException JavaDoc ex) {
448                 throw new SAXException JavaDoc(ex);
449             }
450         }
451         String JavaDoc namespace = result.getNamespace();
452         // @@@AM: Commented out to enable schema replacement
453
//if (isRegistered(namespace)) {
454
// return getSchema(namespace);
455
//}
456
// Add schema to namespace cache
457
schemas.put(namespace, result);
458         return result;
459     }
460     
461     public Schema loadSchema(InputSource JavaDoc source)
462     throws SAXException JavaDoc {
463         return loadSchema(this, source);
464     }
465     
466     public boolean putSchema(Schema schema)
467     throws SAXException JavaDoc {
468         if ( isRegistered(schema.getNamespace()) ) return false;
469         schemas.put(schema.getNamespace(), schema);
470         return true;
471     }
472     
473     
474 }
475
Popular Tags