Imported GNU Classpath 0.20
[official-gcc.git] / libjava / classpath / gnu / xml / dom / ls / DomLSParser.java
blob7ac4cc749fc5ff32b47296763f2d712d819e8f73
1 /* DomLSParser.java --
2 Copyright (C) 1999,2000,2001 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
38 package gnu.xml.dom.ls;
40 import java.io.File;
41 import java.io.InputStream;
42 import java.io.IOException;
43 import java.net.MalformedURLException;
44 import java.net.URL;
45 import java.util.Arrays;
46 import java.util.List;
47 import javax.xml.parsers.ParserConfigurationException;
48 import javax.xml.parsers.SAXParser;
49 import javax.xml.parsers.SAXParserFactory;
50 import org.w3c.dom.Document;
51 import org.w3c.dom.DOMConfiguration;
52 import org.w3c.dom.DOMException;
53 import org.w3c.dom.DOMStringList;
54 import org.w3c.dom.Node;
55 import org.w3c.dom.ls.DOMImplementationLS;
56 import org.w3c.dom.ls.LSException;
57 import org.w3c.dom.ls.LSInput;
58 import org.w3c.dom.ls.LSParser;
59 import org.w3c.dom.ls.LSParserFilter;
60 import org.xml.sax.EntityResolver;
61 import org.xml.sax.ErrorHandler;
62 import org.xml.sax.InputSource;
63 import org.xml.sax.SAXException;
64 import org.xml.sax.SAXNotRecognizedException;
65 import org.xml.sax.SAXParseException;
66 import org.xml.sax.XMLReader;
67 import gnu.xml.dom.DomDocument;
68 import gnu.xml.dom.DomDOMException;
70 /**
71 * Parser implementation for GNU DOM.
73 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
75 public class DomLSParser
76 implements LSParser, DOMConfiguration, DOMStringList, ErrorHandler
79 private static final List SUPPORTED_PARAMETERS
80 = Arrays.asList(new String[] { "cdata-sections",
81 "comments",
82 "element-content-whitespace",
83 "namespaces",
84 "expand-entity-references",
85 "coalescing",
86 "validating",
87 "xinclude-aware",
88 "entity-resolver",
89 "error-handler" });
91 private LSParserFilter filter;
92 private final boolean async;
93 private String schemaType;
94 private SAXEventSink eventSink;
95 private SAXParserFactory factory;
96 private XMLReader reader;
98 private boolean namespaceAware = true;
99 private boolean ignoreWhitespace;
100 private boolean expandEntityReferences;
101 private boolean ignoreComments;
102 private boolean coalescing;
103 private boolean validating;
104 private boolean xIncludeAware;
105 private EntityResolver entityResolver;
106 private ErrorHandler errorHandler;
108 public DomLSParser(short mode, String schemaType)
109 throws DOMException
111 switch (mode)
113 case DOMImplementationLS.MODE_ASYNCHRONOUS:
114 async = true;
115 break;
116 case DOMImplementationLS.MODE_SYNCHRONOUS:
117 async = false;
118 break;
119 default:
120 throw new DomDOMException(DOMException.NOT_SUPPORTED_ERR);
122 // TODO schemaType
123 this.schemaType = schemaType;
124 factory = SAXParserFactory.newInstance();
127 // -- LSParser --
129 public DOMConfiguration getDomConfig()
131 return this;
134 public LSParserFilter getFilter()
136 return filter;
139 public void setFilter(LSParserFilter filter)
141 this.filter = filter;
144 public boolean getAsync()
146 return async;
149 public boolean getBusy()
151 return eventSink != null;
154 public Document parse(LSInput input)
155 throws DOMException, LSException
157 if (async)
159 return doParse(input);
161 else
163 synchronized (this)
165 return doParse(input);
170 public Document parseURI(String uri)
171 throws DOMException, LSException
173 LSInput input = new DomLSInput();
174 input.setSystemId(uri);
175 return parse(input);
178 public Node parseWithContext(LSInput input, Node context, short action)
179 throws DOMException, LSException
181 Document doc = (context.getNodeType() == Node.DOCUMENT_NODE) ?
182 (Document) context : context.getOwnerDocument();
183 input.setBaseURI(doc.getDocumentURI());
184 // TODO use namespaces defined on context node
185 Document ret = parse(input);
186 Node root = ret.getDocumentElement();
187 root = doc.adoptNode(root);
188 switch (action)
190 case ACTION_APPEND_AS_CHILDREN:
191 context.appendChild(root);
192 break;
193 case ACTION_REPLACE_CHILDREN:
194 Node c1 = context.getFirstChild();
195 while (c1 != null)
197 Node next = c1.getNextSibling();
198 context.removeChild(c1);
199 c1 = next;
201 context.appendChild(root);
202 break;
203 case ACTION_INSERT_BEFORE:
204 Node p1 = context.getParentNode();
205 p1.insertBefore(root, context);
206 break;
207 case ACTION_INSERT_AFTER:
208 Node p2 = context.getParentNode();
209 Node r1 = context.getNextSibling();
210 if (r1 == null)
212 p2.appendChild(root);
214 else
216 p2.insertBefore(root, r1);
218 break;
219 case ACTION_REPLACE:
220 Node p3 = context.getParentNode();
221 Node r2 = context.getNextSibling();
222 p3.removeChild(context);
223 if (r2 == null)
225 p3.appendChild(root);
227 else
229 p3.insertBefore(root, r2);
231 break;
233 return root;
236 public void abort()
238 if (eventSink != null)
240 eventSink.interrupt();
244 private Document doParse(LSInput input)
245 throws DOMException, LSException
247 // create event sink
248 if (eventSink != null)
250 throw new LSException(LSException.PARSE_ERR, "parse in progress");
252 InputSource source = getInputSource(input);
253 eventSink = (filter == null) ? new SAXEventSink() :
254 new FilteredSAXEventSink(filter);
255 // configure sink
256 eventSink.namespaceAware = namespaceAware;
257 eventSink.ignoreWhitespace = ignoreWhitespace;
258 eventSink.expandEntityReferences = expandEntityReferences;
259 eventSink.ignoreComments = ignoreComments;
260 eventSink.coalescing = coalescing;
261 // get and configure reader
262 XMLReader reader = getXMLReader();
263 eventSink.reader = reader;
266 reader.setContentHandler(eventSink);
267 reader.setDTDHandler(eventSink);
268 reader.setProperty("http://xml.org/sax/properties/lexical-handler",
269 eventSink);
270 reader.setProperty("http://xml.org/sax/properties/declaration-handler",
271 eventSink);
272 reader.setFeature("http://xml.org/sax/features/namespaces",
273 namespaceAware);
274 reader.setFeature("http://xml.org/sax/features/namespace-prefixes",
275 true);
276 reader.setFeature("http://xml.org/sax/features/validation",
277 validating);
280 reader.setFeature("http://xml.org/sax/features/use-attributes2",
281 true);
283 catch (SAXNotRecognizedException e)
285 // ignore
289 reader.setFeature("http://xml.org/sax/features/external-general-entities",
290 true);
292 catch (SAXNotRecognizedException e)
294 // ignore
296 reader.setEntityResolver(entityResolver);
297 reader.setErrorHandler(errorHandler);
298 // parse
299 reader.parse(source);
301 catch (DOMException e)
303 reader = null;
304 eventSink = null;
305 throw e;
307 catch (SAXException e)
309 reader = null;
310 eventSink = null;
311 throw new DomLSException(LSException.PARSE_ERR, e);
313 catch (IOException e)
315 reader = null;
316 eventSink = null;
317 throw new DomLSException(LSException.PARSE_ERR, e);
319 // return document
320 Document ret = eventSink.doc;
321 String systemId = input.getSystemId();
322 if (systemId != null && ret instanceof DomDocument)
324 ((DomDocument) ret).setDocumentURI(systemId);
326 eventSink = null;
327 return ret;
330 private XMLReader getXMLReader()
331 throws LSException
333 if (reader == null)
335 factory.setNamespaceAware(namespaceAware);
336 factory.setValidating(validating);
337 factory.setXIncludeAware(xIncludeAware);
340 SAXParser parser = factory.newSAXParser();
341 reader = parser.getXMLReader();
343 catch (ParserConfigurationException e)
345 throw new DomLSException(LSException.PARSE_ERR, e);
347 catch (SAXException e)
349 throw new DomLSException(LSException.PARSE_ERR, e);
352 return reader;
355 private InputSource getInputSource(LSInput input)
356 throws LSException
358 InputSource source = null;
359 String systemId = input.getSystemId();
360 InputStream in = input.getByteStream();
361 if (in != null)
363 source = new InputSource(in);
364 source.setSystemId(systemId);
366 if (source == null && entityResolver != null)
368 String publicId = input.getPublicId();
371 source = entityResolver.resolveEntity(publicId, systemId);
373 catch (SAXException e)
375 throw new DomLSException(LSException.PARSE_ERR, e);
377 catch (IOException e)
379 throw new DomLSException(LSException.PARSE_ERR, e);
382 if (source == null)
384 URL url = null;
385 String base = input.getBaseURI();
390 URL baseURL = (base == null) ? null : new URL(base);
391 url = (baseURL == null) ? new URL(systemId) :
392 new URL(baseURL, systemId);
394 catch (MalformedURLException e)
396 File baseFile = (base == null) ? null : new File(base);
397 url = (baseFile == null) ? new File(systemId).toURL() :
398 new File(baseFile, systemId).toURL();
400 in = url.openStream();
401 systemId = url.toString();
402 source = new InputSource(in);
403 source.setSystemId(systemId);
405 catch (IOException e)
407 throw new DomLSException(LSException.PARSE_ERR, e);
410 return source;
413 // -- DOMConfiguration --
415 public void setParameter(String name, Object value)
416 throws DOMException
418 name = name.toLowerCase();
419 if ("cdata-sections".equals(name))
421 coalescing = !((Boolean) value).booleanValue();
423 else if ("comments".equals(name))
425 ignoreComments = !((Boolean) value).booleanValue();
427 else if ("element-content-whitespace".equals(name))
429 ignoreWhitespace = !((Boolean) value).booleanValue();
431 else if ("namespaces".equals(name))
433 namespaceAware = ((Boolean) value).booleanValue();
435 else if ("expand-entity-references".equals(name))
437 expandEntityReferences = ((Boolean) value).booleanValue();
439 else if ("coalescing".equals(name))
441 coalescing = ((Boolean) value).booleanValue();
443 else if ("validating".equals(name))
445 validating = ((Boolean) value).booleanValue();
447 else if ("xinclude-aware".equals(name))
449 xIncludeAware = ((Boolean) value).booleanValue();
451 else if ("entity-resolver".equals(name))
453 entityResolver = (EntityResolver) value;
455 else if ("error-handler".equals(name))
457 errorHandler = (ErrorHandler) value;
459 else
461 throw new DomDOMException(DOMException.NOT_SUPPORTED_ERR);
463 // invalidate reader, a new one will be created
464 reader = null;
467 public Object getParameter(String name)
468 throws DOMException
470 name = name.toLowerCase();
471 if ("cdata-sections".equals(name))
473 return coalescing ? Boolean.FALSE : Boolean.TRUE;
475 else if ("comments".equals(name))
477 return ignoreComments ? Boolean.FALSE : Boolean.TRUE;
479 else if ("element-content-whitespace".equals(name))
481 return ignoreWhitespace ? Boolean.FALSE : Boolean.TRUE;
483 else if ("namespaces".equals(name))
485 return namespaceAware ? Boolean.TRUE : Boolean.FALSE;
487 else if ("expand-entity-references".equals(name))
489 return expandEntityReferences ? Boolean.TRUE : Boolean.FALSE;
491 else if ("coalescing".equals(name))
493 return coalescing ? Boolean.TRUE : Boolean.FALSE;
495 else if ("validating".equals(name))
497 return validating ? Boolean.TRUE : Boolean.FALSE;
499 else if ("xinclude-aware".equals(name))
501 return xIncludeAware ? Boolean.TRUE : Boolean.FALSE;
503 else if ("entity-resolver".equals(name))
505 return entityResolver;
507 else if ("error-handler".equals(name))
509 return errorHandler;
511 else
513 throw new DomDOMException(DOMException.NOT_SUPPORTED_ERR);
517 public boolean canSetParameter(String name, Object value)
519 return contains(name);
522 public DOMStringList getParameterNames()
524 return this;
527 // -- DOMStringList --
529 public String item(int i)
531 return (String) SUPPORTED_PARAMETERS.get(i);
534 public int getLength()
536 return SUPPORTED_PARAMETERS.size();
539 public boolean contains(String str)
541 return SUPPORTED_PARAMETERS.contains(str);
544 // -- ErrorHandler --
546 public void warning(SAXParseException e)
547 throws SAXException
549 if (errorHandler != null)
551 errorHandler.warning(e);
555 public void error(SAXParseException e)
556 throws SAXException
558 if (errorHandler != null)
560 errorHandler.error(e);
564 public void fatalError(SAXParseException e)
565 throws SAXException
567 if (errorHandler != null)
569 errorHandler.fatalError(e);
571 abort();