2
* The Apache Software License, Version 1.1
5
* Copyright (c) 1999-2003 The Apache Software Foundation. All rights
8
* Redistribution and use in source and binary forms, with or without
9
* modification, are permitted provided that the following conditions
12
* 1. Redistributions of source code must retain the above copyright
13
* notice, this list of conditions and the following disclaimer.
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
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.
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.
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.
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
48
* ====================================================================
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/>.
2
* Copyright 1999-2006 The Apache Software Foundation.
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
8
* http://www.apache.org/licenses/LICENSE-2.0
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
57
16
package org.apache.xerces.dom;
18
import java.lang.ref.SoftReference;
58
20
import org.apache.xerces.impl.RevalidationHandler;
21
import org.apache.xerces.impl.dtd.XMLDTDLoader;
59
22
import org.apache.xerces.parsers.DOMParserImpl;
60
23
import org.apache.xerces.util.XMLChar;
24
import org.apache.xerces.xni.grammars.XMLGrammarDescription;
61
25
import org.apache.xml.serialize.DOMSerializerImpl;
62
26
import org.w3c.dom.DOMException;
63
27
import org.w3c.dom.DOMImplementation;
64
28
import org.w3c.dom.Document;
65
29
import org.w3c.dom.DocumentType;
66
30
import org.w3c.dom.Element;
67
import org.w3c.dom.ls.LSParser;
68
31
import org.w3c.dom.ls.DOMImplementationLS;
69
32
import org.w3c.dom.ls.LSInput;
70
33
import org.w3c.dom.ls.LSOutput;
34
import org.w3c.dom.ls.LSParser;
71
35
import org.w3c.dom.ls.LSSerializer;
73
38
* The DOMImplementation class is description of a particular
74
39
* implementation of the Document Object Model. As such its data is
119
106
* Test if the DOM implementation supports a specific "feature" --
120
107
* currently meaning language and level thereof.
122
* @param feature The package name of the feature to test.
109
* @param feature The package name of the feature to test.
123
110
* In Level 1, supported values are "HTML" and "XML" (case-insensitive).
124
111
* At this writing, org.apache.xerces.dom supports only XML.
126
* @param version The version number of the feature being tested.
113
* @param version The version number of the feature being tested.
127
114
* This is interpreted as "Version of the DOM API supported for the
128
115
* specified Feature", and in Level 1 should be "1.0"
130
* @return true iff this implementation is compatable with the specified
117
* @return true iff this implementation is compatable with the specified
131
118
* feature and version.
133
public boolean hasFeature(String feature, String version) {
135
boolean anyVersion = version == null || version.length() == 0;
136
if (feature.startsWith("+")) {
137
feature = feature.substring(1);
139
// check if Xalan implementation is around and if yes report true for supporting
141
if ((feature.equalsIgnoreCase("XPath")
142
|| feature.equalsIgnoreCase("+XPath"))
143
&& (anyVersion || version.equals("3.0"))) {
146
ObjectFactory.findProviderClass(
147
"org.apache.xpath.domapi.XPathEvaluatorImpl",
148
ObjectFactory.findClassLoader(),
150
} catch (Exception e) {
156
feature.equalsIgnoreCase("Core")
158
|| version.equals("1.0")
159
|| version.equals("2.0")
160
|| version.equals("3.0")))
161
|| (feature.equalsIgnoreCase("XML")
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
120
public boolean hasFeature(String feature, String version) {
122
boolean anyVersion = version == null || version.length() == 0;
124
// check if Xalan implementation is around and if yes report true for supporting
126
// if a plus sign "+" is prepended to any feature name, implementations
127
// are considered in which the specified feature may not be directly
128
// castable DOMImplementation.getFeature(feature, version). Without a
129
// plus, only features whose interfaces are directly castable are considered.
130
if ((feature.equalsIgnoreCase("+XPath"))
131
&& (anyVersion || version.equals("3.0"))) {
133
Class xpathClass = ObjectFactory.findProviderClass(
134
"org.apache.xpath.domapi.XPathEvaluatorImpl",
135
ObjectFactory.findClassLoader(), true);
137
// Check if the DOM XPath implementation implements
138
// the interface org.w3c.dom.XPathEvaluator
139
Class interfaces[] = xpathClass.getInterfaces();
140
for (int i = 0; i < interfaces.length; i++) {
141
if (interfaces[i].getName().equals(
142
"org.w3c.dom.xpath.XPathEvaluator")) {
146
} catch (Exception e) {
151
if (feature.startsWith("+")) {
152
feature = feature.substring(1);
155
feature.equalsIgnoreCase("Core")
157
|| version.equals("1.0")
158
|| version.equals("2.0")
159
|| version.equals("3.0")))
160
|| (feature.equalsIgnoreCase("XML")
162
|| version.equals("1.0")
163
|| version.equals("2.0")
164
|| version.equals("3.0")))
165
|| (feature.equalsIgnoreCase("LS")
166
&& (anyVersion || version.equals("3.0")));
167
} // hasFeature(String,String):boolean
368
386
// create default parser configuration validating against XMLSchemas
369
387
return new DOMParserImpl(
370
"org.apache.xerces.parsers.XML11Configuration",
388
"org.apache.xerces.parsers.XIncludeAwareParserConfiguration",
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.
388
public LSSerializer createLSSerializer() {
389
return new DOMSerializerImpl();
392
* DOM Level 3 LS CR - Experimental.
393
* Create a new empty input source.
394
* @return The newly created input object.
394
* DOM Level 3 LS CR - Experimental.
395
* Create a new <code>LSSerializer</code> object.
396
* @return The newly created <code>LSSerializer</code> object.
397
* <p ><b>Note:</b> By default, the newly created
398
* <code>LSSerializer</code> has no <code>DOMErrorHandler</code>,
399
* i.e. the value of the <code>"error-handler"</code> configuration
400
* parameter is <code>null</code>. However, implementations may
401
* provide a default error handler at creation time. In that case, the
402
* initial value of the <code>"error-handler"</code> configuration
403
* parameter on the new created <code>LSSerializer</code> contains a
404
* reference to the default error handler.
406
public LSSerializer createLSSerializer() {
407
return new DOMSerializerImpl();
411
* DOM Level 3 LS CR - Experimental.
412
* Create a new empty input source.
413
* @return The newly created input object.
396
415
public LSInput createLSInput() {
397
416
return new DOMInputImpl();
401
420
// Protected methods
403
422
/** NON-DOM: retrieve validator. */
404
synchronized RevalidationHandler getValidator(String schemaType) {
405
// REVISIT: implement retrieving DTD validator
406
if (freeValidatorIndex < 0) {
423
synchronized RevalidationHandler getValidator(String schemaType, String xmlVersion) {
424
if (schemaType == XMLGrammarDescription.XML_SCHEMA) {
407
425
// create new validator - we should not attempt
408
426
// to restrict the number of validation handlers being
428
while (freeSchemaValidatorIndex >= 0) {
429
// return first available validator
430
SoftReference ref = schemaValidators[freeSchemaValidatorIndex];
431
RevalidationHandlerHolder holder = (RevalidationHandlerHolder) ref.get();
432
if (holder != null && holder.handler != null) {
433
RevalidationHandler val = holder.handler;
434
holder.handler = null;
435
--freeSchemaValidatorIndex;
438
schemaValidators[freeSchemaValidatorIndex--] = null;
410
440
return (RevalidationHandler) (ObjectFactory
412
"org.apache.xerces.impl.xs.XMLSchemaValidator",
442
"org.apache.xerces.impl.xs.XMLSchemaValidator",
443
ObjectFactory.findClassLoader(),
446
else if(schemaType == XMLGrammarDescription.XML_DTD) {
447
// return an instance of XML11DTDValidator
448
if ("1.1".equals(xmlVersion)) {
449
while (freeXML11DTDValidatorIndex >= 0) {
450
// return first available validator
451
SoftReference ref = xml11DTDValidators[freeXML11DTDValidatorIndex];
452
RevalidationHandlerHolder holder = (RevalidationHandlerHolder) ref.get();
453
if (holder != null && holder.handler != null) {
454
RevalidationHandler val = holder.handler;
455
holder.handler = null;
456
--freeXML11DTDValidatorIndex;
459
xml11DTDValidators[freeXML11DTDValidatorIndex--] = null;
461
return (RevalidationHandler) (ObjectFactory
463
"org.apache.xerces.impl.dtd.XML11DTDValidator",
464
ObjectFactory.findClassLoader(),
467
// return an instance of XMLDTDValidator
469
while (freeXML10DTDValidatorIndex >= 0) {
470
// return first available validator
471
SoftReference ref = xml10DTDValidators[freeXML10DTDValidatorIndex];
472
RevalidationHandlerHolder holder = (RevalidationHandlerHolder) ref.get();
473
if (holder != null && holder.handler != null) {
474
RevalidationHandler val = holder.handler;
475
holder.handler = null;
476
--freeXML10DTDValidatorIndex;
479
xml10DTDValidators[freeXML10DTDValidatorIndex--] = null;
481
return (RevalidationHandler) (ObjectFactory
483
"org.apache.xerces.impl.dtd.XMLDTDValidator",
413
484
ObjectFactory.findClassLoader(),
417
// return first available validator
418
RevalidationHandler val = validators[freeValidatorIndex];
419
validators[freeValidatorIndex--] = null;
423
491
/** NON-DOM: release validator */
424
synchronized void releaseValidator(String 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
431
RevalidationHandler newarray[] = new RevalidationHandler[currentSize];
432
System.arraycopy(validators, 0, newarray, 0, validators.length);
433
validators = newarray;
435
validators[freeValidatorIndex]=validator;
438
/** NON-DOM: increment document/doctype counter */
439
protected synchronized int assignDocumentNumber() {
440
return ++docAndDoctypeCounter;
442
/** NON-DOM: increment document/doctype counter */
443
protected synchronized int assignDocTypeNumber() {
444
return ++docAndDoctypeCounter;
447
/* DOM Level 3 LS CR - Experimental.
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.
454
* @return The newly created output object.
456
public LSOutput createLSOutput() {
457
return new DOMOutputImpl();
492
synchronized void releaseValidator(String schemaType, String xmlVersion,
493
RevalidationHandler validator) {
494
if (schemaType == XMLGrammarDescription.XML_SCHEMA) {
495
++freeSchemaValidatorIndex;
496
if (schemaValidators.length == freeSchemaValidatorIndex) {
497
// resize size of the validators
498
schemaValidatorsCurrentSize += SIZE;
499
SoftReference newarray[] = new SoftReference[schemaValidatorsCurrentSize];
500
System.arraycopy(schemaValidators, 0, newarray, 0, schemaValidators.length);
501
schemaValidators = newarray;
503
SoftReference ref = schemaValidators[freeSchemaValidatorIndex];
505
RevalidationHandlerHolder holder = (RevalidationHandlerHolder) ref.get();
506
if (holder != null) {
507
holder.handler = validator;
511
schemaValidators[freeSchemaValidatorIndex] = new SoftReference(new RevalidationHandlerHolder(validator));
513
else if (schemaType == XMLGrammarDescription.XML_DTD) {
514
// release an instance of XML11DTDValidator
515
if ("1.1".equals(xmlVersion)) {
516
++freeXML11DTDValidatorIndex;
517
if (xml11DTDValidators.length == freeXML11DTDValidatorIndex) {
518
// resize size of the validators
519
xml11DTDValidatorsCurrentSize += SIZE;
520
SoftReference [] newarray = new SoftReference[xml11DTDValidatorsCurrentSize];
521
System.arraycopy(xml11DTDValidators, 0, newarray, 0, xml11DTDValidators.length);
522
xml11DTDValidators = newarray;
524
SoftReference ref = xml11DTDValidators[freeXML11DTDValidatorIndex];
526
RevalidationHandlerHolder holder = (RevalidationHandlerHolder) ref.get();
527
if (holder != null) {
528
holder.handler = validator;
532
xml11DTDValidators[freeXML11DTDValidatorIndex] = new SoftReference(new RevalidationHandlerHolder(validator));
534
// release an instance of XMLDTDValidator
536
++freeXML10DTDValidatorIndex;
537
if (xml10DTDValidators.length == freeXML10DTDValidatorIndex) {
538
// resize size of the validators
539
xml10DTDValidatorsCurrentSize += SIZE;
540
SoftReference [] newarray = new SoftReference[xml10DTDValidatorsCurrentSize];
541
System.arraycopy(xml10DTDValidators, 0, newarray, 0, xml10DTDValidators.length);
542
xml10DTDValidators = newarray;
544
SoftReference ref = xml10DTDValidators[freeXML10DTDValidatorIndex];
546
RevalidationHandlerHolder holder = (RevalidationHandlerHolder) ref.get();
547
if (holder != null) {
548
holder.handler = validator;
552
xml10DTDValidators[freeXML10DTDValidatorIndex] = new SoftReference(new RevalidationHandlerHolder(validator));
557
/** NON-DOM: retrieve DTD loader */
558
synchronized final XMLDTDLoader getDTDLoader(String xmlVersion) {
559
// return an instance of XML11DTDProcessor
560
if ("1.1".equals(xmlVersion)) {
561
while (freeXML11DTDLoaderIndex >= 0) {
562
// return first available DTD loader
563
SoftReference ref = xml11DTDLoaders[freeXML11DTDLoaderIndex];
564
XMLDTDLoaderHolder holder = (XMLDTDLoaderHolder) ref.get();
565
if (holder != null && holder.loader != null) {
566
XMLDTDLoader val = holder.loader;
567
holder.loader = null;
568
--freeXML11DTDLoaderIndex;
571
xml11DTDLoaders[freeXML11DTDLoaderIndex--] = null;
573
return (XMLDTDLoader) (ObjectFactory
575
"org.apache.xerces.impl.dtd.XML11DTDProcessor",
576
ObjectFactory.findClassLoader(),
579
// return an instance of XMLDTDLoader
581
while (freeXML10DTDLoaderIndex >= 0) {
582
// return first available DTD loader
583
SoftReference ref = xml10DTDLoaders[freeXML10DTDLoaderIndex];
584
XMLDTDLoaderHolder holder = (XMLDTDLoaderHolder) ref.get();
585
if (holder != null && holder.loader != null) {
586
XMLDTDLoader val = holder.loader;
587
holder.loader = null;
588
--freeXML10DTDLoaderIndex;
591
xml10DTDLoaders[freeXML10DTDLoaderIndex--] = null;
593
return new XMLDTDLoader();
597
/** NON-DOM: release DTD loader */
598
synchronized final void releaseDTDLoader(String xmlVersion, XMLDTDLoader loader) {
599
// release an instance of XMLDTDLoader
600
if ("1.1".equals(xmlVersion)) {
601
++freeXML11DTDLoaderIndex;
602
if (xml11DTDLoaders.length == freeXML11DTDLoaderIndex) {
603
// resize size of the DTD loaders
604
xml11DTDLoaderCurrentSize += SIZE;
605
SoftReference [] newarray = new SoftReference[xml11DTDLoaderCurrentSize];
606
System.arraycopy(xml11DTDLoaders, 0, newarray, 0, xml11DTDLoaders.length);
607
xml11DTDLoaders = newarray;
609
SoftReference ref = xml11DTDLoaders[freeXML11DTDLoaderIndex];
611
XMLDTDLoaderHolder holder = (XMLDTDLoaderHolder) ref.get();
612
if (holder != null) {
613
holder.loader = loader;
617
xml11DTDLoaders[freeXML11DTDLoaderIndex] = new SoftReference(new XMLDTDLoaderHolder(loader));
619
// release an instance of XMLDTDLoader
621
++freeXML10DTDLoaderIndex;
622
if (xml10DTDLoaders.length == freeXML10DTDLoaderIndex) {
623
// resize size of the DTD loaders
624
xml10DTDLoaderCurrentSize += SIZE;
625
SoftReference [] newarray = new SoftReference[xml10DTDLoaderCurrentSize];
626
System.arraycopy(xml10DTDLoaders, 0, newarray, 0, xml10DTDLoaders.length);
627
xml10DTDLoaders = newarray;
629
SoftReference ref = xml10DTDLoaders[freeXML10DTDLoaderIndex];
631
XMLDTDLoaderHolder holder = (XMLDTDLoaderHolder) ref.get();
632
if (holder != null) {
633
holder.loader = loader;
637
xml10DTDLoaders[freeXML10DTDLoaderIndex] = new SoftReference(new XMLDTDLoaderHolder(loader));
641
/** NON-DOM: increment document/doctype counter */
642
protected synchronized int assignDocumentNumber() {
643
return ++docAndDoctypeCounter;
646
/** NON-DOM: increment document/doctype counter */
647
protected synchronized int assignDocTypeNumber() {
648
return ++docAndDoctypeCounter;
652
* DOM Level 3 LS CR - Experimental.
654
* Create a new empty output destination object where
655
* <code>LSOutput.characterStream</code>,
656
* <code>LSOutput.byteStream</code>, <code>LSOutput.systemId</code>,
657
* <code>LSOutput.encoding</code> are null.
658
* @return The newly created output object.
660
public LSOutput createLSOutput() {
661
return new DOMOutputImpl();
665
* A holder for RevalidationHandlers. This allows us to reuse
666
* SoftReferences which haven't yet been cleared by the garbage
669
static class RevalidationHandlerHolder {
670
RevalidationHandlerHolder(RevalidationHandler handler) {
671
this.handler = handler;
673
RevalidationHandler handler;
677
* A holder for XMLDTDLoaders. This allows us to reuse SoftReferences
678
* which haven't yet been cleared by the garbage collector.
680
static class XMLDTDLoaderHolder {
681
XMLDTDLoaderHolder(XMLDTDLoader loader) {
682
this.loader = loader;
460
687
} // class DOMImplementationImpl