Merge from the pain train
[official-gcc.git] / libjava / gnu / xml / dom / ls / DomLSParser.java
blob489777fc913d75da82b458d75b381bd7aeb7496d
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., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 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();
265 reader.setContentHandler(eventSink);
266 reader.setDTDHandler(eventSink);
267 reader.setProperty("http://xml.org/sax/properties/lexical-handler",
268 eventSink);
269 reader.setProperty("http://xml.org/sax/properties/declaration-handler",
270 eventSink);
271 reader.setFeature("http://xml.org/sax/features/namespaces",
272 namespaceAware);
273 reader.setFeature("http://xml.org/sax/features/namespace-prefixes",
274 true);
275 reader.setFeature("http://xml.org/sax/features/validation",
276 validating);
279 reader.setFeature("http://xml.org/sax/features/use-attributes2",
280 true);
282 catch (SAXNotRecognizedException e)
284 // ignore
288 reader.setFeature("http://xml.org/sax/features/external-general-entities",
289 true);
291 catch (SAXNotRecognizedException e)
293 // ignore
295 reader.setEntityResolver(entityResolver);
296 reader.setErrorHandler(errorHandler);
297 // parse
298 reader.parse(source);
300 catch (DOMException e)
302 reader = null;
303 eventSink = null;
304 throw e;
306 catch (SAXException e)
308 reader = null;
309 eventSink = null;
310 throw new DomLSException(LSException.PARSE_ERR, e);
312 catch (IOException e)
314 reader = null;
315 eventSink = null;
316 throw new DomLSException(LSException.PARSE_ERR, e);
318 // return document
319 Document ret = eventSink.doc;
320 String systemId = input.getSystemId();
321 if (systemId != null && ret instanceof DomDocument)
323 ((DomDocument) ret).setDocumentURI(systemId);
325 eventSink = null;
326 return ret;
329 private XMLReader getXMLReader()
330 throws LSException
332 if (reader == null)
334 factory.setNamespaceAware(namespaceAware);
335 factory.setValidating(validating);
336 factory.setXIncludeAware(xIncludeAware);
339 SAXParser parser = factory.newSAXParser();
340 reader = parser.getXMLReader();
342 catch (ParserConfigurationException e)
344 throw new DomLSException(LSException.PARSE_ERR, e);
346 catch (SAXException e)
348 throw new DomLSException(LSException.PARSE_ERR, e);
351 return reader;
354 private InputSource getInputSource(LSInput input)
355 throws LSException
357 InputSource source = null;
358 String systemId = input.getSystemId();
359 InputStream in = input.getByteStream();
360 if (in != null)
362 source = new InputSource(in);
363 source.setSystemId(systemId);
365 if (source == null && entityResolver != null)
367 String publicId = input.getPublicId();
370 source = entityResolver.resolveEntity(publicId, systemId);
372 catch (SAXException e)
374 throw new DomLSException(LSException.PARSE_ERR, e);
376 catch (IOException e)
378 throw new DomLSException(LSException.PARSE_ERR, e);
381 if (source == null)
383 URL url = null;
384 String base = input.getBaseURI();
389 URL baseURL = (base == null) ? null : new URL(base);
390 url = (baseURL == null) ? new URL(systemId) :
391 new URL(baseURL, systemId);
393 catch (MalformedURLException e)
395 File baseFile = (base == null) ? null : new File(base);
396 url = (baseFile == null) ? new File(systemId).toURL() :
397 new File(baseFile, systemId).toURL();
399 in = url.openStream();
400 systemId = url.toString();
401 source = new InputSource(in);
402 source.setSystemId(systemId);
404 catch (IOException e)
406 throw new DomLSException(LSException.PARSE_ERR, e);
409 return source;
412 // -- DOMConfiguration --
414 public void setParameter(String name, Object value)
415 throws DOMException
417 name = name.toLowerCase();
418 if ("cdata-sections".equals(name))
420 coalescing = !((Boolean) value).booleanValue();
422 else if ("comments".equals(name))
424 ignoreComments = !((Boolean) value).booleanValue();
426 else if ("element-content-whitespace".equals(name))
428 ignoreWhitespace = !((Boolean) value).booleanValue();
430 else if ("namespaces".equals(name))
432 namespaceAware = ((Boolean) value).booleanValue();
434 else if ("expand-entity-references".equals(name))
436 expandEntityReferences = ((Boolean) value).booleanValue();
438 else if ("coalescing".equals(name))
440 coalescing = ((Boolean) value).booleanValue();
442 else if ("validating".equals(name))
444 validating = ((Boolean) value).booleanValue();
446 else if ("xinclude-aware".equals(name))
448 xIncludeAware = ((Boolean) value).booleanValue();
450 else if ("entity-resolver".equals(name))
452 entityResolver = (EntityResolver) value;
454 else if ("error-handler".equals(name))
456 errorHandler = (ErrorHandler) value;
458 else
460 throw new DomDOMException(DOMException.NOT_SUPPORTED_ERR);
462 // invalidate reader, a new one will be created
463 reader = null;
466 public Object getParameter(String name)
467 throws DOMException
469 name = name.toLowerCase();
470 if ("cdata-sections".equals(name))
472 return coalescing ? Boolean.FALSE : Boolean.TRUE;
474 else if ("comments".equals(name))
476 return ignoreComments ? Boolean.FALSE : Boolean.TRUE;
478 else if ("element-content-whitespace".equals(name))
480 return ignoreWhitespace ? Boolean.FALSE : Boolean.TRUE;
482 else if ("namespaces".equals(name))
484 return namespaceAware ? Boolean.TRUE : Boolean.FALSE;
486 else if ("expand-entity-references".equals(name))
488 return expandEntityReferences ? Boolean.TRUE : Boolean.FALSE;
490 else if ("coalescing".equals(name))
492 return coalescing ? Boolean.TRUE : Boolean.FALSE;
494 else if ("validating".equals(name))
496 return validating ? Boolean.TRUE : Boolean.FALSE;
498 else if ("xinclude-aware".equals(name))
500 return xIncludeAware ? Boolean.TRUE : Boolean.FALSE;
502 else if ("entity-resolver".equals(name))
504 return entityResolver;
506 else if ("error-handler".equals(name))
508 return errorHandler;
510 else
512 throw new DomDOMException(DOMException.NOT_SUPPORTED_ERR);
516 public boolean canSetParameter(String name, Object value)
518 return contains(name);
521 public DOMStringList getParameterNames()
523 return this;
526 // -- DOMStringList --
528 public String item(int i)
530 return (String) SUPPORTED_PARAMETERS.get(i);
533 public int getLength()
535 return SUPPORTED_PARAMETERS.size();
538 public boolean contains(String str)
540 return SUPPORTED_PARAMETERS.contains(str);
543 // -- ErrorHandler --
545 public void warning(SAXParseException e)
546 throws SAXException
548 if (errorHandler != null)
550 errorHandler.warning(e);
554 public void error(SAXParseException e)
555 throws SAXException
557 if (errorHandler != null)
559 errorHandler.error(e);
563 public void fatalError(SAXParseException e)
564 throws SAXException
566 if (errorHandler != null)
568 errorHandler.fatalError(e);
570 abort();