KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xml > internal > resolver > tools > ResolvingParser


1 // ResolvingParser.java - An interface for reading catalog files
2

3 /*
4  * Copyright 2001-2004 The Apache Software Foundation or its licensors,
5  * as applicable.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */

19
20 package com.sun.org.apache.xml.internal.resolver.tools;
21
22 import java.io.IOException JavaDoc;
23 import java.io.InputStream JavaDoc;
24 import java.net.URL JavaDoc;
25 import java.net.MalformedURLException JavaDoc;
26 import java.util.Locale JavaDoc;
27
28 import org.xml.sax.Parser JavaDoc;
29 import org.xml.sax.InputSource JavaDoc;
30 import org.xml.sax.Locator JavaDoc;
31 import org.xml.sax.ErrorHandler JavaDoc;
32 import org.xml.sax.DTDHandler JavaDoc;
33 import org.xml.sax.DocumentHandler JavaDoc;
34 import org.xml.sax.AttributeList JavaDoc;
35 import org.xml.sax.EntityResolver JavaDoc;
36 import org.xml.sax.SAXException JavaDoc;
37
38 import javax.xml.parsers.SAXParserFactory JavaDoc;
39 import javax.xml.parsers.SAXParser JavaDoc;
40
41 import com.sun.org.apache.xml.internal.resolver.Catalog;
42 import com.sun.org.apache.xml.internal.resolver.CatalogManager;
43 import com.sun.org.apache.xml.internal.resolver.helpers.FileURL;
44
45 /**
46  * A SAX Parser that performs catalog-based entity resolution.
47  *
48  * <p>This class implements a SAX Parser that performs entity resolution
49  * using the CatalogResolver. The actual, underlying parser is obtained
50  * from a SAXParserFactory.</p>
51  * </p>
52  *
53  * @deprecated This interface has been replaced by the
54  * {@link com.sun.org.apache.xml.internal.resolver.tools.ResolvingXMLReader} for SAX2.
55  * @see CatalogResolver
56  * @see org.xml.sax.Parser
57  *
58  * @author Norman Walsh
59  * <a HREF="mailto:Norman.Walsh@Sun.COM">Norman.Walsh@Sun.COM</a>
60  *
61  * @version 1.0
62  */

63 public class ResolvingParser
64   implements Parser JavaDoc, DTDHandler JavaDoc, DocumentHandler JavaDoc, EntityResolver JavaDoc {
65   /** Make the parser Namespace aware? */
66   public static boolean namespaceAware = true;
67
68   /** Make the parser validating? */
69   public static boolean validating = false;
70
71   /** Suppress explanatory message?
72    *
73    * @see #parse(InputSource)
74    */

75   public static boolean suppressExplanation = false;
76
77   /** The underlying parser. */
78   private SAXParser JavaDoc saxParser = null;
79
80   /** The underlying reader. */
81   private Parser JavaDoc parser = null;
82
83   /** The underlying DocumentHandler. */
84   private DocumentHandler JavaDoc documentHandler = null;
85
86   /** The underlying DTDHandler. */
87   private DTDHandler JavaDoc dtdHandler = null;
88
89   /** The manager for the underlying resolver. */
90   private CatalogManager catalogManager = CatalogManager.getStaticManager();
91
92   /** The underlying catalog resolver. */
93   private CatalogResolver catalogResolver = null;
94
95   /** A separate resolver for oasis-xml-pi catalogs. */
96   private CatalogResolver piCatalogResolver = null;
97
98   /** Are we in the prolog? Is an oasis-xml-catalog PI valid now? */
99   private boolean allowXMLCatalogPI = false;
100
101   /** Has an oasis-xml-catalog PI been seen? */
102   private boolean oasisXMLCatalogPI = false;
103
104   /** The base URI of the input document, if known. */
105   private URL JavaDoc baseURL = null;
106
107   /** Constructor. */
108   public ResolvingParser() {
109     initParser();
110   }
111
112   /** Constructor. */
113   public ResolvingParser(CatalogManager manager) {
114     catalogManager = manager;
115     initParser();
116   }
117
118   /** Initialize the parser. */
119   private void initParser() {
120     catalogResolver = new CatalogResolver(catalogManager);
121
122     SAXParserFactory JavaDoc spf = SAXParserFactory.newInstance();
123     spf.setNamespaceAware(namespaceAware);
124     spf.setValidating(validating);
125
126     try {
127       saxParser = spf.newSAXParser();
128       parser = saxParser.getParser();
129       documentHandler = null;
130       dtdHandler = null;
131     } catch (Exception JavaDoc ex) {
132       ex.printStackTrace();
133     }
134   }
135
136   /** Return the Catalog being used. */
137   public Catalog getCatalog() {
138     return catalogResolver.getCatalog();
139   }
140
141   /**
142    * SAX Parser API.
143    *
144    * <p>Note that the JAXP 1.1ea2 parser crashes with an InternalError if
145    * it encounters a system identifier that appears to be a relative URI
146    * that begins with a slash. For example, the declaration:</p>
147    *
148    * <pre>
149    * &lt;!DOCTYPE book SYSTEM "/path/to/dtd/on/my/system/docbookx.dtd">
150    * </pre>
151    *
152    * <p>would cause such an error. As a convenience, this method catches
153    * that error and prints an explanation. (Unfortunately, it's not possible
154    * to identify the particular system identifier that causes the problem.)
155    * </p>
156    *
157    * <p>The underlying error is forwarded after printing the explanatory
158    * message. The message is only every printed once and if
159    * <code>suppressExplanation</code> is set to <code>false</code> before
160    * parsing, it will never be printed.</p>
161    */

162   public void parse(InputSource JavaDoc input)
163     throws IOException JavaDoc,
164        SAXException JavaDoc {
165     setupParse(input.getSystemId());
166     try {
167       parser.parse(input);
168     } catch (InternalError JavaDoc ie) {
169       explain(input.getSystemId());
170       throw ie;
171     }
172   }
173
174   /** SAX Parser API.
175    *
176    * @see #parse(InputSource)
177    */

178   public void parse(String JavaDoc systemId)
179     throws IOException JavaDoc,
180        SAXException JavaDoc {
181     setupParse(systemId);
182     try {
183       parser.parse(systemId);
184     } catch (InternalError JavaDoc ie) {
185       explain(systemId);
186       throw ie;
187     }
188   }
189
190   /** SAX Parser API. */
191   public void setDocumentHandler(DocumentHandler JavaDoc handler) {
192     documentHandler = handler;
193   }
194
195   /** SAX Parser API. */
196   public void setDTDHandler(DTDHandler JavaDoc handler) {
197     dtdHandler = handler;
198   }
199
200   /**
201    * SAX Parser API.
202    *
203    * <p>The purpose of this class is to implement an entity resolver.
204    * Attempting to set a different one is pointless (and ignored).</p>
205    */

206   public void setEntityResolver(EntityResolver JavaDoc resolver) {
207     // nop
208
}
209
210   /** SAX Parser API. */
211   public void setErrorHandler(ErrorHandler JavaDoc handler) {
212     parser.setErrorHandler(handler);
213   }
214
215   /** SAX Parser API. */
216   public void setLocale(Locale JavaDoc locale) throws SAXException JavaDoc {
217     parser.setLocale(locale);
218   }
219
220   /** SAX DocumentHandler API. */
221   public void characters(char[] ch, int start, int length)
222     throws SAXException JavaDoc {
223     if (documentHandler != null) {
224       documentHandler.characters(ch,start,length);
225     }
226   }
227
228   /** SAX DocumentHandler API. */
229   public void endDocument() throws SAXException JavaDoc {
230     if (documentHandler != null) {
231       documentHandler.endDocument();
232     }
233   }
234
235   /** SAX DocumentHandler API. */
236   public void endElement(String JavaDoc name) throws SAXException JavaDoc {
237     if (documentHandler != null) {
238       documentHandler.endElement(name);
239     }
240   }
241
242   /** SAX DocumentHandler API. */
243   public void ignorableWhitespace(char[] ch, int start, int length)
244     throws SAXException JavaDoc {
245     if (documentHandler != null) {
246       documentHandler.ignorableWhitespace(ch,start,length);
247     }
248   }
249
250   /** SAX DocumentHandler API. */
251   public void processingInstruction(String JavaDoc target, String JavaDoc pidata)
252     throws SAXException JavaDoc {
253
254     if (target.equals("oasis-xml-catalog")) {
255       URL JavaDoc catalog = null;
256       String JavaDoc data = pidata;
257
258       int pos = data.indexOf("catalog=");
259       if (pos >= 0) {
260     data = data.substring(pos+8);
261     if (data.length() > 1) {
262       String JavaDoc quote = data.substring(0,1);
263       data = data.substring(1);
264       pos = data.indexOf(quote);
265       if (pos >= 0) {
266         data = data.substring(0, pos);
267         try {
268           if (baseURL != null) {
269         catalog = new URL JavaDoc(baseURL, data);
270           } else {
271         catalog = new URL JavaDoc(data);
272           }
273         } catch (MalformedURLException JavaDoc mue) {
274           // nevermind
275
}
276       }
277     }
278       }
279
280       if (allowXMLCatalogPI) {
281     if (catalogManager.getAllowOasisXMLCatalogPI()) {
282       catalogManager.debug.message(4,"oasis-xml-catalog PI", pidata);
283
284       if (catalog != null) {
285         try {
286           catalogManager.debug.message(4,"oasis-xml-catalog", catalog.toString());
287           oasisXMLCatalogPI = true;
288
289           if (piCatalogResolver == null) {
290         piCatalogResolver = new CatalogResolver(true);
291           }
292
293           piCatalogResolver.getCatalog().parseCatalog(catalog.toString());
294         } catch (Exception JavaDoc e) {
295           catalogManager.debug.message(3, "Exception parsing oasis-xml-catalog: "
296                 + catalog.toString());
297         }
298       } else {
299         catalogManager.debug.message(3, "PI oasis-xml-catalog unparseable: " + pidata);
300       }
301     } else {
302       catalogManager.debug.message(4,"PI oasis-xml-catalog ignored: " + pidata);
303     }
304       } else {
305     catalogManager.debug.message(3, "PI oasis-xml-catalog occurred in an invalid place: "
306               + pidata);
307       }
308     } else {
309       if (documentHandler != null) {
310     documentHandler.processingInstruction(target, pidata);
311       }
312     }
313   }
314
315   /** SAX DocumentHandler API. */
316   public void setDocumentLocator(Locator JavaDoc locator) {
317     if (documentHandler != null) {
318       documentHandler.setDocumentLocator(locator);
319     }
320   }
321
322   /** SAX DocumentHandler API. */
323   public void startDocument() throws SAXException JavaDoc {
324     if (documentHandler != null) {
325       documentHandler.startDocument();
326     }
327   }
328
329   /** SAX DocumentHandler API. */
330   public void startElement(String JavaDoc name, AttributeList JavaDoc atts)
331     throws SAXException JavaDoc {
332     allowXMLCatalogPI = false;
333     if (documentHandler != null) {
334       documentHandler.startElement(name,atts);
335     }
336   }
337
338   /** SAX DTDHandler API. */
339   public void notationDecl (String JavaDoc name, String JavaDoc publicId, String JavaDoc systemId)
340     throws SAXException JavaDoc {
341     allowXMLCatalogPI = false;
342     if (dtdHandler != null) {
343       dtdHandler.notationDecl(name,publicId,systemId);
344     }
345   }
346
347   /** SAX DTDHandler API. */
348   public void unparsedEntityDecl (String JavaDoc name,
349                   String JavaDoc publicId,
350                   String JavaDoc systemId,
351                   String JavaDoc notationName)
352     throws SAXException JavaDoc {
353     allowXMLCatalogPI = false;
354     if (dtdHandler != null) {
355       dtdHandler.unparsedEntityDecl (name, publicId, systemId, notationName);
356     }
357   }
358
359   /**
360    * Implements the <code>resolveEntity</code> method
361    * for the SAX interface, using an underlying CatalogResolver
362    * to do the real work.
363    */

364   public InputSource JavaDoc resolveEntity (String JavaDoc publicId, String JavaDoc systemId) {
365     allowXMLCatalogPI = false;
366     String JavaDoc resolved = catalogResolver.getResolvedEntity(publicId, systemId);
367
368     if (resolved == null && piCatalogResolver != null) {
369       resolved = piCatalogResolver.getResolvedEntity(publicId, systemId);
370     }
371
372     if (resolved != null) {
373       try {
374     InputSource JavaDoc iSource = new InputSource JavaDoc(resolved);
375     iSource.setPublicId(publicId);
376
377     // Ideally this method would not attempt to open the
378
// InputStream, but there is a bug (in Xerces, at least)
379
// that causes the parser to mistakenly open the wrong
380
// system identifier if the returned InputSource does
381
// not have a byteStream.
382
//
383
// It could be argued that we still shouldn't do this here,
384
// but since the purpose of calling the entityResolver is
385
// almost certainly to open the input stream, it seems to
386
// do little harm.
387
//
388
URL JavaDoc url = new URL JavaDoc(resolved);
389     InputStream JavaDoc iStream = url.openStream();
390     iSource.setByteStream(iStream);
391
392     return iSource;
393       } catch (Exception JavaDoc e) {
394     catalogManager.debug.message(1, "Failed to create InputSource", resolved);
395     return null;
396       }
397     } else {
398       return null;
399     }
400   }
401
402   /** Setup for parsing. */
403   private void setupParse(String JavaDoc systemId) {
404     allowXMLCatalogPI = true;
405     parser.setEntityResolver(this);
406     parser.setDocumentHandler(this);
407     parser.setDTDHandler(this);
408
409     URL JavaDoc cwd = null;
410
411     try {
412       cwd = FileURL.makeURL("basename");
413     } catch (MalformedURLException JavaDoc mue) {
414       cwd = null;
415     }
416
417     try {
418       baseURL = new URL JavaDoc(systemId);
419     } catch (MalformedURLException JavaDoc mue) {
420       if (cwd != null) {
421     try {
422       baseURL = new URL JavaDoc(cwd, systemId);
423     } catch (MalformedURLException JavaDoc mue2) {
424       // give up
425
baseURL = null;
426     }
427       } else {
428     // give up
429
baseURL = null;
430       }
431     }
432   }
433
434   /** Provide one possible explanation for an InternalError. */
435   private void explain(String JavaDoc systemId) {
436     if (!suppressExplanation) {
437       System.out.println("Parser probably encountered bad URI in " + systemId);
438       System.out.println("For example, replace '/some/uri' with 'file:/some/uri'.");
439     }
440   }
441 }
442
443
Popular Tags