KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > util > xml > catalog > readers > OASISXMLCatalogReader


1 // OASISXMLCatalogReader.java - Read XML Catalog files
2

3 /* ====================================================================
4  * The Apache Software License, Version 1.1
5  *
6  * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
7  * reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  * notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  * notice, this list of conditions and the following disclaimer in
18  * the documentation and/or other materials provided with the
19  * distribution.
20  *
21  * 3. The end-user documentation included with the redistribution,
22  * if any, must include the following acknowledgment:
23  * "This product includes software developed by the
24  * Apache Software Foundation (http://www.apache.org/)."
25  * Alternately, this acknowledgment may appear in the software itself,
26  * if and wherever such third-party acknowledgments normally appear.
27  *
28  * 4. The names "Apache" and "Apache Software Foundation" must
29  * not be used to endorse or promote products derived from this
30  * software without prior written permission. For written
31  * permission, please contact apache@apache.org.
32  *
33  * 5. Products derived from this software may not be called "Apache",
34  * nor may "Apache" appear in their name, without prior written
35  * permission of the Apache Software Foundation.
36  *
37  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48  * SUCH DAMAGE.
49  * ====================================================================
50  *
51  * This software consists of voluntary contributions made by many
52  * individuals on behalf of the Apache Software Foundation. For more
53  * information on the Apache Software Foundation, please see
54  * <http://www.apache.org/>.
55  */

56
57 package org.jboss.util.xml.catalog.readers;
58
59 import java.util.Stack JavaDoc;
60 import java.util.Vector JavaDoc;
61 import java.util.Enumeration JavaDoc;
62 import org.jboss.util.xml.catalog.Catalog;
63 import org.jboss.util.xml.catalog.CatalogEntry;
64 import org.jboss.util.xml.catalog.CatalogException;
65 import org.jboss.util.xml.catalog.helpers.PublicId;
66
67 import org.xml.sax.*;
68 import org.w3c.dom.*;
69
70 /**
71  * Parse OASIS Entity Resolution Technical Committee
72  * XML Catalog files.
73  *
74  * @see Catalog
75  *
76  * @author Norman Walsh
77  * <a HREF="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
78  *
79  * @version 1.0
80  */

81 public class OASISXMLCatalogReader extends SAXCatalogReader implements SAXCatalogParser {
82   /** The catalog object needs to be stored by the object so that
83    * SAX callbacks can use it.
84    */

85   protected Catalog catalog = null;
86
87   /** The namespace name of OASIS ERTC catalogs */
88   public static final String JavaDoc namespaceName = "urn:oasis:names:tc:entity:xmlns:xml:catalog";
89
90   /** The namespace name of OASIS ERTC TR9401 catalog extension */
91   public static final String JavaDoc tr9401NamespaceName = "urn:oasis:names:tc:entity:xmlns:tr9401:catalog";
92
93   protected Stack JavaDoc baseURIStack = new Stack JavaDoc();
94   protected Stack JavaDoc overrideStack = new Stack JavaDoc();
95   protected Stack JavaDoc namespaceStack = new Stack JavaDoc();
96
97   /** Set the current catalog. */
98   public void setCatalog (Catalog catalog) {
99     this.catalog = catalog;
100     debug = catalog.getCatalogManager().debug;
101   }
102
103   /** Get the current catalog. */
104   public Catalog getCatalog () {
105     return catalog;
106   }
107
108   /**
109    * Are we in an extension namespace?
110    *
111    * @return true if the current stack of open namespaces includes
112    * an extension namespace.
113    */

114   protected boolean inExtensionNamespace() {
115     boolean inExtension = false;
116
117     Enumeration JavaDoc elements = namespaceStack.elements();
118     while (!inExtension && elements.hasMoreElements()) {
119       String JavaDoc ns = (String JavaDoc) elements.nextElement();
120       if (ns == null) {
121     inExtension = true;
122       } else {
123     inExtension = (!ns.equals(tr9401NamespaceName)
124                && !ns.equals(namespaceName));
125       }
126     }
127
128     return inExtension;
129   }
130
131   // ----------------------------------------------------------------------
132
// Implement the SAX ContentHandler interface
133

134   /** The SAX <code>setDocumentLocator</code> method does nothing. */
135   public void setDocumentLocator (Locator locator) {
136     return;
137   }
138
139   /** The SAX <code>startDocument</code> method does nothing. */
140   public void startDocument ()
141     throws SAXException {
142     baseURIStack.push(catalog.getCurrentBase());
143     overrideStack.push(catalog.getDefaultOverride());
144     return;
145   }
146
147   /** The SAX <code>endDocument</code> method does nothing. */
148   public void endDocument ()
149     throws SAXException {
150     return;
151   }
152
153   /**
154    * The SAX <code>startElement</code> method recognizes elements
155    * from the plain catalog format and instantiates CatalogEntry
156    * objects for them.
157    *
158    * @param namespaceURI The namespace name of the element.
159    * @param localName The local name of the element.
160    * @param qName The QName of the element.
161    * @param atts The list of attributes on the element.
162    *
163    * @see CatalogEntry
164    */

165   public void startElement (String JavaDoc namespaceURI,
166                 String JavaDoc localName,
167                 String JavaDoc qName,
168                 Attributes atts)
169     throws SAXException {
170
171     int entryType = -1;
172     Vector JavaDoc entryArgs = new Vector JavaDoc();
173
174     namespaceStack.push(namespaceURI);
175
176     boolean inExtension = inExtensionNamespace();
177
178     if (namespaceURI != null && namespaceName.equals(namespaceURI)
179     && !inExtension) {
180       // This is an XML Catalog entry
181

182       if (atts.getValue("xml:base") != null) {
183     String JavaDoc baseURI = atts.getValue("xml:base");
184     entryType = Catalog.BASE;
185     entryArgs.add(baseURI);
186     baseURIStack.push(baseURI);
187
188     debug.message(4, "xml:base", baseURI);
189
190     try {
191       CatalogEntry ce = new CatalogEntry(entryType, entryArgs);
192       catalog.addEntry(ce);
193     } catch (CatalogException cex) {
194       if (cex.getExceptionType() == CatalogException.INVALID_ENTRY_TYPE) {
195         debug.message(1, "Invalid catalog entry type", localName);
196       } else if (cex.getExceptionType() == CatalogException.INVALID_ENTRY) {
197         debug.message(1, "Invalid catalog entry (base)", localName);
198       }
199     }
200
201     entryType = -1;
202     entryArgs = new Vector JavaDoc();
203
204       } else {
205     baseURIStack.push(baseURIStack.peek());
206       }
207
208       if ((localName.equals("catalog") || localName.equals("group"))
209       && atts.getValue("prefer") != null) {
210     String JavaDoc override = atts.getValue("prefer");
211
212     if (override.equals("public")) {
213       override = "yes";
214     } else if (override.equals("system")) {
215       override = "no";
216     } else {
217       debug.message(1,
218             "Invalid prefer: must be 'system' or 'public'",
219             localName);
220       override = catalog.getDefaultOverride();
221     }
222
223     entryType = Catalog.OVERRIDE;
224     entryArgs.add(override);
225     overrideStack.push(override);
226
227     debug.message(4, "override", override);
228
229     try {
230       CatalogEntry ce = new CatalogEntry(entryType, entryArgs);
231       catalog.addEntry(ce);
232     } catch (CatalogException cex) {
233       if (cex.getExceptionType() == CatalogException.INVALID_ENTRY_TYPE) {
234         debug.message(1, "Invalid catalog entry type", localName);
235       } else if (cex.getExceptionType() == CatalogException.INVALID_ENTRY) {
236         debug.message(1, "Invalid catalog entry (override)", localName);
237       }
238     }
239
240     entryType = -1;
241     entryArgs = new Vector JavaDoc();
242
243       } else {
244     overrideStack.push(overrideStack.peek());
245       }
246
247       if (localName.equals("delegatePublic")) {
248     if (checkAttributes(atts, "publicIdStartString", "catalog")) {
249       entryType = Catalog.DELEGATE_PUBLIC;
250       entryArgs.add(atts.getValue("publicIdStartString"));
251       entryArgs.add(atts.getValue("catalog"));
252
253       debug.message(4, "delegatePublic",
254             PublicId.normalize(atts.getValue("publicIdStartString")),
255             atts.getValue("catalog"));
256     }
257       } else if (localName.equals("delegateSystem")) {
258     if (checkAttributes(atts, "systemIdStartString", "catalog")) {
259       entryType = Catalog.DELEGATE_SYSTEM;
260       entryArgs.add(atts.getValue("systemIdStartString"));
261       entryArgs.add(atts.getValue("catalog"));
262
263       debug.message(4, "delegateSystem",
264             atts.getValue("systemIdStartString"),
265             atts.getValue("catalog"));
266     }
267       } else if (localName.equals("delegateURI")) {
268     if (checkAttributes(atts, "uriStartString", "catalog")) {
269       entryType = Catalog.DELEGATE_URI;
270       entryArgs.add(atts.getValue("uriStartString"));
271       entryArgs.add(atts.getValue("catalog"));
272
273       debug.message(4, "delegateURI",
274             atts.getValue("uriStartString"),
275             atts.getValue("catalog"));
276     }
277       } else if (localName.equals("rewriteSystem")) {
278     if (checkAttributes(atts, "systemIdStartString", "rewritePrefix")) {
279       entryType = Catalog.REWRITE_SYSTEM;
280       entryArgs.add(atts.getValue("systemIdStartString"));
281       entryArgs.add(atts.getValue("rewritePrefix"));
282
283       debug.message(4, "rewriteSystem",
284             atts.getValue("systemIdStartString"),
285             atts.getValue("rewritePrefix"));
286     }
287       } else if (localName.equals("rewriteURI")) {
288     if (checkAttributes(atts, "uriStartString", "rewritePrefix")) {
289       entryType = Catalog.REWRITE_URI;
290       entryArgs.add(atts.getValue("uriStartString"));
291       entryArgs.add(atts.getValue("rewritePrefix"));
292
293       debug.message(4, "rewriteURI",
294             atts.getValue("uriStartString"),
295             atts.getValue("rewritePrefix"));
296     }
297       } else if (localName.equals("nextCatalog")) {
298     if (checkAttributes(atts, "catalog")) {
299       entryType = Catalog.CATALOG;
300       entryArgs.add(atts.getValue("catalog"));
301
302       debug.message(4, "nextCatalog", atts.getValue("catalog"));
303     }
304       } else if (localName.equals("public")) {
305     if (checkAttributes(atts, "publicId", "uri")) {
306       entryType = Catalog.PUBLIC;
307       entryArgs.add(atts.getValue("publicId"));
308       entryArgs.add(atts.getValue("uri"));
309
310       debug.message(4, "public",
311             PublicId.normalize(atts.getValue("publicId")),
312             atts.getValue("uri"));
313     }
314       } else if (localName.equals("system")) {
315     if (checkAttributes(atts, "systemId", "uri")) {
316       entryType = Catalog.SYSTEM;
317       entryArgs.add(atts.getValue("systemId"));
318       entryArgs.add(atts.getValue("uri"));
319
320       debug.message(4, "system",
321             atts.getValue("systemId"),
322             atts.getValue("uri"));
323     }
324       } else if (localName.equals("uri")) {
325     if (checkAttributes(atts, "name", "uri")) {
326       entryType = Catalog.URI;
327       entryArgs.add(atts.getValue("name"));
328       entryArgs.add(atts.getValue("uri"));
329
330       debug.message(4, "uri",
331             atts.getValue("name"),
332             atts.getValue("uri"));
333     }
334       } else if (localName.equals("catalog")) {
335     // nop, start of catalog
336
} else if (localName.equals("group")) {
337     // nop, a group
338
} else {
339     // This is equivalent to an invalid catalog entry type
340
debug.message(1, "Invalid catalog entry type", localName);
341       }
342
343       if (entryType >= 0) {
344     try {
345       CatalogEntry ce = new CatalogEntry(entryType, entryArgs);
346       catalog.addEntry(ce);
347     } catch (CatalogException cex) {
348       if (cex.getExceptionType() == CatalogException.INVALID_ENTRY_TYPE) {
349         debug.message(1, "Invalid catalog entry type", localName);
350       } else if (cex.getExceptionType() == CatalogException.INVALID_ENTRY) {
351         debug.message(1, "Invalid catalog entry", localName);
352       }
353     }
354       }
355     }
356
357     if (namespaceURI != null && tr9401NamespaceName.equals(namespaceURI)
358     && !inExtension) {
359       // This is a TR9401 Catalog entry
360

361       if (atts.getValue("xml:base") != null) {
362     String JavaDoc baseURI = atts.getValue("xml:base");
363     entryType = Catalog.BASE;
364     entryArgs.add(baseURI);
365     baseURIStack.push(baseURI);
366
367     debug.message(4, "xml:base", baseURI);
368
369     try {
370       CatalogEntry ce = new CatalogEntry(entryType, entryArgs);
371       catalog.addEntry(ce);
372     } catch (CatalogException cex) {
373       if (cex.getExceptionType() == CatalogException.INVALID_ENTRY_TYPE) {
374         debug.message(1, "Invalid catalog entry type", localName);
375       } else if (cex.getExceptionType() == CatalogException.INVALID_ENTRY) {
376         debug.message(1, "Invalid catalog entry (base)", localName);
377       }
378     }
379
380     entryType = -1;
381     entryArgs = new Vector JavaDoc();
382
383       } else {
384     baseURIStack.push(baseURIStack.peek());
385       }
386
387       if (localName.equals("doctype")) {
388     entryType = catalog.DOCTYPE;
389     entryArgs.add(atts.getValue("name"));
390     entryArgs.add(atts.getValue("uri"));
391       } else if (localName.equals("document")) {
392     entryType = catalog.DOCUMENT;
393     entryArgs.add(atts.getValue("uri"));
394       } else if (localName.equals("dtddecl")) {
395     entryType = catalog.DTDDECL;
396     entryArgs.add(atts.getValue("publicId"));
397     entryArgs.add(atts.getValue("uri"));
398       } else if (localName.equals("entity")) {
399     entryType = Catalog.ENTITY;
400     entryArgs.add(atts.getValue("name"));
401     entryArgs.add(atts.getValue("uri"));
402       } else if (localName.equals("linktype")) {
403     entryType = Catalog.LINKTYPE;
404     entryArgs.add(atts.getValue("name"));
405     entryArgs.add(atts.getValue("uri"));
406       } else if (localName.equals("notation")) {
407     entryType = Catalog.NOTATION;
408     entryArgs.add(atts.getValue("name"));
409     entryArgs.add(atts.getValue("uri"));
410       } else if (localName.equals("sgmldecl")) {
411     entryType = Catalog.SGMLDECL;
412     entryArgs.add(atts.getValue("uri"));
413       } else {
414     // This is equivalent to an invalid catalog entry type
415
debug.message(1, "Invalid catalog entry type", localName);
416       }
417
418       if (entryType >= 0) {
419     try {
420       CatalogEntry ce = new CatalogEntry(entryType, entryArgs);
421       catalog.addEntry(ce);
422     } catch (CatalogException cex) {
423       if (cex.getExceptionType() == CatalogException.INVALID_ENTRY_TYPE) {
424         debug.message(1, "Invalid catalog entry type", localName);
425       } else if (cex.getExceptionType() == CatalogException.INVALID_ENTRY) {
426         debug.message(1, "Invalid catalog entry", localName);
427       }
428     }
429       }
430     }
431   }
432
433   public boolean checkAttributes (Attributes atts, String JavaDoc attName) {
434     if (atts.getValue(attName) == null) {
435       debug.message(1, "Error: required attribute " + attName + " missing.");
436       return false;
437     } else {
438       return true;
439     }
440   }
441
442   public boolean checkAttributes (Attributes atts,
443                   String JavaDoc attName1,
444                   String JavaDoc attName2) {
445     return checkAttributes(atts, attName1)
446       && checkAttributes(atts, attName2);
447   }
448
449   /** The SAX <code>endElement</code> method does nothing. */
450   public void endElement (String JavaDoc namespaceURI,
451               String JavaDoc localName,
452               String JavaDoc qName)
453     throws SAXException {
454
455     int entryType = -1;
456     Vector JavaDoc entryArgs = new Vector JavaDoc();
457
458     boolean inExtension = inExtensionNamespace();
459
460     if (namespaceURI != null
461     && !inExtension
462     && (namespaceName.equals(namespaceURI)
463         || tr9401NamespaceName.equals(namespaceURI))) {
464
465       String JavaDoc popURI = (String JavaDoc) baseURIStack.pop();
466       String JavaDoc baseURI = (String JavaDoc) baseURIStack.peek();
467
468       if (!baseURI.equals(popURI)) {
469     entryType = catalog.BASE;
470     entryArgs.add(baseURI);
471
472     debug.message(4, "(reset) xml:base", baseURI);
473
474     try {
475       CatalogEntry ce = new CatalogEntry(entryType, entryArgs);
476       catalog.addEntry(ce);
477     } catch (CatalogException cex) {
478       if (cex.getExceptionType() == CatalogException.INVALID_ENTRY_TYPE) {
479         debug.message(1, "Invalid catalog entry type", localName);
480       } else if (cex.getExceptionType() == CatalogException.INVALID_ENTRY) {
481         debug.message(1, "Invalid catalog entry (rbase)", localName);
482       }
483     }
484       }
485     }
486
487     if (namespaceURI != null && namespaceName.equals(namespaceURI)
488     && !inExtension) {
489       if (localName.equals("catalog") || localName.equals("group")) {
490     String JavaDoc popOverride = (String JavaDoc) overrideStack.pop();
491     String JavaDoc override = (String JavaDoc) overrideStack.peek();
492
493     if (!override.equals(popOverride)) {
494       entryType = catalog.OVERRIDE;
495       entryArgs.add(override);
496       overrideStack.push(override);
497
498       debug.message(4, "(reset) override", override);
499
500       try {
501         CatalogEntry ce = new CatalogEntry(entryType, entryArgs);
502         catalog.addEntry(ce);
503       } catch (CatalogException cex) {
504         if (cex.getExceptionType() == CatalogException.INVALID_ENTRY_TYPE) {
505           debug.message(1, "Invalid catalog entry type", localName);
506         } else if (cex.getExceptionType() == CatalogException.INVALID_ENTRY) {
507           debug.message(1, "Invalid catalog entry (roverride)", localName);
508         }
509       }
510     }
511       }
512     }
513
514     namespaceStack.pop();
515
516     return;
517   }
518
519   /** The SAX <code>characters</code> method does nothing. */
520   public void characters (char ch[], int start, int length)
521     throws SAXException {
522     return;
523   }
524
525   /** The SAX <code>ignorableWhitespace</code> method does nothing. */
526   public void ignorableWhitespace (char ch[], int start, int length)
527     throws SAXException {
528     return;
529   }
530
531   /** The SAX <code>processingInstruction</code> method does nothing. */
532   public void processingInstruction (String JavaDoc target, String JavaDoc data)
533     throws SAXException {
534     return;
535   }
536
537   /** The SAX <code>skippedEntity</code> method does nothing. */
538   public void skippedEntity (String JavaDoc name)
539     throws SAXException {
540     return;
541   }
542
543   /** The SAX <code>startPrefixMapping</code> method does nothing. */
544   public void startPrefixMapping(String JavaDoc prefix, String JavaDoc uri)
545     throws SAXException {
546     return;
547   }
548
549   /** The SAX <code>endPrefixMapping</code> method does nothing. */
550   public void endPrefixMapping(String JavaDoc prefix)
551     throws SAXException {
552     return;
553   }
554
555 }
556
Popular Tags