~ubuntu-branches/ubuntu/karmic/libxerces2-java/karmic

« back to all changes in this revision

Viewing changes to src/org/apache/xerces/dom/CoreDOMImplementationImpl.java

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2006-12-04 17:37:55 UTC
  • mfrom: (2.1.2 etch)
  • Revision ID: james.westby@ubuntu.com-20061204173755-hb6ybrrrk097zhx7
Tags: 2.8.1-1ubuntu1
* Merge with Debian unstable; remaining changes:
  - Build -gcj package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
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/>.
 
2
 * Copyright 1999-2006 The Apache Software Foundation.
 
3
 * 
 
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
 
7
 * 
 
8
 *      http://www.apache.org/licenses/LICENSE-2.0
 
9
 * 
 
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.
56
15
 */
57
16
package org.apache.xerces.dom;
 
17
 
 
18
import java.lang.ref.SoftReference;
 
19
 
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;
 
36
 
72
37
/**
73
38
 * The DOMImplementation class is description of a particular
74
39
 * implementation of the Document Object Model. As such its data is
81
46
 * This particular class, along with CoreDocumentImpl, supports the DOM
82
47
 * Core and Load/Save (Experimental). Optional modules are supported by
83
48
 * the more complete DOMImplementation class along with DocumentImpl.
84
 
 * @version $Id: CoreDOMImplementationImpl.java,v 1.30 2004/02/17 07:14:48 neeraj Exp $
 
49
 * 
 
50
 * @xerces.internal
 
51
 * 
 
52
 * @version $Id: CoreDOMImplementationImpl.java 381413 2006-02-27 19:46:27Z mrglavas $
85
53
 * @since PR-DOM-Level-1-19980818.
86
54
 */
87
55
public class CoreDOMImplementationImpl
88
56
        implements DOMImplementation, DOMImplementationLS {
89
 
        //
90
 
        // Data
91
 
        //
 
57
    
 
58
    //
 
59
    // Data
 
60
    //
92
61
 
93
 
    // validators pool
 
62
    // validator pools
94
63
    private static final int SIZE = 2;
95
 
    private RevalidationHandler validators[] = new RevalidationHandler[SIZE];
96
 
    private int freeValidatorIndex = -1;
97
 
    private int currentSize = SIZE;
 
64
    
 
65
    private SoftReference schemaValidators[] = new SoftReference[SIZE];
 
66
    private SoftReference xml10DTDValidators[] = new SoftReference[SIZE];
 
67
    private SoftReference xml11DTDValidators[] = new SoftReference[SIZE];
 
68
    
 
69
    private int freeSchemaValidatorIndex = -1;
 
70
    private int freeXML10DTDValidatorIndex = -1;
 
71
    private int freeXML11DTDValidatorIndex = -1;
 
72
    
 
73
    private int schemaValidatorsCurrentSize = SIZE;
 
74
    private int xml10DTDValidatorsCurrentSize = SIZE;
 
75
    private int xml11DTDValidatorsCurrentSize = SIZE;
 
76
    
 
77
    private SoftReference xml10DTDLoaders[] = new SoftReference[SIZE];
 
78
    private SoftReference xml11DTDLoaders[] = new SoftReference[SIZE];
 
79
    
 
80
    private int freeXML10DTDLoaderIndex = -1;
 
81
    private int freeXML11DTDLoaderIndex = -1;
 
82
    
 
83
    private int xml10DTDLoaderCurrentSize = SIZE;
 
84
    private int xml11DTDLoaderCurrentSize = SIZE;
98
85
 
99
86
    // Document and doctype counter.  Used to assign order to documents and
100
87
    // doctypes without owners, on an demand basis.   Used for
101
88
    // compareDocumentPosition
102
89
    private int docAndDoctypeCounter = 0;
103
 
 
 
90
    
104
91
        // static
105
92
        /** Dom implementation singleton. */
106
93
        static CoreDOMImplementationImpl singleton =
119
106
         * Test if the DOM implementation supports a specific "feature" --
120
107
         * currently meaning language and level thereof.
121
108
         *
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.
125
112
         *
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"
129
116
         *
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.
132
119
         */
133
 
    public boolean hasFeature(String feature, String 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 xpathClass =
146
 
                    ObjectFactory.findProviderClass(
147
 
                        "org.apache.xpath.domapi.XPathEvaluatorImpl",
148
 
                        ObjectFactory.findClassLoader(),
149
 
                        true);
150
 
            } catch (Exception 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
 
120
        public boolean hasFeature(String feature, String version) {
 
121
            
 
122
            boolean anyVersion = version == null || version.length() == 0;
 
123
            
 
124
            // check if Xalan implementation is around and if yes report true for supporting
 
125
            // XPath API
 
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"))) {
 
132
                try {
 
133
                    Class xpathClass = ObjectFactory.findProviderClass(
 
134
                        "org.apache.xpath.domapi.XPathEvaluatorImpl",
 
135
                        ObjectFactory.findClassLoader(), true);
 
136
                
 
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")) {
 
143
                        return true;
 
144
                    }
 
145
                }
 
146
                } catch (Exception e) {
 
147
                    return false;
 
148
                }
 
149
                return true;
 
150
            }
 
151
            if (feature.startsWith("+")) {
 
152
                feature = feature.substring(1);
 
153
            }
 
154
            return (
 
155
                feature.equalsIgnoreCase("Core")
 
156
                    && (anyVersion
 
157
                        || version.equals("1.0")
 
158
                        || version.equals("2.0")
 
159
                        || version.equals("3.0")))
 
160
                        || (feature.equalsIgnoreCase("XML")
 
161
                    && (anyVersion
 
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
169
168
 
170
169
 
171
170
        /**
293
292
 
294
293
        /**
295
294
         * DOM Level 3 WD - Experimental.
296
 
     */
 
295
         */
297
296
        public Object getFeature(String feature, String version) {
298
 
                if (singleton.hasFeature(feature, version)){
299
 
                        return singleton;
300
 
                }
301
 
                return null;
302
 
 
 
297
            if (singleton.hasFeature(feature, version)) {
 
298
                if ((feature.equalsIgnoreCase("+XPath"))) {
 
299
                    try {
 
300
                        Class xpathClass = ObjectFactory.findProviderClass(
 
301
                            "org.apache.xpath.domapi.XPathEvaluatorImpl",
 
302
                            ObjectFactory.findClassLoader(), true);
 
303
                        
 
304
                        // Check if the DOM XPath implementation implements
 
305
                        // the interface org.w3c.dom.XPathEvaluator
 
306
                        Class interfaces[] = xpathClass.getInterfaces();
 
307
                        for (int i = 0; i < interfaces.length; i++) {
 
308
                            if (interfaces[i].getName().equals(
 
309
                                "org.w3c.dom.xpath.XPathEvaluator")) {
 
310
                                return xpathClass.newInstance();
 
311
                            }
 
312
                        }
 
313
                    } catch (Exception e) {
 
314
                        return null;
 
315
                    }
 
316
                } else {
 
317
                    return singleton;
 
318
                }
 
319
            }
 
320
            return null;
303
321
        }
304
322
 
305
323
        // DOM L3 LS
346
364
     *    NOT_SUPPORTED_ERR: Raised if the requested mode or schema type is
347
365
     *   not supported.
348
366
         */
349
 
        public LSParser createLSParser(short mode, String schemaType)
 
367
    public LSParser createLSParser(short mode, String schemaType)
350
368
                throws DOMException {
351
369
                if (mode != DOMImplementationLS.MODE_SYNCHRONOUS || (schemaType !=null &&
352
370
                   !"http://www.w3.org/2001/XMLSchema".equals(schemaType) &&
367
385
                else {
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",
371
389
                                schemaType);
372
390
                }
373
391
        }
374
392
 
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 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.
 
393
    /**
 
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.
 
405
     */
 
406
    public LSSerializer createLSSerializer() {
 
407
        return new DOMSerializerImpl();
 
408
    }
 
409
    
 
410
        /**
 
411
         * DOM Level 3 LS CR - Experimental.
 
412
         * Create a new empty input source.
 
413
         * @return  The newly created input object.
395
414
         */
396
415
        public LSInput createLSInput() {
397
416
                return new DOMInputImpl();
401
420
        // Protected methods
402
421
        //
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
409
427
            // requested
 
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;
 
436
                    return val;
 
437
                }
 
438
                schemaValidators[freeSchemaValidatorIndex--] = null;
 
439
            }
410
440
            return (RevalidationHandler) (ObjectFactory
411
 
                        .newInstance(
412
 
                            "org.apache.xerces.impl.xs.XMLSchemaValidator",
 
441
                    .newInstance(
 
442
                        "org.apache.xerces.impl.xs.XMLSchemaValidator",
 
443
                        ObjectFactory.findClassLoader(),
 
444
                        true));
 
445
        }
 
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;
 
457
                        return val;
 
458
                    }
 
459
                    xml11DTDValidators[freeXML11DTDValidatorIndex--] = null;
 
460
                }
 
461
                return (RevalidationHandler) (ObjectFactory
 
462
                        .newInstance(
 
463
                                "org.apache.xerces.impl.dtd.XML11DTDValidator",
 
464
                                ObjectFactory.findClassLoader(),
 
465
                                true));
 
466
            }
 
467
            // return an instance of XMLDTDValidator
 
468
            else {
 
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;
 
477
                        return val;
 
478
                    }
 
479
                    xml10DTDValidators[freeXML10DTDValidatorIndex--] = null;
 
480
                }
 
481
                return (RevalidationHandler) (ObjectFactory
 
482
                        .newInstance(
 
483
                            "org.apache.xerces.impl.dtd.XMLDTDValidator",
413
484
                            ObjectFactory.findClassLoader(),
414
485
                            true));
415
 
 
 
486
            }
416
487
        }
417
 
        // return first available validator
418
 
        RevalidationHandler val = validators[freeValidatorIndex];
419
 
        validators[freeValidatorIndex--] = null;
420
 
        return val;
 
488
        return null;
421
489
        }
422
490
 
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
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 createLSOutput() {
457
 
           return new DOMOutputImpl();
458
 
       }
 
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;
 
502
                }
 
503
                SoftReference ref = schemaValidators[freeSchemaValidatorIndex];
 
504
                if (ref != null) {
 
505
                    RevalidationHandlerHolder holder = (RevalidationHandlerHolder) ref.get();
 
506
                    if (holder != null) {
 
507
                        holder.handler = validator;
 
508
                        return;
 
509
                    }
 
510
                }
 
511
                schemaValidators[freeSchemaValidatorIndex] = new SoftReference(new RevalidationHandlerHolder(validator));
 
512
            }
 
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;
 
523
                    }
 
524
                    SoftReference ref = xml11DTDValidators[freeXML11DTDValidatorIndex];
 
525
                    if (ref != null) {
 
526
                        RevalidationHandlerHolder holder = (RevalidationHandlerHolder) ref.get();
 
527
                        if (holder != null) {
 
528
                            holder.handler = validator;
 
529
                            return;
 
530
                        }
 
531
                    }
 
532
                    xml11DTDValidators[freeXML11DTDValidatorIndex] = new SoftReference(new RevalidationHandlerHolder(validator));
 
533
                }
 
534
                // release an instance of XMLDTDValidator
 
535
                else {
 
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;
 
543
                    }
 
544
                    SoftReference ref = xml10DTDValidators[freeXML10DTDValidatorIndex];
 
545
                    if (ref != null) {
 
546
                        RevalidationHandlerHolder holder = (RevalidationHandlerHolder) ref.get();
 
547
                        if (holder != null) {
 
548
                            holder.handler = validator;
 
549
                            return;
 
550
                        }
 
551
                    }
 
552
                    xml10DTDValidators[freeXML10DTDValidatorIndex] = new SoftReference(new RevalidationHandlerHolder(validator));
 
553
                }
 
554
            }
 
555
        }
 
556
    
 
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;
 
569
                    return val;
 
570
                }
 
571
                xml11DTDLoaders[freeXML11DTDLoaderIndex--] = null;
 
572
            }
 
573
            return (XMLDTDLoader) (ObjectFactory
 
574
                    .newInstance(
 
575
                        "org.apache.xerces.impl.dtd.XML11DTDProcessor",
 
576
                        ObjectFactory.findClassLoader(),
 
577
                        true));
 
578
        }
 
579
        // return an instance of XMLDTDLoader
 
580
        else {
 
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;
 
589
                    return val;
 
590
                }
 
591
                xml10DTDLoaders[freeXML10DTDLoaderIndex--] = null;
 
592
            }
 
593
            return new XMLDTDLoader();
 
594
        }
 
595
    }
 
596
    
 
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;
 
608
            }
 
609
            SoftReference ref = xml11DTDLoaders[freeXML11DTDLoaderIndex];
 
610
            if (ref != null) {
 
611
                XMLDTDLoaderHolder holder = (XMLDTDLoaderHolder) ref.get();
 
612
                if (holder != null) {
 
613
                    holder.loader = loader;
 
614
                    return;
 
615
                }
 
616
            }
 
617
            xml11DTDLoaders[freeXML11DTDLoaderIndex] = new SoftReference(new XMLDTDLoaderHolder(loader));
 
618
        }
 
619
        // release an instance of XMLDTDLoader
 
620
        else {
 
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;
 
628
            }
 
629
            SoftReference ref = xml10DTDLoaders[freeXML10DTDLoaderIndex];
 
630
            if (ref != null) {
 
631
                XMLDTDLoaderHolder holder = (XMLDTDLoaderHolder) ref.get();
 
632
                if (holder != null) {
 
633
                    holder.loader = loader;
 
634
                    return;
 
635
                }
 
636
            }
 
637
            xml10DTDLoaders[freeXML10DTDLoaderIndex] = new SoftReference(new XMLDTDLoaderHolder(loader));
 
638
        }
 
639
    }
 
640
    
 
641
        /** NON-DOM:  increment document/doctype counter */
 
642
        protected synchronized int assignDocumentNumber() {
 
643
            return ++docAndDoctypeCounter;
 
644
        }
 
645
    
 
646
        /** NON-DOM:  increment document/doctype counter */
 
647
        protected synchronized int assignDocTypeNumber() {
 
648
            return ++docAndDoctypeCounter;
 
649
        }
 
650
        
 
651
        /**
 
652
     * DOM Level 3 LS CR - Experimental.
 
653
         *
 
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.
 
659
         */
 
660
        public LSOutput createLSOutput() {
 
661
            return new DOMOutputImpl();
 
662
        }
 
663
    
 
664
    /**
 
665
     * A holder for RevalidationHandlers. This allows us to reuse
 
666
     * SoftReferences which haven't yet been cleared by the garbage
 
667
     * collector.
 
668
     */
 
669
    static class RevalidationHandlerHolder {
 
670
        RevalidationHandlerHolder(RevalidationHandler handler) {
 
671
            this.handler = handler;
 
672
        }
 
673
        RevalidationHandler handler;
 
674
    }
 
675
    
 
676
    /**
 
677
     * A holder for XMLDTDLoaders. This allows us to reuse SoftReferences 
 
678
     * which haven't yet been cleared by the garbage collector.
 
679
     */
 
680
    static class XMLDTDLoaderHolder {
 
681
        XMLDTDLoaderHolder(XMLDTDLoader loader) {
 
682
            this.loader = loader;
 
683
        }
 
684
        XMLDTDLoader loader;
 
685
    }
459
686
 
460
687
} // class DOMImplementationImpl