1 /* DomImpl.java --
2    Copyright (C) 1999,2000,2001,2004 Free Software Foundation, Inc.
3 
4 This file is part of GNU Classpath.
5 
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.
10 
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.
15 
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., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20 
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.
25 
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. */
37 
38 package gnu.xml.dom;
39 
40 import org.w3c.dom.Document;
41 import org.w3c.dom.DocumentType;
42 import org.w3c.dom.DOMException;
43 import org.w3c.dom.DOMImplementation;
44 import org.w3c.dom.Element;
45 import org.w3c.dom.ls.DOMImplementationLS;
46 import org.w3c.dom.ls.LSInput;
47 import org.w3c.dom.ls.LSOutput;
48 import org.w3c.dom.ls.LSParser;
49 import org.w3c.dom.ls.LSSerializer;
50 import gnu.xml.dom.html2.DomHTMLImpl;
51 import gnu.xml.dom.ls.DomLSInput;
52 import gnu.xml.dom.ls.DomLSOutput;
53 import gnu.xml.dom.ls.DomLSParser;
54 import gnu.xml.dom.ls.DomLSSerializer;
55 
56 /**
57  * <p> "DOMImplementation" implementation. </p>
58  *
59  * <p> At this writing, the following features are supported:
60  * "XML" (L1, L2, L3),
61  * "Events" (L2), "MutationEvents" (L2), "USER-Events" (a conformant extension),
62  * "HTMLEvents" (L2), "UIEvents" (L2), "Traversal" (L2), "XPath" (L3),
63  * "LS" (L3) "LS-Async" (L3).
64  * It is possible to compile the package so it doesn't support some of these
65  * features (notably, Traversal).
66  *
67  * @author David Brownell
68  * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
69  */
70 public class DomImpl
71   implements DOMImplementation, DOMImplementationLS
72 {
73 
74   /**
75    * Constructs a DOMImplementation object which supports
76    * "XML" and other DOM Level 2 features.
77    */
DomImpl()78   public DomImpl()
79   {
80   }
81 
82   /**
83    * <b>DOM L1</b>
84    * Returns true if the specified feature and version are
85    * supported.  Note that the case of the feature name is ignored.
86    */
hasFeature(String name, String version)87   public boolean hasFeature(String name, String version)
88   {
89     if (name.length() == 0)
90       {
91         return false;
92       }
93     name = name.toLowerCase();
94     if (name.charAt(0) == '+')
95       {
96         name = name.substring(1);
97       }
98 
99     if ("xml".equals(name) || "core".equals(name))
100       {
101         return (version == null ||
102                 "".equals(version) ||
103                 "1.0".equals(version) ||
104                 "2.0".equals(version) ||
105                 "3.0".equals(version));
106 
107       }
108     else if ("ls".equals(name) || "ls-async".equals(name))
109       {
110         return (version == null ||
111                 "".equals(version) ||
112                 "3.0".equals(version));
113       }
114     else if ("events".equals(name)
115              || "mutationevents".equals(name)
116              || "uievents".equals(name)
117              // || "mouseevents".equals(name)
118              || "htmlevents".equals(name))
119       {
120         return (version == null ||
121                 "".equals(version) ||
122                 "2.0".equals(version));
123 
124         // Extension:  "USER-" prefix event types can
125         // be created and passed through the DOM.
126 
127       }
128     else if ("user-events".equals(name))
129       {
130         return (version == null ||
131                 "".equals(version) ||
132                 "0.1".equals(version));
133 
134         // NOTE:  "hasFeature" for events is here interpreted to
135         // mean the DOM can manufacture those sorts of events,
136         // since actually choosing to report the events is more
137         // often part of the environment or application.  It's
138         // only really an issue for mutation events.
139 
140       }
141     else if (DomNode.reportMutations
142              && "traversal".equals(name))
143       {
144         return (version == null ||
145                 "".equals(version) ||
146                 "2.0".equals(version));
147       }
148     else if ("xpath".equals(name))
149       {
150         return (version == null ||
151                 "".equals(version) ||
152                 "3.0".equals(version));
153       }
154     else if ("html".equals(name) || "xhtml".equals(name))
155       {
156         return (version == null ||
157                 "".equals(version) ||
158                 "2.0".equals(version));
159       }
160 
161     // views
162     // stylesheets
163     // css, css2
164     // range
165 
166     return false;
167   }
168 
169   /**
170    * <b>DOM L2</b>
171    * Creates and returns a DocumentType, associated with this
172    * implementation.  This DocumentType can have no associated
173    * objects(notations, entities) until the DocumentType is
174    * first associated with a document.
175    *
176    * <p> Note that there is no implication that this DTD will
177    * be parsed by the DOM, or ever have contents.  Moreover, the
178    * DocumentType created here can only be added to a document by
179    * the createDocument method(below).  <em>That means that the only
180    * portable way to create a Document object is to start parsing,
181    * queue comment and processing instruction (PI) nodes, and then only
182    * create a DOM Document after <b>(a)</b> it's known if a DocumentType
183    * object is needed, and <b>(b) the name and namespace of the root
184    * element is known.  Queued comment and PI nodes would then be
185    * inserted appropriately in the document prologue, both before and
186    * after the DTD node, and additional attributes assigned to the
187    * root element.</em>
188    *(One hopes that the final DOM REC fixes this serious botch.)
189    */
createDocumentType(String rootName, String publicId, String systemId)190   public DocumentType createDocumentType(String rootName,
191                                          String publicId,
192                                          String systemId)
193     // CR2 deleted internal subset, ensuring DocumentType
194     // is 100% useless instead of just 90% so.
195   {
196     DomDocument.checkNCName(rootName, false);
197     return new DomDoctype(this, rootName, publicId, systemId, null);
198   }
199 
200   /**
201    * <b>DOM L2</b>
202    * Creates and returns a Document, populated only with a root element and
203    * optionally a document type(if that was provided).
204    */
createDocument(String namespaceURI, String rootName, DocumentType doctype)205   public Document createDocument(String namespaceURI,
206                                  String rootName,
207                                  DocumentType doctype)
208   {
209     Document doc = createDocument();
210     Element root = null;
211 
212     if (rootName != null)
213       {
214         root = doc.createElementNS(namespaceURI, rootName);
215         if (rootName.startsWith("xmlns:"))
216           {
217             throw new DomDOMException(DOMException.NAMESPACE_ERR,
218                                       "xmlns is reserved", null, 0);
219           }
220       }
221     // Bleech -- L2 seemingly _requires_ omission of xmlns attributes.
222     if (doctype != null)
223       {
224         doc.appendChild(doctype);               // handles WRONG_DOCUMENT error
225       }
226     if (root != null)
227       {
228         doc.appendChild(root);
229       }
230     return doc;
231   }
232 
createDocument()233   protected Document createDocument()
234   {
235     return new DomDocument(this);
236   }
237 
238   // DOM Level 3
239 
getFeature(String feature, String version)240   public Object getFeature(String feature, String version)
241   {
242     if (hasFeature(feature, version))
243       {
244         if ("html".equalsIgnoreCase(feature) ||
245             "xhtml".equalsIgnoreCase(feature))
246           {
247             return new DomHTMLImpl();
248           }
249         return this;
250       }
251     return null;
252   }
253 
254   // -- DOMImplementationLS --
255 
createLSParser(short mode, String schemaType)256   public LSParser createLSParser(short mode, String schemaType)
257     throws DOMException
258   {
259     return new DomLSParser(mode, schemaType);
260   }
261 
createLSSerializer()262   public LSSerializer createLSSerializer()
263   {
264     return new DomLSSerializer();
265   }
266 
createLSInput()267   public LSInput createLSInput()
268   {
269     return new DomLSInput();
270   }
271 
createLSOutput()272   public LSOutput createLSOutput()
273   {
274     return new DomLSOutput();
275   }
276 
277 }
278