KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xerces > internal > dom > CoreDOMImplementationImpl


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 1999-2003 The Apache Software Foundation. All rights
6  * reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Xerces" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation and was
52  * originally based on software copyright (c) 1999, International
53  * Business Machines, Inc., http://www.apache.org. For more
54  * information on the Apache Software Foundation, please see
55  * <http://www.apache.org/>.
56  */

57 package com.sun.org.apache.xerces.internal.dom;
58 import com.sun.org.apache.xerces.internal.impl.RevalidationHandler;
59 import com.sun.org.apache.xerces.internal.parsers.DOMParserImpl;
60 import com.sun.org.apache.xerces.internal.util.XMLChar;
61 import com.sun.org.apache.xml.internal.serialize.DOMSerializerImpl;
62 import org.w3c.dom.DOMException JavaDoc;
63 import org.w3c.dom.DOMImplementation JavaDoc;
64 import org.w3c.dom.Document JavaDoc;
65 import org.w3c.dom.DocumentType JavaDoc;
66 import org.w3c.dom.Element JavaDoc;
67 import org.w3c.dom.ls.LSParser JavaDoc;
68 import org.w3c.dom.ls.DOMImplementationLS JavaDoc;
69 import org.w3c.dom.ls.LSInput JavaDoc;
70 import org.w3c.dom.ls.LSOutput JavaDoc;
71 import org.w3c.dom.ls.LSSerializer JavaDoc;
72 /**
73  * The DOMImplementation class is description of a particular
74  * implementation of the Document Object Model. As such its data is
75  * static, shared by all instances of this implementation.
76  * <P>
77  * The DOM API requires that it be a real object rather than static
78  * methods. However, there's nothing that says it can't be a singleton,
79  * so that's how I've implemented it.
80  * <P>
81  * This particular class, along with CoreDocumentImpl, supports the DOM
82  * Core and Load/Save (Experimental). Optional modules are supported by
83  * the more complete DOMImplementation class along with DocumentImpl.
84  * @version $Id: CoreDOMImplementationImpl.java,v 1.30 2004/02/17 07:14:48 neeraj Exp $
85  * @since PR-DOM-Level-1-19980818.
86  */

87 public class CoreDOMImplementationImpl
88     implements DOMImplementation JavaDoc, DOMImplementationLS JavaDoc {
89     //
90
// Data
91
//
92

93     // validators pool
94
private static final int SIZE = 2;
95     private RevalidationHandler validators[] = new RevalidationHandler[SIZE];
96     private int freeValidatorIndex = -1;
97     private int currentSize = SIZE;
98
99     // Document and doctype counter. Used to assign order to documents and
100
// doctypes without owners, on an demand basis. Used for
101
// compareDocumentPosition
102
private int docAndDoctypeCounter = 0;
103
104     // static
105
/** Dom implementation singleton. */
106     static CoreDOMImplementationImpl singleton =
107         new CoreDOMImplementationImpl();
108     //
109
// Public methods
110
//
111
/** NON-DOM: Obtain and return the single shared object */
112     public static DOMImplementation JavaDoc getDOMImplementation() {
113         return singleton;
114     }
115     //
116
// DOMImplementation methods
117
//
118
/**
119      * Test if the DOM implementation supports a specific "feature" --
120      * currently meaning language and level thereof.
121      *
122      * @param feature The package name of the feature to test.
123      * In Level 1, supported values are "HTML" and "XML" (case-insensitive).
124      * At this writing, com.sun.org.apache.xerces.internal.dom supports only XML.
125      *
126      * @param version The version number of the feature being tested.
127      * This is interpreted as "Version of the DOM API supported for the
128      * specified Feature", and in Level 1 should be "1.0"
129      *
130      * @return true iff this implementation is compatable with the specified
131      * feature and version.
132      */

133     public boolean hasFeature(String JavaDoc feature, String JavaDoc version) {
134
135         boolean anyVersion = version == null || version.length() == 0;
136         if (feature.startsWith("+")) {
137             feature = feature.substring(1);
138         }
139         // check if Xalan implementation is around and if yes report true for supporting
140
// XPath API
141
if ((feature.equalsIgnoreCase("XPath")
142             || feature.equalsIgnoreCase("+XPath"))
143             && (anyVersion || version.equals("3.0"))) {
144             try {
145                 Class JavaDoc xpathClass =
146                     ObjectFactory.findProviderClass(
147                         "com.sun.org.apache.xpath.internal.domapi.XPathEvaluatorImpl",
148                         ObjectFactory.findClassLoader(),
149                         true);
150             } catch (Exception JavaDoc e) {
151                 return false;
152             }
153             return true;
154         }
155         return (
156             feature.equalsIgnoreCase("Core")
157                 && (anyVersion
158                     || version.equals("1.0")
159                     || version.equals("2.0")
160                     || version.equals("3.0")))
161             || (feature.equalsIgnoreCase("XML")
162                 && (anyVersion
163                     || version.equals("1.0")
164                     || version.equals("2.0")
165                     || version.equals("3.0")))
166             || (feature.equalsIgnoreCase("LS")
167                 && (anyVersion || version.equals("3.0")));
168     } // hasFeature(String,String):boolean
169

170
171     /**
172      * Introduced in DOM Level 2. <p>
173      *
174      * Creates an empty DocumentType node.
175      *
176      * @param qualifiedName The qualified name of the document type to be created.
177      * @param publicID The document type public identifier.
178      * @param systemID The document type system identifier.
179      * @since WD-DOM-Level-2-19990923
180      */

181     public DocumentType JavaDoc createDocumentType( String JavaDoc qualifiedName,
182                                     String JavaDoc publicID, String JavaDoc systemID) {
183         // REVISIT: this might allow creation of invalid name for DOCTYPE
184
// xmlns prefix.
185
// also there is no way for a user to turn off error checking.
186
checkQName(qualifiedName);
187         return new DocumentTypeImpl(null, qualifiedName, publicID, systemID);
188     }
189
190     final void checkQName(String JavaDoc qname){
191         int index = qname.indexOf(':');
192         int lastIndex = qname.lastIndexOf(':');
193         int length = qname.length();
194
195         // it is an error for NCName to have more than one ':'
196
// check if it is valid QName [Namespace in XML production 6]
197
if (index == 0 || index == length - 1 || lastIndex != index) {
198             String JavaDoc msg =
199                 DOMMessageFormatter.formatMessage(
200                     DOMMessageFormatter.DOM_DOMAIN,
201                     "NAMESPACE_ERR",
202                     null);
203             throw new DOMException JavaDoc(DOMException.NAMESPACE_ERR, msg);
204         }
205         int start = 0;
206         // Namespace in XML production [6]
207
if (index > 0) {
208             // check that prefix is NCName
209
if (!XMLChar.isNCNameStart(qname.charAt(start))) {
210                 String JavaDoc msg =
211                     DOMMessageFormatter.formatMessage(
212                         DOMMessageFormatter.DOM_DOMAIN,
213                         "INVALID_CHARACTER_ERR",
214                         null);
215                 throw new DOMException JavaDoc(DOMException.INVALID_CHARACTER_ERR, msg);
216             }
217             for (int i = 1; i < index; i++) {
218                 if (!XMLChar.isNCName(qname.charAt(i))) {
219                     String JavaDoc msg =
220                         DOMMessageFormatter.formatMessage(
221                             DOMMessageFormatter.DOM_DOMAIN,
222                             "INVALID_CHARACTER_ERR",
223                             null);
224                     throw new DOMException JavaDoc(
225                         DOMException.INVALID_CHARACTER_ERR,
226                         msg);
227                 }
228             }
229             start = index + 1;
230         }
231
232         // check local part
233
if (!XMLChar.isNCNameStart(qname.charAt(start))) {
234             // REVISIT: add qname parameter to the message
235
String JavaDoc msg =
236                 DOMMessageFormatter.formatMessage(
237                     DOMMessageFormatter.DOM_DOMAIN,
238                     "INVALID_CHARACTER_ERR",
239                     null);
240             throw new DOMException JavaDoc(DOMException.INVALID_CHARACTER_ERR, msg);
241         }
242         for (int i = start + 1; i < length; i++) {
243             if (!XMLChar.isNCName(qname.charAt(i))) {
244                 String JavaDoc msg =
245                     DOMMessageFormatter.formatMessage(
246                         DOMMessageFormatter.DOM_DOMAIN,
247                         "INVALID_CHARACTER_ERR",
248                         null);
249                 throw new DOMException JavaDoc(DOMException.INVALID_CHARACTER_ERR, msg);
250             }
251         }
252     }
253
254
255     /**
256      * Introduced in DOM Level 2. <p>
257      *
258      * Creates an XML Document object of the specified type with its document
259      * element.
260      *
261      * @param namespaceURI The namespace URI of the document
262      * element to create, or null.
263      * @param qualifiedName The qualified name of the document
264      * element to create.
265      * @param doctype The type of document to be created or null.<p>
266      *
267      * When doctype is not null, its
268      * Node.ownerDocument attribute is set to
269      * the document being created.
270      * @return Document A new Document object.
271      * @throws DOMException WRONG_DOCUMENT_ERR: Raised if doctype has
272      * already been used with a different document.
273      * @since WD-DOM-Level-2-19990923
274      */

275     public Document JavaDoc createDocument(
276         String JavaDoc namespaceURI,
277         String JavaDoc qualifiedName,
278         DocumentType JavaDoc doctype)
279         throws DOMException JavaDoc {
280         if (doctype != null && doctype.getOwnerDocument() != null) {
281             String JavaDoc msg =
282                 DOMMessageFormatter.formatMessage(
283                     DOMMessageFormatter.DOM_DOMAIN,
284                     "WRONG_DOCUMENT_ERR",
285                     null);
286             throw new DOMException JavaDoc(DOMException.WRONG_DOCUMENT_ERR, msg);
287         }
288         CoreDocumentImpl doc = new CoreDocumentImpl(doctype);
289         Element JavaDoc e = doc.createElementNS(namespaceURI, qualifiedName);
290         doc.appendChild(e);
291         return doc;
292     }
293
294     /**
295      * DOM Level 3 WD - Experimental.
296      */

297     public Object JavaDoc getFeature(String JavaDoc feature, String JavaDoc version) {
298         if (singleton.hasFeature(feature, version)){
299             return singleton;
300         }
301         return null;
302
303     }
304
305     // DOM L3 LS
306

307     /**
308      * DOM Level 3 LS CR - Experimental.
309      * Create a new <code>LSParser</code>. The newly constructed parser may
310      * then be configured by means of its <code>DOMConfiguration</code>
311      * object, and used to parse documents by means of its <code>parse</code>
312      * method.
313      * @param mode The <code>mode</code> argument is either
314      * <code>MODE_SYNCHRONOUS</code> or <code>MODE_ASYNCHRONOUS</code>, if
315      * <code>mode</code> is <code>MODE_SYNCHRONOUS</code> then the
316      * <code>LSParser</code> that is created will operate in synchronous
317      * mode, if it's <code>MODE_ASYNCHRONOUS</code> then the
318      * <code>LSParser</code> that is created will operate in asynchronous
319      * mode.
320      * @param schemaType An absolute URI representing the type of the schema
321      * language used during the load of a <code>Document</code> using the
322      * newly created <code>LSParser</code>. Note that no lexical checking
323      * is done on the absolute URI. In order to create a
324      * <code>LSParser</code> for any kind of schema types (i.e. the
325      * LSParser will be free to use any schema found), use the value
326      * <code>null</code>.
327      * <p ><b>Note:</b> For W3C XML Schema [<a HREF='http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/'>XML Schema Part 1</a>]
328      * , applications must use the value
329      * <code>"http://www.w3.org/2001/XMLSchema"</code>. For XML DTD [<a HREF='http://www.w3.org/TR/2000/REC-xml-20001006'>XML 1.0</a>],
330      * applications must use the value
331      * <code>"http://www.w3.org/TR/REC-xml"</code>. Other Schema languages
332      * are outside the scope of the W3C and therefore should recommend an
333      * absolute URI in order to use this method.
334      * @return The newly created <code>LSParser</code> object. This
335      * <code>LSParser</code> is either synchronous or asynchronous
336      * depending on the value of the <code>mode</code> argument.
337      * <p ><b>Note:</b> By default, the newly created <code>LSParser</code>
338      * does not contain a <code>DOMErrorHandler</code>, i.e. the value of
339      * the "<a HREF='http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030609/core.html#parameter-error-handler'>
340      * error-handler</a>" configuration parameter is <code>null</code>. However, implementations
341      * may provide a default error handler at creation time. In that case,
342      * the initial value of the <code>"error-handler"</code> configuration
343      * parameter on the new created <code>LSParser</code> contains a
344      * reference to the default error handler.
345      * @exception DOMException
346      * NOT_SUPPORTED_ERR: Raised if the requested mode or schema type is
347      * not supported.
348      */

349         public LSParser JavaDoc createLSParser(short mode, String JavaDoc schemaType)
350         throws DOMException JavaDoc {
351         if (mode != DOMImplementationLS.MODE_SYNCHRONOUS || (schemaType !=null &&
352            !"http://www.w3.org/2001/XMLSchema".equals(schemaType) &&
353             !"http://www.w3.org/TR/REC-xml".equals(schemaType))) {
354             String JavaDoc msg =
355                 DOMMessageFormatter.formatMessage(
356                     DOMMessageFormatter.DOM_DOMAIN,
357                     "NOT_SUPPORTED_ERR",
358                     null);
359             throw new DOMException JavaDoc(DOMException.NOT_SUPPORTED_ERR, msg);
360         }
361         if (schemaType != null
362             && schemaType.equals("http://www.w3.org/TR/REC-xml")) {
363             return new DOMParserImpl(
364                 "com.sun.org.apache.xerces.internal.parsers.XML11Configuration",
365                 schemaType);
366         }
367         else {
368             // create default parser configuration validating against XMLSchemas
369
return new DOMParserImpl(
370                 "com.sun.org.apache.xerces.internal.parsers.XML11Configuration",
371                 schemaType);
372         }
373     }
374
375     /**
376      * DOM Level 3 LS CR - Experimental.
377          * Create a new <code>LSSerializer</code> object.
378          * @return The newly created <code>LSSerializer</code> object.
379          * <p ><b>Note:</b> By default, the newly created
380          * <code>LSSerializer</code> has no <code>DOMErrorHandler</code>,
381          * i.e. the value of the <code>"error-handler"</code> configuration
382          * parameter is <code>null</code>. However, implementations may
383          * provide a default error handler at creation time. In that case, the
384          * initial value of the <code>"error-handler"</code> configuration
385          * parameter on the new created <code>LSSerializer</code> contains a
386          * reference to the default error handler.
387      */

388     public LSSerializer JavaDoc createLSSerializer() {
389         return new DOMSerializerImpl();
390     }
391     /**
392      * DOM Level 3 LS CR - Experimental.
393          * Create a new empty input source.
394          * @return The newly created input object.
395      */

396     public LSInput JavaDoc createLSInput() {
397         return new DOMInputImpl();
398     }
399
400     synchronized Object JavaDoc getDTDValidator() {
401      return ObjectFactory.newInstance( "com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator", ObjectFactory.findClassLoader(), true);
402     }
403
404     //
405
// Protected methods
406
//
407
/** NON-DOM: retrieve validator. */
408     synchronized RevalidationHandler getValidator(String JavaDoc schemaType) {
409         // REVISIT: implement retrieving DTD validator
410
if (freeValidatorIndex < 0) {
411             // create new validator - we should not attempt
412
// to restrict the number of validation handlers being
413
// requested
414
return (RevalidationHandler) (ObjectFactory .newInstance( "com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator", ObjectFactory.findClassLoader(), true));
415
416         }
417         // return first available validator
418
RevalidationHandler val = validators[freeValidatorIndex];
419         validators[freeValidatorIndex--] = null;
420         return val;
421     }
422
423     /** NON-DOM: release validator */
424     synchronized void releaseValidator(String JavaDoc schemaType,
425                                          RevalidationHandler validator) {
426        // REVISIT: implement support for DTD validators as well
427
++freeValidatorIndex;
428        if (validators.length == freeValidatorIndex ){
429             // resize size of the validators
430
currentSize+=SIZE;
431             RevalidationHandler newarray[] = new RevalidationHandler[currentSize];
432             System.arraycopy(validators, 0, newarray, 0, validators.length);
433             validators = newarray;
434        }
435        validators[freeValidatorIndex]=validator;
436     }
437
438        /** NON-DOM: increment document/doctype counter */
439        protected synchronized int assignDocumentNumber() {
440             return ++docAndDoctypeCounter;
441        }
442        /** NON-DOM: increment document/doctype counter */
443        protected synchronized int assignDocTypeNumber() {
444             return ++docAndDoctypeCounter;
445        }
446
447     /* DOM Level 3 LS CR - Experimental.
448      *
449      * Create a new empty output destination object where
450      * <code>LSOutput.characterStream</code>,
451      * <code>LSOutput.byteStream</code>, <code>LSOutput.systemId</code>,
452      * <code>LSOutput.encoding</code> are null.
453
454      * @return The newly created output object.
455      */

456        public LSOutput JavaDoc createLSOutput() {
457            return new DOMOutputImpl();
458        }
459
460 } // class DOMImplementationImpl
461
Popular Tags