libjava/ChangeLog:
[official-gcc.git] / libjava / classpath / gnu / xml / dom / ls / DomLSParser.java
blobf4f555e8c39c675de49dc6d614d0ae692207e0c2
1 /* DomLSParser.java --
2 Copyright (C) 1999,2000,2001,2007 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.setNamespaceAware(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://gnu.org/sax/features/coalescing",
281 coalescing);
283 catch (SAXNotRecognizedException e)
285 // ignore
289 reader.setFeature("http://xml.org/sax/features/use-attributes2",
290 true);
292 catch (SAXNotRecognizedException e)
294 // ignore
298 reader.setFeature("http://xml.org/sax/features/external-general-entities",
299 true);
301 catch (SAXNotRecognizedException e)
303 // ignore
305 reader.setEntityResolver(entityResolver);
306 reader.setErrorHandler(errorHandler);
307 // parse
308 reader.parse(source);
310 catch (DOMException e)
312 reader = null;
313 eventSink = null;
314 throw e;
316 catch (SAXException e)
318 reader = null;
319 eventSink = null;
320 throw new DomLSException(LSException.PARSE_ERR, e);
322 catch (IOException e)
324 reader = null;
325 eventSink = null;
326 throw new DomLSException(LSException.PARSE_ERR, e);
328 // return document
329 Document ret = eventSink.doc;
330 String systemId = input.getSystemId();
331 if (systemId != null && ret instanceof DomDocument)
333 ((DomDocument) ret).setDocumentURI(systemId);
335 eventSink = null;
336 return ret;
339 private XMLReader getXMLReader()
340 throws LSException
342 if (reader == null)
344 factory.setNamespaceAware(namespaceAware);
345 factory.setValidating(validating);
346 factory.setXIncludeAware(xIncludeAware);
349 SAXParser parser = factory.newSAXParser();
350 reader = parser.getXMLReader();
352 catch (ParserConfigurationException e)
354 throw new DomLSException(LSException.PARSE_ERR, e);
356 catch (SAXException e)
358 throw new DomLSException(LSException.PARSE_ERR, e);
361 return reader;
364 private InputSource getInputSource(LSInput input)
365 throws LSException
367 InputSource source = null;
368 String systemId = input.getSystemId();
369 InputStream in = input.getByteStream();
370 if (in != null)
372 source = new InputSource(in);
373 source.setSystemId(systemId);
375 if (source == null)
377 URL url = null;
378 String base = input.getBaseURI();
383 URL baseURL = (base == null) ? null : new URL(base);
384 url = (baseURL == null) ? new URL(systemId) :
385 new URL(baseURL, systemId);
387 catch (MalformedURLException e)
389 File baseFile = (base == null) ? null : new File(base);
390 url = (baseFile == null) ? new File(systemId).toURL() :
391 new File(baseFile, systemId).toURL();
393 in = url.openStream();
394 systemId = url.toString();
395 source = new InputSource(in);
396 source.setSystemId(systemId);
398 catch (IOException e)
400 throw new DomLSException(LSException.PARSE_ERR, e);
403 return source;
406 // -- DOMConfiguration --
408 public void setParameter(String name, Object value)
409 throws DOMException
411 name = name.toLowerCase();
412 if ("cdata-sections".equals(name))
414 coalescing = !((Boolean) value).booleanValue();
416 else if ("comments".equals(name))
418 ignoreComments = !((Boolean) value).booleanValue();
420 else if ("element-content-whitespace".equals(name))
422 ignoreWhitespace = !((Boolean) value).booleanValue();
424 else if ("namespaces".equals(name))
426 namespaceAware = ((Boolean) value).booleanValue();
428 else if ("expand-entity-references".equals(name))
430 expandEntityReferences = ((Boolean) value).booleanValue();
432 else if ("coalescing".equals(name))
434 coalescing = ((Boolean) value).booleanValue();
436 else if ("validating".equals(name))
438 validating = ((Boolean) value).booleanValue();
440 else if ("xinclude-aware".equals(name))
442 xIncludeAware = ((Boolean) value).booleanValue();
444 else if ("entity-resolver".equals(name))
446 entityResolver = (EntityResolver) value;
448 else if ("error-handler".equals(name))
450 errorHandler = (ErrorHandler) value;
452 else
454 throw new DomDOMException(DOMException.NOT_SUPPORTED_ERR);
456 // invalidate reader, a new one will be created
457 reader = null;
460 public Object getParameter(String name)
461 throws DOMException
463 name = name.toLowerCase();
464 if ("cdata-sections".equals(name))
466 return coalescing ? Boolean.FALSE : Boolean.TRUE;
468 else if ("comments".equals(name))
470 return ignoreComments ? Boolean.FALSE : Boolean.TRUE;
472 else if ("element-content-whitespace".equals(name))
474 return ignoreWhitespace ? Boolean.FALSE : Boolean.TRUE;
476 else if ("namespaces".equals(name))
478 return namespaceAware ? Boolean.TRUE : Boolean.FALSE;
480 else if ("expand-entity-references".equals(name))
482 return expandEntityReferences ? Boolean.TRUE : Boolean.FALSE;
484 else if ("coalescing".equals(name))
486 return coalescing ? Boolean.TRUE : Boolean.FALSE;
488 else if ("validating".equals(name))
490 return validating ? Boolean.TRUE : Boolean.FALSE;
492 else if ("xinclude-aware".equals(name))
494 return xIncludeAware ? Boolean.TRUE : Boolean.FALSE;
496 else if ("entity-resolver".equals(name))
498 return entityResolver;
500 else if ("error-handler".equals(name))
502 return errorHandler;
504 else
506 throw new DomDOMException(DOMException.NOT_SUPPORTED_ERR);
510 public boolean canSetParameter(String name, Object value)
512 return contains(name);
515 public DOMStringList getParameterNames()
517 return this;
520 // -- DOMStringList --
522 public String item(int i)
524 return (String) SUPPORTED_PARAMETERS.get(i);
527 public int getLength()
529 return SUPPORTED_PARAMETERS.size();
532 public boolean contains(String str)
534 return SUPPORTED_PARAMETERS.contains(str);
537 // -- ErrorHandler --
539 public void warning(SAXParseException e)
540 throws SAXException
542 if (errorHandler != null)
544 errorHandler.warning(e);
548 public void error(SAXParseException e)
549 throws SAXException
551 if (errorHandler != null)
553 errorHandler.error(e);
557 public void fatalError(SAXParseException e)
558 throws SAXException
560 if (errorHandler != null)
562 errorHandler.fatalError(e);
564 abort();