Merge from the pain train
[official-gcc.git] / libjava / gnu / xml / dom / DomDoctype.java
blob8c760a5317f87a2bf62346165024804928be63cc
1 /* DomDoctype.java --
2 Copyright (C) 1999,2000,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. */
38 package gnu.xml.dom;
40 import java.util.HashMap;
41 import org.w3c.dom.DocumentType;
42 import org.w3c.dom.DOMException;
43 import org.w3c.dom.DOMImplementation;
44 import org.w3c.dom.Entity;
45 import org.w3c.dom.NamedNodeMap;
46 import org.w3c.dom.Node;
47 import org.w3c.dom.Notation;
49 /**
50 * <p> "DocumentType" implementation (with no extensions for supporting
51 * any document typing information). This is a non-core DOM class,
52 * supporting the "XML" feature. </p>
54 * <p> <em>Few XML applications will actually care about this partial
55 * DTD support</em>, since it doesn't expose any (!) of the data typing
56 * facilities which can motivate applications to use DTDs. It does not
57 * expose element content models, or information about attribute typing
58 * rules. Plus the information it exposes isn't very useful; as one example,
59 * DOM exposes information about unparsed ENTITY objects, which is only used
60 * with certain element attributes, but does not expose the information about
61 * those attributes which is needed to apply that data! </p>
63 * <p> Also, note that there are no nonportable ways to associate even the
64 * notation and entity information exposed by DOM with a DocumentType. While
65 * there is a DOM L2 method to construct a DocumentType, it only gives access
66 * to the textual content of the &lt;!DOCTYPE ...&gt; declaration. </p>
68 * <p> In short, <em>you are strongly advised not to rely on this incomplete
69 * DTD functionality</em> in your application code.</p>
71 * @see DomEntity
72 * @see DomEntityReference
73 * @see DomNotation
75 * @author David Brownell
76 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
78 public class DomDoctype
79 extends DomExtern
80 implements DocumentType
83 private DomNamedNodeMap notations;
84 private DomNamedNodeMap entities;
85 private final DOMImplementation implementation;
86 private String subset;
88 private HashMap elements = new HashMap();
89 private boolean ids;
91 /**
92 * Constructs a DocumentType node associated with the specified
93 * implementation, with the specified name.
95 * <p>This constructor should only be invoked by a DOMImplementation as
96 * part of its createDocumentType functionality, or through a subclass
97 * which is similarly used in a "Sub-DOM" style layer.
99 * <p> Note that at this time there is no standard SAX API granting
100 * access to the internal subset text, so that relying on that value
101 * is not currently portable.
103 * @param impl The implementation with which this object is associated
104 * @param name Name of this root element
105 * @param publicId If non-null, provides the external subset's
106 * PUBLIC identifier
107 * @param systemId If non-null, provides the external subset's
108 * SYSTEM identifier
109 * @param internalSubset Provides the literal value (unparsed, no
110 * entities expanded) of the DTD's internal subset.
112 protected DomDoctype(DOMImplementation impl,
113 String name,
114 String publicId,
115 String systemId,
116 String internalSubset)
118 super(DOCUMENT_TYPE_NODE, null, name, publicId, systemId);
119 implementation = impl;
120 subset = internalSubset;
124 * JAXP builder constructor.
125 * @param doc the document
126 * @param name the name of the document element
127 * @param publicId the public ID of the document type declaration
128 * @param systemId the system ID of the document type declaration
130 public DomDoctype(DomDocument doc,
131 String name,
132 String publicId,
133 String systemId)
135 super(DOCUMENT_TYPE_NODE, doc, name, publicId, systemId);
136 implementation = doc.getImplementation();
140 * <b>DOM L1</b>
141 * Returns the root element's name (just like getNodeName).
143 final public String getName()
145 return getNodeName();
149 * <b>DOM L1</b>
150 * Returns information about any general entities declared
151 * in the DTD.
153 * <p><em>Note: DOM L1 doesn't throw a DOMException here, but
154 * then it doesn't have the strange construction rules of L2.</em>
156 * @exception DOMException HIERARCHY_REQUEST_ERR if the DocumentType
157 * is not associated with a document.
159 public NamedNodeMap getEntities()
161 if (entities == null)
163 entities = new DomNamedNodeMap(this, Node.ENTITY_NODE);
165 return entities;
169 * Records the declaration of a general entity in this DocumentType.
171 * @param name Name of the entity
172 * @param publicId If non-null, provides the entity's PUBLIC identifier
173 * @param systemId Provides the entity's SYSTEM identifier
174 * @param notation If non-null, provides the entity's notation
175 * (indicating an unparsed entity)
176 * @return The Entity that was declared, or null if the entity wasn't
177 * recorded (because it's a parameter entity or because an entity with
178 * this name was already declared).
180 * @exception DOMException NO_MODIFICATION_ALLOWED_ERR if the
181 * DocumentType is no longer writable.
182 * @exception DOMException HIERARCHY_REQUEST_ERR if the DocumentType
183 * is not associated with a document.
185 public Entity declareEntity(String name,
186 String publicId,
187 String systemId,
188 String notation)
190 DomEntity entity;
192 if (name.charAt(0) == '%' || "[dtd]".equals(name))
194 return null;
196 if (isReadonly())
198 throw new DomDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
200 getEntities();
202 DomDocument.checkName(name, (owner != null) ?
203 "1.1".equals(owner.getXmlVersion()) : false);
204 if (entities.getNamedItem(name) != null)
206 return null;
209 entity = new DomEntity(owner, name, publicId, systemId, notation);
210 entities.setNamedItem(entity);
211 return entity;
215 * <b>DOM L1</b>
216 * Returns information about any notations declared in the DTD.
218 * <p><em>Note: DOM L1 doesn't throw a DOMException here, but
219 * then it doesn't have the strange construction rules of L2.</em>
221 * @exception DOMException HIERARCHY_REQUEST_ERR if the DocumentType
222 * is not associated with a document.
224 public NamedNodeMap getNotations()
226 if (notations == null)
228 notations = new DomNamedNodeMap(this, Node.NOTATION_NODE);
230 return notations;
234 * Records the declaration of a notation in this DocumentType.
236 * @param name Name of the notation
237 * @param publicId If non-null, provides the notation's PUBLIC identifier
238 * @param systemId If non-null, provides the notation's SYSTEM identifier
239 * @return The notation that was declared.
241 * @exception DOMException NO_MODIFICATION_ALLOWED_ERR if the
242 * DocumentType is no longer writable.
243 * @exception DOMException HIERARCHY_REQUEST_ERR if the DocumentType
244 * is not associated with a document.
246 public Notation declareNotation(String name,
247 String publicId,
248 String systemId)
250 DomNotation notation;
252 if (isReadonly())
254 throw new DomDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR);
256 getNotations();
258 DomDocument.checkName(name, (owner != null) ?
259 "1.1".equals(owner.getXmlVersion()) : false);
261 notation = new DomNotation(owner, name, publicId, systemId);
262 notations.setNamedItem(notation);
263 return notation;
267 * <b>DOM L2</b>
268 * Returns the internal subset of the document, as a string of unparsed
269 * XML declarations (and comments, PIs, whitespace); or returns null if
270 * there is no such subset. There is no vendor-independent expectation
271 * that this attribute be set, or that declarations found in it be
272 * reflected in the <em>entities</em> or <em>notations</em> attributes
273 * of this Document "Type" object.
275 * <p> Some application-specific XML profiles require that documents
276 * only use specific PUBLIC identifiers, without an internal subset
277 * to modify the interperetation of the declarations associated with
278 * that PUBLIC identifier through some standard.
280 public String getInternalSubset()
282 return subset;
286 * The base URI of a DocumentType is always <code>null</code>.
287 * See the Infoset Mapping, appendix C.
289 public final String getBaseURI()
291 return null;
295 * Sets the internal "readonly" flag so the node and its associated
296 * data (only lists of entities and notations, no type information
297 * at the moment) can't be changed.
299 public void makeReadonly()
301 super.makeReadonly();
302 if (entities != null)
304 entities.makeReadonly();
306 if (notations != null)
308 notations.makeReadonly();
312 void setOwner(DomDocument doc)
314 if (entities != null)
316 for (DomNode ctx = entities.first; ctx != null; ctx = ctx.next)
318 ctx.setOwner(doc);
321 if (notations != null)
323 for (DomNode ctx = notations.first; ctx != null; ctx = ctx.next)
325 ctx.setOwner(doc);
328 super.setOwner(doc);
332 * <b>DOM L2</b>
333 * Consults the DOM implementation to determine if the requested
334 * feature is supported.
336 final public boolean supports(String feature, String version)
338 return implementation.hasFeature(feature, version);
342 * Returns the implementation associated with this document type.
344 final public DOMImplementation getImplementation()
346 return implementation;
349 public void elementDecl(String name, String model)
351 DTDElementTypeInfo info = getElementTypeInfo(name);
352 if (info == null)
354 info = new DTDElementTypeInfo(name, model);
355 elements.put(name, info);
357 else
359 info.model = model;
363 DTDElementTypeInfo getElementTypeInfo(String name)
365 return (DTDElementTypeInfo) elements.get(name);
368 public void attributeDecl(String eName, String aName, String type,
369 String mode, String value)
371 DTDAttributeTypeInfo info = new DTDAttributeTypeInfo(eName, aName, type,
372 mode, value);
373 DTDElementTypeInfo elementInfo = getElementTypeInfo(eName);
374 if (elementInfo == null)
376 elementInfo = new DTDElementTypeInfo(eName, null);
377 elements.put(eName, elementInfo);
379 elementInfo.setAttributeTypeInfo(aName, info);
380 if ("ID".equals(type))
382 ids = true;
386 DTDAttributeTypeInfo getAttributeTypeInfo(String elementName, String name)
388 DTDElementTypeInfo elementInfo =
389 (DTDElementTypeInfo) elements.get(elementName);
390 return (elementInfo == null) ? null :
391 elementInfo.getAttributeTypeInfo(name);
394 boolean hasIds()
396 return ids;
399 public boolean isSameNode(Node arg)
401 if (equals(arg))
403 return true;
405 if (!(arg instanceof DocumentType))
407 return false;
409 DocumentType doctype = (DocumentType) arg;
410 if (!equal(getPublicId(), doctype.getPublicId()))
412 return false;
414 if (!equal(getSystemId(), doctype.getSystemId()))
416 return false;
418 if (!equal(getInternalSubset(), doctype.getInternalSubset()))
420 return false;
422 // TODO entities
423 // TODO notations
424 return true;
428 * Shallow clone of the doctype, except that associated
429 * entities and notations are (deep) cloned.
431 public Object clone()
433 DomDoctype node = (DomDoctype) super.clone();
435 if (entities != null)
437 node.entities = new DomNamedNodeMap(node, Node.ENTITY_NODE);
438 for (DomNode ctx = entities.first; ctx != null; ctx = ctx.next)
440 node.entities.setNamedItem(ctx.cloneNode(true));
443 if (notations != null)
445 node.notations = new DomNamedNodeMap(node, Node.NOTATION_NODE);
446 for (DomNode ctx = notations.first; ctx != null; ctx = ctx.next)
448 node.notations.setNamedItem(ctx.cloneNode(true));
451 return node;