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)
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
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
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
;
41 import java
.io
.InputStream
;
42 import java
.io
.IOException
;
43 import java
.net
.MalformedURLException
;
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
;
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",
82 "element-content-whitespace",
84 "expand-entity-references",
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
)
113 case DOMImplementationLS
.MODE_ASYNCHRONOUS
:
116 case DOMImplementationLS
.MODE_SYNCHRONOUS
:
120 throw new DomDOMException(DOMException
.NOT_SUPPORTED_ERR
);
123 this.schemaType
= schemaType
;
124 factory
= SAXParserFactory
.newInstance();
129 public DOMConfiguration
getDomConfig()
134 public LSParserFilter
getFilter()
139 public void setFilter(LSParserFilter filter
)
141 this.filter
= filter
;
144 public boolean getAsync()
149 public boolean getBusy()
151 return eventSink
!= null;
154 public Document
parse(LSInput input
)
155 throws DOMException
, LSException
159 return doParse(input
);
165 return doParse(input
);
170 public Document
parseURI(String uri
)
171 throws DOMException
, LSException
173 LSInput input
= new DomLSInput();
174 input
.setSystemId(uri
);
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
);
190 case ACTION_APPEND_AS_CHILDREN
:
191 context
.appendChild(root
);
193 case ACTION_REPLACE_CHILDREN
:
194 Node c1
= context
.getFirstChild();
197 Node next
= c1
.getNextSibling();
198 context
.removeChild(c1
);
201 context
.appendChild(root
);
203 case ACTION_INSERT_BEFORE
:
204 Node p1
= context
.getParentNode();
205 p1
.insertBefore(root
, context
);
207 case ACTION_INSERT_AFTER
:
208 Node p2
= context
.getParentNode();
209 Node r1
= context
.getNextSibling();
212 p2
.appendChild(root
);
216 p2
.insertBefore(root
, r1
);
220 Node p3
= context
.getParentNode();
221 Node r2
= context
.getNextSibling();
222 p3
.removeChild(context
);
225 p3
.appendChild(root
);
229 p3
.insertBefore(root
, r2
);
238 if (eventSink
!= null)
240 eventSink
.interrupt();
244 private Document
doParse(LSInput input
)
245 throws DOMException
, LSException
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
);
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",
269 reader
.setProperty("http://xml.org/sax/properties/declaration-handler",
271 reader
.setFeature("http://xml.org/sax/features/namespaces",
273 reader
.setFeature("http://xml.org/sax/features/namespace-prefixes",
275 reader
.setFeature("http://xml.org/sax/features/validation",
279 reader
.setFeature("http://xml.org/sax/features/use-attributes2",
282 catch (SAXNotRecognizedException e
)
288 reader
.setFeature("http://xml.org/sax/features/external-general-entities",
291 catch (SAXNotRecognizedException e
)
295 reader
.setEntityResolver(entityResolver
);
296 reader
.setErrorHandler(errorHandler
);
298 reader
.parse(source
);
300 catch (DOMException e
)
306 catch (SAXException e
)
310 throw new DomLSException(LSException
.PARSE_ERR
, e
);
312 catch (IOException e
)
316 throw new DomLSException(LSException
.PARSE_ERR
, e
);
319 Document ret
= eventSink
.doc
;
320 String systemId
= input
.getSystemId();
321 if (systemId
!= null && ret
instanceof DomDocument
)
323 ((DomDocument
) ret
).setDocumentURI(systemId
);
329 private XMLReader
getXMLReader()
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
);
354 private InputSource
getInputSource(LSInput input
)
357 InputSource source
= null;
358 String systemId
= input
.getSystemId();
359 InputStream in
= input
.getByteStream();
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
);
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
);
412 // -- DOMConfiguration --
414 public void setParameter(String name
, Object value
)
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
;
460 throw new DomDOMException(DOMException
.NOT_SUPPORTED_ERR
);
462 // invalidate reader, a new one will be created
466 public Object
getParameter(String name
)
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
))
512 throw new DomDOMException(DOMException
.NOT_SUPPORTED_ERR
);
516 public boolean canSetParameter(String name
, Object value
)
518 return contains(name
);
521 public DOMStringList
getParameterNames()
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
)
548 if (errorHandler
!= null)
550 errorHandler
.warning(e
);
554 public void error(SAXParseException e
)
557 if (errorHandler
!= null)
559 errorHandler
.error(e
);
563 public void fatalError(SAXParseException e
)
566 if (errorHandler
!= null)
568 errorHandler
.fatalError(e
);