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)
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. */
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
;
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 <!DOCTYPE ...> 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>
72 * @see DomEntityReference
75 * @author David Brownell
76 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
78 public class DomDoctype
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();
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
107 * @param systemId If non-null, provides the external subset's
109 * @param internalSubset Provides the literal value (unparsed, no
110 * entities expanded) of the DTD's internal subset.
112 protected DomDoctype(DOMImplementation impl
,
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
,
135 super(DOCUMENT_TYPE_NODE
, doc
, name
, publicId
, systemId
);
136 implementation
= doc
.getImplementation();
141 * Returns the root element's name (just like getNodeName).
143 final public String
getName()
145 return getNodeName();
150 * Returns information about any general entities declared
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
);
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
,
192 if (name
.charAt(0) == '%' || "[dtd]".equals(name
))
198 throw new DomDOMException(DOMException
.NO_MODIFICATION_ALLOWED_ERR
);
202 DomDocument
.checkName(name
, (owner
!= null) ?
203 "1.1".equals(owner
.getXmlVersion()) : false);
204 if (entities
.getNamedItem(name
) != null)
209 entity
= new DomEntity(owner
, name
, publicId
, systemId
, notation
);
210 entities
.setNamedItem(entity
);
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
);
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
,
250 DomNotation notation
;
254 throw new DomDOMException(DOMException
.NO_MODIFICATION_ALLOWED_ERR
);
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
);
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()
286 * The base URI of a DocumentType is always <code>null</code>.
287 * See the Infoset Mapping, appendix C.
289 public final String
getBaseURI()
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
)
321 if (notations
!= null)
323 for (DomNode ctx
= notations
.first
; ctx
!= null; ctx
= ctx
.next
)
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
);
354 info
= new DTDElementTypeInfo(name
, model
);
355 elements
.put(name
, info
);
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
,
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
))
386 DTDAttributeTypeInfo
getAttributeTypeInfo(String elementName
, String name
)
388 DTDElementTypeInfo elementInfo
=
389 (DTDElementTypeInfo
) elements
.get(elementName
);
390 return (elementInfo
== null) ?
null :
391 elementInfo
.getAttributeTypeInfo(name
);
399 public boolean isSameNode(Node arg
)
405 if (!(arg
instanceof DocumentType
))
409 DocumentType doctype
= (DocumentType
) arg
;
410 if (!equal(getPublicId(), doctype
.getPublicId()))
414 if (!equal(getSystemId(), doctype
.getSystemId()))
418 if (!equal(getInternalSubset(), doctype
.getInternalSubset()))
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));