KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ant > internal > ui > dtd > Parser


1 /*******************************************************************************
2  * Copyright (c) 2002, 2005 Object Factory Inc.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * Object Factory Inc. - Initial implementation
10  *******************************************************************************/

11 package org.eclipse.ant.internal.ui.dtd;
12
13 import java.io.IOException JavaDoc;
14 import java.io.Reader JavaDoc;
15 import java.io.StringReader JavaDoc;
16
17 import javax.xml.parsers.ParserConfigurationException JavaDoc;
18 import javax.xml.parsers.SAXParser JavaDoc;
19 import javax.xml.parsers.SAXParserFactory JavaDoc;
20
21 import org.eclipse.ant.internal.ui.dtd.schema.SchemaFactory;
22 import org.xml.sax.EntityResolver JavaDoc;
23 import org.xml.sax.InputSource JavaDoc;
24 import org.xml.sax.SAXException JavaDoc;
25 import org.xml.sax.SAXNotRecognizedException JavaDoc;
26 import org.xml.sax.SAXNotSupportedException JavaDoc;
27 import org.xml.sax.XMLReader JavaDoc;
28 import org.xml.sax.ext.DeclHandler JavaDoc;
29
30
31 /**
32  * Simple parser for DTDs. Returns ISchema representing the DTD.
33  *
34  * To parse a DTD, you must parse an XML document. The <code>parseDTD()</code>
35  * method builds a temporary XML document in memory that refers to or includes
36  * the DTD.
37  *
38  * There is no dependency in this package on any code outside the package except
39  * XMLReader.
40  *
41  * To hide the underlying parser, XML parser exceptions are wrapped by a
42  * ParseError. Unless debugging, the two string constants are sufficient to
43  * determine the cause of the error.
44  * @author Bob Foster
45  */

46 public class Parser {
47     
48     /** ParseError message when system parser doesn't do the job */
49     public static final String JavaDoc NOT_SUPPORTED = AntDTDMessages.Parser_XML_parser_does_not_support_DeclHandler_1;
50     /** ParseError message for a well-formed or validation error in XML or DTD.
51      * Currently not returned. */

52     public static final String JavaDoc PARSE_ERROR = AntDTDMessages.Parser_Error_parsing_XML_document_or_DTD_2;
53     
54     private static final String JavaDoc INTERNAL = "internal://usereader.objfac.com"; //$NON-NLS-1$
55

56     /**
57      * Parse the XML document at the input source and return a document walker
58      * that can be used to validate any document with the same DTD (internal and
59      * external) or provide user assistance for this document.
60      * @param inputSource Source for XML document to start DTD parse. Must
61      * contain a DOCTYPE declaration with internal or external subset, or both.
62      * @param entityResolver EntityResolver or null.
63      * @return schema for document.
64      * @throws ParseError for NOT_SUPPORTED or PARSE_ERROR.
65      * @throws IOException
66      */

67     public ISchema parse(InputSource JavaDoc inputSource, EntityResolver JavaDoc entityResolver) throws ParseError, IOException JavaDoc {
68         XMLReader JavaDoc parser = null;
69         SchemaFactory factory = new SchemaFactory();
70         try {
71             parser = getXMLReader();
72             DeclHandler JavaDoc handler = factory;
73             parser.setProperty("http://xml.org/sax/properties/declaration-handler", handler); //$NON-NLS-1$
74
if (entityResolver != null) {
75                 parser.setEntityResolver(entityResolver);
76             }
77             parser.parse(inputSource);
78         } catch (SAXNotRecognizedException JavaDoc e) {
79             throw new ParseError(NOT_SUPPORTED);
80         } catch (SAXNotSupportedException JavaDoc e) {
81             throw new ParseError(NOT_SUPPORTED);
82         } catch (SAXException JavaDoc e) {
83             // Don't care about errors in XML, so just fall thru.
84
// If parse failed in DTD, may have incomplete schema,
85
// but this is better than no schema.
86
factory.setErrorException(e);
87         }
88
89         return factory.getSchema();
90     }
91     
92     private XMLReader JavaDoc getXMLReader() throws ParseError {
93         SAXParser JavaDoc parser = null;
94         try {
95             parser = SAXParserFactory.newInstance().newSAXParser();
96             return parser.getXMLReader();
97         } catch (ParserConfigurationException JavaDoc e) {
98             throw new ParseError(e.getMessage());
99         } catch (SAXException JavaDoc e) {
100             throw new ParseError(e.getMessage());
101         }
102     }
103     
104     /**
105      * Parse the XML document at the argument URL and return a document walker
106      * that can be used to validate any document with the same DTD (internal
107      * and external) or provide user assistance for this document.
108      * @param url Of XML document to start DTD parse. Must contain a DOCTYPE
109      * declaration with internal or external subset, or both.
110      * @return IWalker that can be used to traverse document.
111      * @throws ParseError for NOT_SUPPORTED or PARSE_ERROR.
112      * @throws IOException
113      */

114     public ISchema parse(String JavaDoc url) throws ParseError, IOException JavaDoc {
115         return parse(new InputSource JavaDoc(url), null);
116     }
117     
118     /**
119      * Parse the XML document using the argument reader and return a document
120      * walker that can be used to validate any document with the same DTD
121      * (internal and external) or provide user assistance for this document.
122      * @param reader Reader for XML document to start DTD parse. Must contain a
123      * DOCTYPE declaration with internal or external subset, or both.
124      * @return IWalker that can be used to traverse document.
125      * @throws ParseError for NOT_SUPPORTED or PARSE_ERROR.
126      * @throws IOException
127      */

128     public ISchema parse(Reader JavaDoc reader) throws ParseError, IOException JavaDoc {
129         return parse(new InputSource JavaDoc(reader), null);
130     }
131     
132     /**
133      * Parse the DTD with the given public and system ids and return a document
134      * walker that can be used to validate or provide user assistance for any
135      * document with the same external DTD and no internal subset.
136      * @param pub PUBLIC id of DTD.
137      * @param sys SYSTEM id of DTD.
138      * @param root Plausible root element qname. Any name will do but a
139      * name that will not cause a validation error is preferred.
140      * @return IWalker that can be used to traverse document.
141      * @throws ParseError for NOT_SUPPORTED or PARSE_ERROR.
142      * @throws IOException
143      */

144     public ISchema parseDTD(String JavaDoc pub, String JavaDoc sys, String JavaDoc root) throws ParseError, IOException JavaDoc {
145         return parse(new InputSource JavaDoc(new DTDReader(pub, sys, root)), null);
146     }
147     
148     /**
149      * Parse the DTD from the reader and return a document walker that can be
150      * used to validate or provide user assistance for any document with the
151      * same external DTD and no internal subset.
152      * @param reader Reader for external subset DTD
153      * @param root Plausible root element qname. Any name will do but a
154      * name that will not cause a validation error is preferred.
155      * @return ISchema that can be used to traverse document.
156      * @throws ParseError for NOT_SUPPORTED or PARSE_ERROR.
157      * @throws IOException
158      */

159     public ISchema parseDTD(Reader JavaDoc reader, String JavaDoc root) throws ParseError, IOException JavaDoc {
160         return parse(new InputSource JavaDoc(new DTDReader(INTERNAL, INTERNAL, root)), new DTDEntityResolver(reader));
161     }
162     
163     private static class DTDReader extends Reader JavaDoc {
164         private Reader JavaDoc fDelegate;
165         
166         public DTDReader(String JavaDoc pub, String JavaDoc sys, String JavaDoc root) {
167             String JavaDoc document = "<!DOCTYPE "+root+" PUBLIC '"+pub+"' '"+sys+"'><"+root+"/>"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
168
fDelegate = new StringReader JavaDoc(document);
169         }
170         
171         /**
172          * @see java.io.Reader#close()
173          */

174         public void close() throws IOException JavaDoc {
175             fDelegate.close();
176         }
177
178         /* (non-Javadoc)
179          * @see java.io.Reader#read(char[], int, int)
180          */

181         public int read(char[] cbuf, int off, int len) throws IOException JavaDoc {
182             return fDelegate.read(cbuf, off, len);
183         }
184     }
185     
186     private static class DTDEntityResolver implements EntityResolver JavaDoc {
187         private Reader JavaDoc reader;
188         public DTDEntityResolver(Reader JavaDoc reader) {
189             this.reader = reader;
190         }
191         /**
192          * @see org.xml.sax.EntityResolver#resolveEntity(java.lang.String, java.lang.String)
193          */

194         public InputSource JavaDoc resolveEntity(String JavaDoc publicId, String JavaDoc systemId) {
195             if (publicId.equals(INTERNAL) && systemId.equals(INTERNAL))
196                 return new InputSource JavaDoc(reader);
197             return null;
198         }
199     }
200 }
Popular Tags