KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > xml > xmlc > dom > XMLCDocument


1 /*
2  * Enhydra Java Application Server Project
3  *
4  * The contents of this file are subject to the Enhydra Public License
5  * Version 1.1 (the "License"); you may not use this file except in
6  * compliance with the License. You may obtain a copy of the License on
7  * the Enhydra web site ( http://www.enhydra.org/ ).
8  *
9  * Software distributed under the License is distributed on an "AS IS"
10  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
11  * the License for the specific terms governing rights and limitations
12  * under the License.
13  *
14  * The Initial Developer of the Enhydra Application Server is Lutris
15  * Technologies, Inc. The Enhydra Application Server and portions created
16  * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
17  * All Rights Reserved.
18  *
19  * Contributor(s):
20  *
21  * $Id: XMLCDocument.java,v 1.4 2005/01/26 08:29:24 jkjome Exp $
22  */

23
24 package org.enhydra.xml.xmlc.dom;
25
26 import java.util.TreeMap JavaDoc;
27 import java.util.TreeSet JavaDoc;
28
29 import org.enhydra.xml.io.DOMFormatter;
30 import org.enhydra.xml.io.Encodings;
31 import org.enhydra.xml.xmlc.XMLCException;
32 import org.w3c.dom.Document JavaDoc;
33 import org.w3c.dom.DocumentType JavaDoc;
34 import org.w3c.dom.Element JavaDoc;
35 import org.w3c.dom.Node JavaDoc;
36 import org.w3c.dom.html.HTMLDocument;
37
38 /*
39  * NB: This has some HTML specific data in it. At one time, it was split
40  * into two classes, however it proved simpler to store the data here.
41  *
42  * NB: The DTD data kept here is specialized to collect the minimum amount of
43  * information on elements and attributes needed by XMLC. The API reflects
44  * this, which is a kludge, however its only used internally. This should
45  * be more general and interface to the DTD/Schema; however until this
46  * information is actually part of the DOM spec, the parsers just
47  * fill in the minimum.
48  */

49
50
51 /**
52  * Class that is a container for the parsed Document DOM. It contains
53  * information obtained from that parsers that is not part of the DOM. It also
54  * provides various operations on that document.
55  */

56 final public class XMLCDocument {
57     /**
58      * The DTD-specific DOM Factory.
59      */

60     private XMLCDomFactory fDomFactory;
61
62     /**
63      * Is this an HTML document we are dealing with?
64      */

65     private boolean fIsHtmlDocument;
66
67     /**
68      * Is this a HTML frameset?
69      */

70     private boolean fIsHtmlFrameSet;
71     
72     /**
73      * Information from XML header.
74      */

75     private String JavaDoc fXMLVersion;
76     private String JavaDoc fEncoding;
77
78     /**
79      * The DOM Document.
80      */

81     private Document JavaDoc fDocument;
82
83     /**
84      * The DOM Document type (null for HTML).
85      */

86     private DocumentType JavaDoc fDocType;
87
88     /**
89      * Table of element to id attribute name mappings.
90      */

91     private TreeMap JavaDoc fElementIdAttrs = new TreeMap JavaDoc();
92
93     /**
94      * Table of id attribute names.
95      */

96     private TreeSet JavaDoc fIdAttrNames = new TreeSet JavaDoc();
97
98     /**
99      * Last id attribute name; provides easy access to fIdAttrNames
100      * when there is only one.
101      */

102     private String JavaDoc fLastIdAttrName;
103
104     /**
105      * Table of elements that can have PCDATA children.
106      */

107     private TreeSet JavaDoc fPCDataElements = new TreeSet JavaDoc();
108
109     /**
110      * Constructor. A document is not initially associated with this
111      * object.
112      *
113      * @param domFactory The DOM factory to create and get information about
114      * DOMs.
115      * @param isHtmlDocument Is this an HTML document?
116      */

117     public XMLCDocument(XMLCDomFactory domFactory) throws XMLCException {
118         fDomFactory = domFactory;
119     }
120
121     /**
122      * Get the DOM factory associated with this object.
123      */

124     public XMLCDomFactory getDomFactory() {
125         return fDomFactory;
126     }
127
128     /**
129      * Creates an empty <code>DocumentType</code> node.
130      */

131     public DocumentType JavaDoc createDocumentType(String JavaDoc qualifiedName,
132                                            String JavaDoc publicID,
133                                            String JavaDoc systemID,
134                                            String JavaDoc internalSubset) {
135         fDocType = fDomFactory.createDocumentType(qualifiedName,
136                                                   publicID, systemID,
137                                                   internalSubset);
138         return fDocType;
139     }
140
141     /**
142      * Create the document. All arguments are null for HTML.
143      */

144     public Document JavaDoc createDocument(String JavaDoc namespaceURI,
145                                    String JavaDoc qualifiedName) {
146         fDocument = fDomFactory.createDocument(namespaceURI, qualifiedName,
147                                                fDocType);
148         fIsHtmlDocument = (fDocument instanceof HTMLDocument);
149         return fDocument;
150     }
151
152     /**
153      * Get the document associated with this object.
154      */

155     public Document JavaDoc getDocument() {
156         return fDocument;
157     }
158
159     /*
160      * Is this an HTML document?
161      */

162     public boolean isHtmlDocument() {
163         return fIsHtmlDocument;
164     }
165
166     /**
167      * Is the document as a HTML frameset?
168      */

169     public boolean isHtmlFrameSet() {
170         return fIsHtmlFrameSet;
171     }
172
173     /**
174      * Flat the document as a HTML frameset.
175      */

176     public void setIsHtmlFrameSet() {
177         fIsHtmlFrameSet = true;
178     }
179
180     /**
181      * Set the XML version.
182      *
183      * @param xmlVersion XML version string.
184      */

185     public void setXMLVersion(String JavaDoc xmlVersion) {
186         fXMLVersion = xmlVersion;
187     }
188
189     /**
190      * Get the XML version.
191      */

192     public String JavaDoc getXMLVersion() {
193         return fXMLVersion;
194     }
195
196     /*
197      * Get the default encoding or null if none.
198      */

199     public String JavaDoc getEncoding() {
200         return fEncoding;
201     }
202
203     /*
204      * Set the default encoding. This will be converted to the MIME-prefered
205      * name if not null.
206      */

207     public void setEncoding(String JavaDoc encoding) {
208         if (encoding == null) {
209             fEncoding = null;
210         } else {
211             Encodings encodings = Encodings.getEncodings();
212             String JavaDoc mimeEncoding = encodings.getMIMEPreferred(encoding);
213             if (mimeEncoding != null) {
214                 fEncoding = mimeEncoding;
215             } else {
216                 fEncoding = encoding;
217             }
218         }
219     }
220
221     /**
222      * Flag an element as having #PCDATA as part of its content model.
223      *
224      * @param elementName The name of the element.
225      */

226     public void addPCDataContentElement(String JavaDoc elementName) {
227         fPCDataElements.add(elementName);
228     }
229
230     /**
231      * Define an element id attribute. For XML, all ID attributes
232      * must be defined, even if not used. This is need to make
233      * global id attribute mode work.
234      *
235      * @param elementName The name of the element.
236      * @param attributeName The name of the ID attribute.
237      */

238     public void addIdAttribute(String JavaDoc elementName,
239                                String JavaDoc attributeName) {
240         fElementIdAttrs.put(elementName, attributeName);
241         if (!(attributeName.equals(fLastIdAttrName)
242               || fIdAttrNames.contains(attributeName))) {
243             fIdAttrNames.add(attributeName);
244             fLastIdAttrName = attributeName;
245         }
246     }
247
248     /**
249      * Convert an implementation-specific DOM node class name to the
250      * external interface or class name.
251      *
252      * @see XMLCDomFactory
253      */

254     public String JavaDoc nodeClassToInterface(Node JavaDoc node) {
255         return fDomFactory.nodeClassToInterface(node);
256     }
257
258     /**
259      * Get the global id attribute name. A DTD supports global id mode if a
260      * single attribute name is used for all elements that support ids and
261      * never used as a non-id attribute name. This is intended for the HTML
262      * `id' attribute. However, if a DTD conforms to this requirement, more
263      * efficient code for cloning the object can be generated. It has been
264      * suggested that `id' be a defacto standard for XML as well.
265      *
266      * This method will not be called until after the DTD has been parsed, so
267      * this can be determined.
268      *
269      * See the <A HREF="http://www.xml.com/axml/axml.html">
270      * XML Annotated Specification</A>.
271      *
272      * @return The global id attribute name or null if there is not a global
273      * ID attribute.
274      */

275     public String JavaDoc getGlobalIdAttribute() {
276         if (fIsHtmlDocument) {
277             return "id";
278         } else {
279             if (fIdAttrNames.size() == 1) {
280                 return fLastIdAttrName;
281             } else {
282                 return null;
283             }
284         }
285     }
286
287     /**
288      * Get the id attribute name for an element. The attribute
289      * doesn't need to actually exist in this element, this just gets
290      * the name for the attribute.
291      *
292      * @return The attribute name or null if the element does not have
293      * an id attribute.
294      */

295     public String JavaDoc getIdAttrName(Element JavaDoc element) {
296         if (fIsHtmlDocument) {
297             return "id";
298         } else {
299             return (String JavaDoc)fElementIdAttrs.get(element.getTagName());
300         }
301     }
302
303     /**
304      * Extract the unique id for an element object. This is specified with
305      * an attribute of type <CODE>ID</CODE>.
306      *
307      * @return The id or null if the element does not have an id.
308      */

309     public String JavaDoc getElementId(Element JavaDoc element) {
310         String JavaDoc idAttrName = getIdAttrName(element);
311         if (idAttrName == null) {
312             return null; // element doesn't have an id attribute
313
}
314         String JavaDoc id = element.getAttribute(idAttrName);
315         if ((id == null) || (id.length() == 0)) {
316             return null; // No id.
317
}
318         return id;
319     }
320
321     /**
322      * Extract the class names for an element.
323      * @see XMLCDomFactory#getElementClassNames
324      */

325     public String JavaDoc[] getElementClassNames(Element JavaDoc element) {
326         return fDomFactory.getElementClassNames(element);
327     }
328     
329     /**
330      * Extract the name for an element. This is a non-unique name for an
331      * element. In HTML, the name is specified with the <CODE>name</CODE>
332      * attribute. It's not supported for XML.
333      *
334      * @return The element name or null if the node has no name.
335      * XML returns null.
336      */

337     public String JavaDoc getElementName(Element JavaDoc element) {
338         if (fIsHtmlDocument) {
339             String JavaDoc name = element.getAttribute("name");
340             if (name.length() == 0) {
341                 return null;
342             } else {
343                 return name;
344             }
345         } else {
346             return null;
347         }
348     }
349
350     /**
351      * Determine if an an attribute of an element may contain a URL.
352      * @see XMLCDomFactory#isURLAttribute
353      */

354     public boolean isURLAttribute(Element JavaDoc element,
355                                   String JavaDoc attrName) {
356         return fDomFactory.isURLAttribute(element, attrName);
357     }
358
359     /**
360      * Check if an element has #PCDATA as part of it's content model.
361      */

362     public boolean hasPCDataInContentModel(Element JavaDoc element) {
363         return fPCDataElements.contains(element.getTagName());
364     }
365
366     /**
367      * Convert the document to a string representation of the document. The
368      * results are parsable into the same DOM hierarchy
369      */

370     public String JavaDoc toDocument() {
371         return new DOMFormatter(DOMFormatter.getDefaultOutputOptions(getDocument())).toString(getDocument());
372     }
373 }
374
Popular Tags