Merge from the pain train
[official-gcc.git] / libjava / gnu / xml / dom / Consumer.java
blob426b1e5da62bfd04f2192223842e511e34c7e39f
1 /* Consumer.java --
2 Copyright (C) 2001,2004 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. */
39 package gnu.xml.dom;
41 import org.w3c.dom.DocumentType;
42 import org.w3c.dom.Node;
43 import org.w3c.dom.Text;
45 import org.xml.sax.Attributes;
46 import org.xml.sax.SAXException;
47 import org.xml.sax.ext.Attributes2;
49 import gnu.xml.pipeline.DomConsumer;
50 import gnu.xml.pipeline.EventConsumer;
53 /**
54 * Event consumer which constructs DOM documents using the implementation
55 * in this package, using SAX2 events. This packages various backdoors
56 * into this DOM implementation, as needed to address DOM requirements
57 * that can't be met by strictly conforming implementations of DOM.
59 * <p> These requirements all relate to {@link DocumentType} nodes and
60 * features of that node type. These features are normally not used,
61 * because that interface only exposes a subset of the information found
62 * in DTDs. More, that subset does not include the most important typing
63 * information. For example, it excludes element content models and
64 * attribute typing. It does expose some entity management issues,
65 * although entity management doesn't relate to document typing.
67 * <p> Note that SAX2 does not expose the literal text of the DTD's
68 * internal subset, so it will not be present in DOM trees constructed
69 * using this API. (Though with a good SAX2 implementation, it could
70 * be partially recreated...)
72 * @author David Brownell
74 public class Consumer extends DomConsumer
76 /**
77 * Constructs an unconfigured event consumer,
78 * as a terminus in a SAX event pipeline.
80 // used by PipelineFactory [terminus]
81 public Consumer ()
82 throws SAXException
84 super (DomDocument.class);
85 setHandler (new Backdoor (this));
88 /**
89 * Constructs an unconfigured event consumer,
90 * as a stage in a SAX event pipeline.
92 // used by PipelineFactory [filter]
93 public Consumer (EventConsumer next)
94 throws SAXException
96 super (DomDocument.class, next);
97 setHandler (new Backdoor (this));
101 * Implements the backdoors needed by DOM.
102 * All methods in this class use implementation-specific APIs that are
103 * implied by the DOM specification (needed to implement testable
104 * behavior) but which are excluded from the DOM specification.
106 public static class Backdoor extends DomConsumer.Handler
109 * Constructor.
110 * @param consumer must have been initialized to use the
111 * {@link DomDocument} class (or a subclass) for
112 * constructing DOM trees
114 protected Backdoor (DomConsumer consumer)
115 throws SAXException
116 { super (consumer); }
118 // helper routine
119 private DomDoctype getDoctype ()
120 throws SAXException
122 DomDocument doc = (DomDocument) getDocument ();
123 DocumentType dt = doc.getDoctype ();
125 if (dt == null)
126 throw new SAXException ("doctype missing!");
127 return (DomDoctype) dt;
130 // SAX2 "lexical" event
131 public void startDTD (String name, String publicId, String systemId)
132 throws SAXException
134 DomDocument doc = (DomDocument) getDocument ();
136 super.startDTD (name, publicId, systemId);
137 // DOM L2 doctype creation model is bizarre
138 DomDoctype dt = new DomDoctype (doc, name, publicId, systemId);
139 doc.appendChild (dt);
142 // SAX2 "lexical" event
143 public void endDTD ()
144 throws SAXException
146 super.endDTD ();
147 // DOM L2 has no way to make things readonly
148 getDoctype ().makeReadonly ();
151 // SAX1 DTD event
152 public void notationDecl (
153 String name,
154 String publicId, String systemId
155 ) throws SAXException
157 // DOM L2 can't create/save notation nodes
158 getDoctype ().declareNotation (name, publicId, systemId);
161 // SAX1 DTD event
162 public void unparsedEntityDecl (
163 String name,
164 String publicId, String systemId,
165 String notationName
166 ) throws SAXException
168 // DOM L2 can't create/save entity nodes
169 getDoctype ().declareEntity (name, publicId, systemId,
170 notationName);
173 // SAX2 declaration event
174 public void internalEntityDecl (String name, String value)
175 throws SAXException
177 // DOM L2 can't create/save entity nodes
178 // NOTE: this doesn't save the value as a child of this
179 // node, though it could realistically do so.
180 getDoctype ().declareEntity (name, null, null, null);
183 // SAX2 declaration event
184 public void externalEntityDecl (
185 String name,
186 String publicId,
187 String systemId
188 ) throws SAXException
190 // DOM L2 can't create/save entity nodes
191 // NOTE: DOM allows for these to have children, if
192 // they don't have unbound namespace references.
193 getDoctype ().declareEntity (name, publicId, systemId, null);
196 // SAX2 element
197 public void startElement (
198 String uri,
199 String localName,
200 String qName,
201 Attributes atts
202 ) throws SAXException
204 Node top;
206 super.startElement (uri, localName, qName, atts);
208 // might there be more work?
209 top = getTop ();
210 if (!top.hasAttributes () || !(atts instanceof Attributes2))
211 return;
213 // remember any attributes that got defaulted
214 DomNamedNodeMap map = (DomNamedNodeMap) top.getAttributes ();
215 Attributes2 attrs = (Attributes2) atts;
216 int length = atts.getLength ();
218 //map.compact ();
219 for (int i = 0; i < length; i++) {
220 if (attrs.isSpecified (i))
221 continue;
223 // value was defaulted.
224 String temp = attrs.getQName (i);
225 DomAttr attr;
227 if ("".equals (temp))
228 attr = (DomAttr) map.getNamedItemNS (attrs.getURI (i),
229 atts.getLocalName (i));
230 else
231 attr = (DomAttr) map.getNamedItem (temp);
233 // DOM L2 can't write this flag, only read it
234 attr.setSpecified (false);
238 public void endElement (
239 String uri,
240 String localName,
241 String qName
242 ) throws SAXException
244 DomNode top = (DomNode) getTop ();
245 top.compact ();
246 super.endElement (uri, localName, qName);
249 protected Text createText (
250 boolean isCDATA,
251 char buf [],
252 int off,
253 int len
255 DomDocument doc = (DomDocument) getDocument ();
257 if (isCDATA)
258 return doc.createCDATASection (buf, off, len);
259 else
260 return doc.createTextNode (buf, off, len);
263 public void elementDecl(String name, String model)
264 throws SAXException
266 getDoctype().elementDecl(name, model);
269 public void attributeDecl (
270 String ename,
271 String aname,
272 String type,
273 String mode,
274 String value
275 ) throws SAXException
277 getDoctype().attributeDecl(ename, aname, type, mode, value);
279 if (value == null && !"ID".equals (type))
280 return;
282 DomDoctype.ElementInfo info;
284 info = getDoctype ().getElementInfo (ename);
285 if (value != null)
286 info.setAttrDefault (aname, value);
287 if ("ID".equals (type))
288 info.setIdAttr (aname);
293 // force duplicate name checking off while we're
294 // using parser output (don't duplicate the work)
295 public void startDocument () throws SAXException
297 super.startDocument ();
299 DomDocument doc = (DomDocument) getDocument ();
300 doc.setStrictErrorChecking(false);
301 doc.setBuilding(true);
305 * Required by DOM Level 3 to report document parameters
307 public void xmlDecl(String version,
308 String encoding,
309 boolean standalone,
310 String inputEncoding)
311 throws SAXException
313 super.xmlDecl(version, encoding, standalone, inputEncoding);
315 DomDocument doc = (DomDocument) getDocument();
316 doc.setXmlEncoding(encoding);
317 doc.setInputEncoding(inputEncoding);
320 public void endDocument ()
321 throws SAXException
323 DomDocument doc = (DomDocument) getDocument ();
324 doc.setStrictErrorChecking(true);
325 doc.setBuilding(false);
326 doc.compact ();
327 DomDoctype doctype = (DomDoctype) doc.getDoctype();
328 if (doctype != null)
330 doctype.makeReadonly();
332 super.endDocument ();
335 // these three methods collaborate to populate entity
336 // refs, marking contents readonly on end-of-entity
338 public boolean canPopulateEntityRefs ()
339 { return true; }
341 public void startEntity (String name)
342 throws SAXException
344 if (name.charAt (0) == '%' || "[dtd]".equals (name))
345 return;
346 super.startEntity (name);
348 DomNode top = (DomNode) getTop ();
350 if (top.getNodeType () == Node.ENTITY_REFERENCE_NODE)
351 top.readonly = false;
354 public void endEntity (String name)
355 throws SAXException
357 if (name.charAt (0) == '%' || "[dtd]".equals (name))
358 return;
359 DomNode top = (DomNode) getTop ();
361 if (top.getNodeType () == Node.ENTITY_REFERENCE_NODE) {
362 top.compact ();
363 top.makeReadonly ();
365 super.endEntity (name);