src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/validation/SoftReferenceGrammarPool.java
author joehw
Wed, 18 Oct 2017 13:25:49 -0700
changeset 47359 e1a6c0168741
parent 47216 71c04702a3d5
child 47712 bde0215f1f70
permissions -rw-r--r--
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked Reviewed-by: lancea, rriggs, mullan
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
6
7f561c08de6b Initial load
duke
parents:
diff changeset
     1
/*
47359
e1a6c0168741 8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents: 47216
diff changeset
     2
 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
e1a6c0168741 8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents: 47216
diff changeset
     3
 * @LastModified: Oct 2017
6
7f561c08de6b Initial load
duke
parents:
diff changeset
     4
 */
7f561c08de6b Initial load
duke
parents:
diff changeset
     5
/*
44797
8b3b3b911b8a 8162572: Update License Header for all JAXP sources
joehw
parents: 25868
diff changeset
     6
 * Licensed to the Apache Software Foundation (ASF) under one or more
8b3b3b911b8a 8162572: Update License Header for all JAXP sources
joehw
parents: 25868
diff changeset
     7
 * contributor license agreements.  See the NOTICE file distributed with
8b3b3b911b8a 8162572: Update License Header for all JAXP sources
joehw
parents: 25868
diff changeset
     8
 * this work for additional information regarding copyright ownership.
8b3b3b911b8a 8162572: Update License Header for all JAXP sources
joehw
parents: 25868
diff changeset
     9
 * The ASF licenses this file to You under the Apache License, Version 2.0
8b3b3b911b8a 8162572: Update License Header for all JAXP sources
joehw
parents: 25868
diff changeset
    10
 * (the "License"); you may not use this file except in compliance with
8b3b3b911b8a 8162572: Update License Header for all JAXP sources
joehw
parents: 25868
diff changeset
    11
 * the License.  You may obtain a copy of the License at
6
7f561c08de6b Initial load
duke
parents:
diff changeset
    12
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    13
 *      http://www.apache.org/licenses/LICENSE-2.0
7f561c08de6b Initial load
duke
parents:
diff changeset
    14
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    15
 * Unless required by applicable law or agreed to in writing, software
7f561c08de6b Initial load
duke
parents:
diff changeset
    16
 * distributed under the License is distributed on an "AS IS" BASIS,
7f561c08de6b Initial load
duke
parents:
diff changeset
    17
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7f561c08de6b Initial load
duke
parents:
diff changeset
    18
 * See the License for the specific language governing permissions and
7f561c08de6b Initial load
duke
parents:
diff changeset
    19
 * limitations under the License.
7f561c08de6b Initial load
duke
parents:
diff changeset
    20
 */
7f561c08de6b Initial load
duke
parents:
diff changeset
    21
7f561c08de6b Initial load
duke
parents:
diff changeset
    22
package com.sun.org.apache.xerces.internal.jaxp.validation;
7f561c08de6b Initial load
duke
parents:
diff changeset
    23
7f561c08de6b Initial load
duke
parents:
diff changeset
    24
import java.lang.ref.Reference;
7f561c08de6b Initial load
duke
parents:
diff changeset
    25
import java.lang.ref.ReferenceQueue;
7f561c08de6b Initial load
duke
parents:
diff changeset
    26
import java.lang.ref.SoftReference;
7f561c08de6b Initial load
duke
parents:
diff changeset
    27
7f561c08de6b Initial load
duke
parents:
diff changeset
    28
import com.sun.org.apache.xerces.internal.xni.grammars.Grammar;
7f561c08de6b Initial load
duke
parents:
diff changeset
    29
import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription;
7f561c08de6b Initial load
duke
parents:
diff changeset
    30
import com.sun.org.apache.xerces.internal.xni.grammars.XMLSchemaDescription;
7f561c08de6b Initial load
duke
parents:
diff changeset
    31
import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
7f561c08de6b Initial load
duke
parents:
diff changeset
    32
7f561c08de6b Initial load
duke
parents:
diff changeset
    33
/**
7f561c08de6b Initial load
duke
parents:
diff changeset
    34
 * <p>This grammar pool is a memory sensitive cache. The grammars
7f561c08de6b Initial load
duke
parents:
diff changeset
    35
 * stored in the pool are softly reachable and may be cleared by
7f561c08de6b Initial load
duke
parents:
diff changeset
    36
 * the garbage collector in response to memory demand. Equality
7f561c08de6b Initial load
duke
parents:
diff changeset
    37
 * of <code>XMLSchemaDescription</code>s is determined using both
7f561c08de6b Initial load
duke
parents:
diff changeset
    38
 * the target namespace for the schema and schema location.</p>
7f561c08de6b Initial load
duke
parents:
diff changeset
    39
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    40
 * @author Michael Glavassevich, IBM
7f561c08de6b Initial load
duke
parents:
diff changeset
    41
 */
7f561c08de6b Initial load
duke
parents:
diff changeset
    42
final class SoftReferenceGrammarPool implements XMLGrammarPool {
7f561c08de6b Initial load
duke
parents:
diff changeset
    43
7f561c08de6b Initial load
duke
parents:
diff changeset
    44
    //
7f561c08de6b Initial load
duke
parents:
diff changeset
    45
    // Constants
7f561c08de6b Initial load
duke
parents:
diff changeset
    46
    //
7f561c08de6b Initial load
duke
parents:
diff changeset
    47
7f561c08de6b Initial load
duke
parents:
diff changeset
    48
    /** Default size. */
7f561c08de6b Initial load
duke
parents:
diff changeset
    49
    protected static final int TABLE_SIZE = 11;
7f561c08de6b Initial load
duke
parents:
diff changeset
    50
7f561c08de6b Initial load
duke
parents:
diff changeset
    51
    /** Zero length grammar array. */
7f561c08de6b Initial load
duke
parents:
diff changeset
    52
    protected static final Grammar [] ZERO_LENGTH_GRAMMAR_ARRAY = new Grammar [0];
7f561c08de6b Initial load
duke
parents:
diff changeset
    53
7f561c08de6b Initial load
duke
parents:
diff changeset
    54
    //
7f561c08de6b Initial load
duke
parents:
diff changeset
    55
    // Data
7f561c08de6b Initial load
duke
parents:
diff changeset
    56
    //
7f561c08de6b Initial load
duke
parents:
diff changeset
    57
7f561c08de6b Initial load
duke
parents:
diff changeset
    58
    /** Grammars. */
7f561c08de6b Initial load
duke
parents:
diff changeset
    59
    protected Entry [] fGrammars = null;
7f561c08de6b Initial load
duke
parents:
diff changeset
    60
7f561c08de6b Initial load
duke
parents:
diff changeset
    61
    /** Flag indicating whether this pool is locked */
7f561c08de6b Initial load
duke
parents:
diff changeset
    62
    protected boolean fPoolIsLocked;
7f561c08de6b Initial load
duke
parents:
diff changeset
    63
7f561c08de6b Initial load
duke
parents:
diff changeset
    64
    /** The number of grammars in the pool */
7f561c08de6b Initial load
duke
parents:
diff changeset
    65
    protected int fGrammarCount = 0;
7f561c08de6b Initial load
duke
parents:
diff changeset
    66
7f561c08de6b Initial load
duke
parents:
diff changeset
    67
    /** Reference queue for cleared grammar references */
47359
e1a6c0168741 8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents: 47216
diff changeset
    68
    protected final ReferenceQueue<Grammar> fReferenceQueue = new ReferenceQueue<>();
6
7f561c08de6b Initial load
duke
parents:
diff changeset
    69
7f561c08de6b Initial load
duke
parents:
diff changeset
    70
    //
7f561c08de6b Initial load
duke
parents:
diff changeset
    71
    // Constructors
7f561c08de6b Initial load
duke
parents:
diff changeset
    72
    //
7f561c08de6b Initial load
duke
parents:
diff changeset
    73
7f561c08de6b Initial load
duke
parents:
diff changeset
    74
    /** Constructs a grammar pool with a default number of buckets. */
7f561c08de6b Initial load
duke
parents:
diff changeset
    75
    public SoftReferenceGrammarPool() {
7f561c08de6b Initial load
duke
parents:
diff changeset
    76
        fGrammars = new Entry[TABLE_SIZE];
7f561c08de6b Initial load
duke
parents:
diff changeset
    77
        fPoolIsLocked = false;
7f561c08de6b Initial load
duke
parents:
diff changeset
    78
    } // <init>()
7f561c08de6b Initial load
duke
parents:
diff changeset
    79
7f561c08de6b Initial load
duke
parents:
diff changeset
    80
    /** Constructs a grammar pool with a specified number of buckets. */
7f561c08de6b Initial load
duke
parents:
diff changeset
    81
    public SoftReferenceGrammarPool(int initialCapacity) {
7f561c08de6b Initial load
duke
parents:
diff changeset
    82
        fGrammars = new Entry[initialCapacity];
7f561c08de6b Initial load
duke
parents:
diff changeset
    83
        fPoolIsLocked = false;
7f561c08de6b Initial load
duke
parents:
diff changeset
    84
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
    85
7f561c08de6b Initial load
duke
parents:
diff changeset
    86
    //
7f561c08de6b Initial load
duke
parents:
diff changeset
    87
    // XMLGrammarPool methods
7f561c08de6b Initial load
duke
parents:
diff changeset
    88
    //
7f561c08de6b Initial load
duke
parents:
diff changeset
    89
7f561c08de6b Initial load
duke
parents:
diff changeset
    90
    /* <p> Retrieve the initial known set of grammars. This method is
7f561c08de6b Initial load
duke
parents:
diff changeset
    91
     * called by a validator before the validation starts. The application
7f561c08de6b Initial load
duke
parents:
diff changeset
    92
     * can provide an initial set of grammars available to the current
7f561c08de6b Initial load
duke
parents:
diff changeset
    93
     * validation attempt. </p>
7f561c08de6b Initial load
duke
parents:
diff changeset
    94
     *
7f561c08de6b Initial load
duke
parents:
diff changeset
    95
     * @param grammarType The type of the grammar, from the
7f561c08de6b Initial load
duke
parents:
diff changeset
    96
     *                    <code>com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription</code>
7f561c08de6b Initial load
duke
parents:
diff changeset
    97
     *                    interface.
7f561c08de6b Initial load
duke
parents:
diff changeset
    98
     * @return            The set of grammars the validator may put in its "bucket"
7f561c08de6b Initial load
duke
parents:
diff changeset
    99
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   100
    public Grammar [] retrieveInitialGrammarSet (String grammarType) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   101
        synchronized (fGrammars) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   102
            clean();
7f561c08de6b Initial load
duke
parents:
diff changeset
   103
            // Return no grammars. This allows the garbage collector to sift
7f561c08de6b Initial load
duke
parents:
diff changeset
   104
            // out grammars which are not in use when memory demand is high.
7f561c08de6b Initial load
duke
parents:
diff changeset
   105
            // It also allows the pool to return the "right" schema grammar
7f561c08de6b Initial load
duke
parents:
diff changeset
   106
            // based on schema locations.
7f561c08de6b Initial load
duke
parents:
diff changeset
   107
            return ZERO_LENGTH_GRAMMAR_ARRAY;
7f561c08de6b Initial load
duke
parents:
diff changeset
   108
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   109
    } // retrieveInitialGrammarSet (String): Grammar[]
7f561c08de6b Initial load
duke
parents:
diff changeset
   110
7f561c08de6b Initial load
duke
parents:
diff changeset
   111
    /* <p> Return the final set of grammars that the validator ended up
7f561c08de6b Initial load
duke
parents:
diff changeset
   112
     * with. This method is called after the validation finishes. The
7f561c08de6b Initial load
duke
parents:
diff changeset
   113
     * application may then choose to cache some of the returned grammars.</p>
7f561c08de6b Initial load
duke
parents:
diff changeset
   114
     * <p>In this implementation, we make our choice based on whether this object
7f561c08de6b Initial load
duke
parents:
diff changeset
   115
     * is "locked"--that is, whether the application has instructed
7f561c08de6b Initial load
duke
parents:
diff changeset
   116
     * us not to accept any new grammars.</p>
7f561c08de6b Initial load
duke
parents:
diff changeset
   117
     *
7f561c08de6b Initial load
duke
parents:
diff changeset
   118
     * @param grammarType The type of the grammars being returned;
7f561c08de6b Initial load
duke
parents:
diff changeset
   119
     * @param grammars    An array containing the set of grammars being
7f561c08de6b Initial load
duke
parents:
diff changeset
   120
     *                    returned; order is not significant.
7f561c08de6b Initial load
duke
parents:
diff changeset
   121
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   122
    public void cacheGrammars(String grammarType, Grammar[] grammars) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   123
        if (!fPoolIsLocked) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   124
            for (int i = 0; i < grammars.length; ++i) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   125
                putGrammar(grammars[i]);
7f561c08de6b Initial load
duke
parents:
diff changeset
   126
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   127
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   128
    } // cacheGrammars(String, Grammar[]);
7f561c08de6b Initial load
duke
parents:
diff changeset
   129
7f561c08de6b Initial load
duke
parents:
diff changeset
   130
    /* <p> This method requests that the application retrieve a grammar
7f561c08de6b Initial load
duke
parents:
diff changeset
   131
     * corresponding to the given GrammarIdentifier from its cache.
7f561c08de6b Initial load
duke
parents:
diff changeset
   132
     * If it cannot do so it must return null; the parser will then
7f561c08de6b Initial load
duke
parents:
diff changeset
   133
     * call the EntityResolver. </p>
7f561c08de6b Initial load
duke
parents:
diff changeset
   134
     * <strong>An application must not call its EntityResolver itself
7f561c08de6b Initial load
duke
parents:
diff changeset
   135
     * from this method; this may result in infinite recursions.</strong>
7f561c08de6b Initial load
duke
parents:
diff changeset
   136
     *
7f561c08de6b Initial load
duke
parents:
diff changeset
   137
     * This implementation chooses to use the root element name to identify a DTD grammar
7f561c08de6b Initial load
duke
parents:
diff changeset
   138
     * and the target namespace to identify a Schema grammar.
7f561c08de6b Initial load
duke
parents:
diff changeset
   139
     *
7f561c08de6b Initial load
duke
parents:
diff changeset
   140
     * @param desc The description of the Grammar being requested.
7f561c08de6b Initial load
duke
parents:
diff changeset
   141
     * @return     The Grammar corresponding to this description or null if
7f561c08de6b Initial load
duke
parents:
diff changeset
   142
     *             no such Grammar is known.
7f561c08de6b Initial load
duke
parents:
diff changeset
   143
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   144
    public Grammar retrieveGrammar(XMLGrammarDescription desc) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   145
        return getGrammar(desc);
7f561c08de6b Initial load
duke
parents:
diff changeset
   146
    } // retrieveGrammar(XMLGrammarDescription):  Grammar
7f561c08de6b Initial load
duke
parents:
diff changeset
   147
7f561c08de6b Initial load
duke
parents:
diff changeset
   148
    //
7f561c08de6b Initial load
duke
parents:
diff changeset
   149
    // Public methods
7f561c08de6b Initial load
duke
parents:
diff changeset
   150
    //
7f561c08de6b Initial load
duke
parents:
diff changeset
   151
7f561c08de6b Initial load
duke
parents:
diff changeset
   152
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   153
     * Puts the specified grammar into the grammar pool and associates it to
7f561c08de6b Initial load
duke
parents:
diff changeset
   154
     * its root element name or its target namespace.
7f561c08de6b Initial load
duke
parents:
diff changeset
   155
     *
7f561c08de6b Initial load
duke
parents:
diff changeset
   156
     * @param grammar The Grammar.
7f561c08de6b Initial load
duke
parents:
diff changeset
   157
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   158
    public void putGrammar(Grammar grammar) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   159
        if (!fPoolIsLocked) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   160
            synchronized (fGrammars) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   161
                clean();
7f561c08de6b Initial load
duke
parents:
diff changeset
   162
                XMLGrammarDescription desc = grammar.getGrammarDescription();
7f561c08de6b Initial load
duke
parents:
diff changeset
   163
                int hash = hashCode(desc);
7f561c08de6b Initial load
duke
parents:
diff changeset
   164
                int index = (hash & 0x7FFFFFFF) % fGrammars.length;
7f561c08de6b Initial load
duke
parents:
diff changeset
   165
                for (Entry entry = fGrammars[index]; entry != null; entry = entry.next) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   166
                    if (entry.hash == hash && equals(entry.desc, desc)) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   167
                        if (entry.grammar.get() != grammar) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   168
                            entry.grammar = new SoftGrammarReference(entry, grammar, fReferenceQueue);
7f561c08de6b Initial load
duke
parents:
diff changeset
   169
                        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   170
                        return;
7f561c08de6b Initial load
duke
parents:
diff changeset
   171
                    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   172
                }
7f561c08de6b Initial load
duke
parents:
diff changeset
   173
                // create a new entry
7f561c08de6b Initial load
duke
parents:
diff changeset
   174
                Entry entry = new Entry(hash, index, desc, grammar, fGrammars[index], fReferenceQueue);
7f561c08de6b Initial load
duke
parents:
diff changeset
   175
                fGrammars[index] = entry;
7f561c08de6b Initial load
duke
parents:
diff changeset
   176
                fGrammarCount++;
7f561c08de6b Initial load
duke
parents:
diff changeset
   177
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   178
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   179
    } // putGrammar(Grammar)
7f561c08de6b Initial load
duke
parents:
diff changeset
   180
7f561c08de6b Initial load
duke
parents:
diff changeset
   181
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   182
     * Returns the grammar associated to the specified grammar description.
7f561c08de6b Initial load
duke
parents:
diff changeset
   183
     * Currently, the root element name is used as the key for DTD grammars
7f561c08de6b Initial load
duke
parents:
diff changeset
   184
     * and the target namespace  is used as the key for Schema grammars.
7f561c08de6b Initial load
duke
parents:
diff changeset
   185
     *
7f561c08de6b Initial load
duke
parents:
diff changeset
   186
     * @param desc The Grammar Description.
7f561c08de6b Initial load
duke
parents:
diff changeset
   187
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   188
    public Grammar getGrammar(XMLGrammarDescription desc) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   189
        synchronized (fGrammars) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   190
            clean();
7f561c08de6b Initial load
duke
parents:
diff changeset
   191
            int hash = hashCode(desc);
7f561c08de6b Initial load
duke
parents:
diff changeset
   192
            int index = (hash & 0x7FFFFFFF) % fGrammars.length;
7f561c08de6b Initial load
duke
parents:
diff changeset
   193
            for (Entry entry = fGrammars[index]; entry != null; entry = entry.next) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   194
                Grammar tempGrammar = (Grammar) entry.grammar.get();
7f561c08de6b Initial load
duke
parents:
diff changeset
   195
                /** If the soft reference has been cleared, remove this entry from the pool. */
7f561c08de6b Initial load
duke
parents:
diff changeset
   196
                if (tempGrammar == null) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   197
                    removeEntry(entry);
7f561c08de6b Initial load
duke
parents:
diff changeset
   198
                }
7f561c08de6b Initial load
duke
parents:
diff changeset
   199
                else if ((entry.hash == hash) && equals(entry.desc, desc)) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   200
                    return tempGrammar;
7f561c08de6b Initial load
duke
parents:
diff changeset
   201
                }
7f561c08de6b Initial load
duke
parents:
diff changeset
   202
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   203
            return null;
7f561c08de6b Initial load
duke
parents:
diff changeset
   204
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   205
    } // getGrammar(XMLGrammarDescription):Grammar
7f561c08de6b Initial load
duke
parents:
diff changeset
   206
7f561c08de6b Initial load
duke
parents:
diff changeset
   207
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   208
     * Removes the grammar associated to the specified grammar description from the
7f561c08de6b Initial load
duke
parents:
diff changeset
   209
     * grammar pool and returns the removed grammar. Currently, the root element name
7f561c08de6b Initial load
duke
parents:
diff changeset
   210
     * is used as the key for DTD grammars and the target namespace  is used
7f561c08de6b Initial load
duke
parents:
diff changeset
   211
     * as the key for Schema grammars.
7f561c08de6b Initial load
duke
parents:
diff changeset
   212
     *
7f561c08de6b Initial load
duke
parents:
diff changeset
   213
     * @param desc The Grammar Description.
7f561c08de6b Initial load
duke
parents:
diff changeset
   214
     * @return     The removed grammar.
7f561c08de6b Initial load
duke
parents:
diff changeset
   215
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   216
    public Grammar removeGrammar(XMLGrammarDescription desc) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   217
        synchronized (fGrammars) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   218
            clean();
7f561c08de6b Initial load
duke
parents:
diff changeset
   219
            int hash = hashCode(desc);
7f561c08de6b Initial load
duke
parents:
diff changeset
   220
            int index = (hash & 0x7FFFFFFF) % fGrammars.length;
7f561c08de6b Initial load
duke
parents:
diff changeset
   221
            for (Entry entry = fGrammars[index]; entry != null; entry = entry.next) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   222
                if ((entry.hash == hash) && equals(entry.desc, desc)) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   223
                    return removeEntry(entry);
7f561c08de6b Initial load
duke
parents:
diff changeset
   224
                }
7f561c08de6b Initial load
duke
parents:
diff changeset
   225
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   226
            return null;
7f561c08de6b Initial load
duke
parents:
diff changeset
   227
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   228
    } // removeGrammar(XMLGrammarDescription):Grammar
7f561c08de6b Initial load
duke
parents:
diff changeset
   229
7f561c08de6b Initial load
duke
parents:
diff changeset
   230
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   231
     * Returns true if the grammar pool contains a grammar associated
7f561c08de6b Initial load
duke
parents:
diff changeset
   232
     * to the specified grammar description. Currently, the root element name
7f561c08de6b Initial load
duke
parents:
diff changeset
   233
     * is used as the key for DTD grammars and the target namespace  is used
7f561c08de6b Initial load
duke
parents:
diff changeset
   234
     * as the key for Schema grammars.
7f561c08de6b Initial load
duke
parents:
diff changeset
   235
     *
7f561c08de6b Initial load
duke
parents:
diff changeset
   236
     * @param desc The Grammar Description.
7f561c08de6b Initial load
duke
parents:
diff changeset
   237
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   238
    public boolean containsGrammar(XMLGrammarDescription desc) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   239
        synchronized (fGrammars) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   240
            clean();
7f561c08de6b Initial load
duke
parents:
diff changeset
   241
            int hash = hashCode(desc);
7f561c08de6b Initial load
duke
parents:
diff changeset
   242
            int index = (hash & 0x7FFFFFFF) % fGrammars.length;
7f561c08de6b Initial load
duke
parents:
diff changeset
   243
            for (Entry entry = fGrammars[index]; entry != null ; entry = entry.next) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   244
                Grammar tempGrammar = (Grammar) entry.grammar.get();
7f561c08de6b Initial load
duke
parents:
diff changeset
   245
                /** If the soft reference has been cleared, remove this entry from the pool. */
7f561c08de6b Initial load
duke
parents:
diff changeset
   246
                if (tempGrammar == null) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   247
                    removeEntry(entry);
7f561c08de6b Initial load
duke
parents:
diff changeset
   248
                }
7f561c08de6b Initial load
duke
parents:
diff changeset
   249
                else if ((entry.hash == hash) && equals(entry.desc, desc)) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   250
                    return true;
7f561c08de6b Initial load
duke
parents:
diff changeset
   251
                }
7f561c08de6b Initial load
duke
parents:
diff changeset
   252
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   253
            return false;
7f561c08de6b Initial load
duke
parents:
diff changeset
   254
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   255
    } // containsGrammar(XMLGrammarDescription):boolean
7f561c08de6b Initial load
duke
parents:
diff changeset
   256
7f561c08de6b Initial load
duke
parents:
diff changeset
   257
    /* <p> Sets this grammar pool to a "locked" state--i.e.,
7f561c08de6b Initial load
duke
parents:
diff changeset
   258
     * no new grammars will be added until it is "unlocked".
7f561c08de6b Initial load
duke
parents:
diff changeset
   259
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   260
    public void lockPool() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   261
        fPoolIsLocked = true;
7f561c08de6b Initial load
duke
parents:
diff changeset
   262
    } // lockPool()
7f561c08de6b Initial load
duke
parents:
diff changeset
   263
7f561c08de6b Initial load
duke
parents:
diff changeset
   264
    /* <p> Sets this grammar pool to an "unlocked" state--i.e.,
7f561c08de6b Initial load
duke
parents:
diff changeset
   265
     * new grammars will be added when putGrammar or cacheGrammars
7f561c08de6b Initial load
duke
parents:
diff changeset
   266
     * are called.
7f561c08de6b Initial load
duke
parents:
diff changeset
   267
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   268
    public void unlockPool() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   269
        fPoolIsLocked = false;
7f561c08de6b Initial load
duke
parents:
diff changeset
   270
    } // unlockPool()
7f561c08de6b Initial load
duke
parents:
diff changeset
   271
7f561c08de6b Initial load
duke
parents:
diff changeset
   272
    /*
7f561c08de6b Initial load
duke
parents:
diff changeset
   273
     * <p>This method clears the pool-i.e., removes references
7f561c08de6b Initial load
duke
parents:
diff changeset
   274
     * to all the grammars in it.</p>
7f561c08de6b Initial load
duke
parents:
diff changeset
   275
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   276
    public void clear() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   277
        for (int i=0; i<fGrammars.length; i++) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   278
            if(fGrammars[i] != null) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   279
                fGrammars[i].clear();
7f561c08de6b Initial load
duke
parents:
diff changeset
   280
                fGrammars[i] = null;
7f561c08de6b Initial load
duke
parents:
diff changeset
   281
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   282
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   283
        fGrammarCount = 0;
7f561c08de6b Initial load
duke
parents:
diff changeset
   284
    } // clear()
7f561c08de6b Initial load
duke
parents:
diff changeset
   285
7f561c08de6b Initial load
duke
parents:
diff changeset
   286
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   287
     * This method checks whether two grammars are the same. Currently, we compare
7f561c08de6b Initial load
duke
parents:
diff changeset
   288
     * the root element names for DTD grammars and the target namespaces for Schema grammars.
7f561c08de6b Initial load
duke
parents:
diff changeset
   289
     * The application can override this behaviour and add its own logic.
7f561c08de6b Initial load
duke
parents:
diff changeset
   290
     *
7f561c08de6b Initial load
duke
parents:
diff changeset
   291
     * @param desc1 The grammar description
7f561c08de6b Initial load
duke
parents:
diff changeset
   292
     * @param desc2 The grammar description of the grammar to be compared to
7f561c08de6b Initial load
duke
parents:
diff changeset
   293
     * @return      True if the grammars are equal, otherwise false
7f561c08de6b Initial load
duke
parents:
diff changeset
   294
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   295
    public boolean equals(XMLGrammarDescription desc1, XMLGrammarDescription desc2) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   296
        if (desc1 instanceof XMLSchemaDescription) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   297
            if (!(desc2 instanceof XMLSchemaDescription)) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   298
                return false;
7f561c08de6b Initial load
duke
parents:
diff changeset
   299
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   300
            final XMLSchemaDescription sd1 = (XMLSchemaDescription) desc1;
7f561c08de6b Initial load
duke
parents:
diff changeset
   301
            final XMLSchemaDescription sd2 = (XMLSchemaDescription) desc2;
7f561c08de6b Initial load
duke
parents:
diff changeset
   302
            final String targetNamespace = sd1.getTargetNamespace();
7f561c08de6b Initial load
duke
parents:
diff changeset
   303
            if (targetNamespace != null) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   304
                if (!targetNamespace.equals(sd2.getTargetNamespace())) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   305
                    return false;
7f561c08de6b Initial load
duke
parents:
diff changeset
   306
                }
7f561c08de6b Initial load
duke
parents:
diff changeset
   307
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   308
            else if (sd2.getTargetNamespace() != null) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   309
                return false;
7f561c08de6b Initial load
duke
parents:
diff changeset
   310
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   311
            // The JAXP 1.3 spec says that the implementation can assume that
7f561c08de6b Initial load
duke
parents:
diff changeset
   312
            // if two schema location hints are the same they always resolve
7f561c08de6b Initial load
duke
parents:
diff changeset
   313
            // to the same document. In the default grammar pool implementation
7f561c08de6b Initial load
duke
parents:
diff changeset
   314
            // we only look at the target namespaces. Here we also compare
7f561c08de6b Initial load
duke
parents:
diff changeset
   315
            // location hints.
7f561c08de6b Initial load
duke
parents:
diff changeset
   316
            final String expandedSystemId = sd1.getExpandedSystemId();
7f561c08de6b Initial load
duke
parents:
diff changeset
   317
            if (expandedSystemId != null) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   318
                if (!expandedSystemId.equals(sd2.getExpandedSystemId())) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   319
                    return false;
7f561c08de6b Initial load
duke
parents:
diff changeset
   320
                }
7f561c08de6b Initial load
duke
parents:
diff changeset
   321
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   322
            else if (sd2.getExpandedSystemId() != null) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   323
                return false;
7f561c08de6b Initial load
duke
parents:
diff changeset
   324
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   325
            return true;
7f561c08de6b Initial load
duke
parents:
diff changeset
   326
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   327
        return desc1.equals(desc2);
7f561c08de6b Initial load
duke
parents:
diff changeset
   328
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   329
7f561c08de6b Initial load
duke
parents:
diff changeset
   330
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   331
     * Returns the hash code value for the given grammar description.
7f561c08de6b Initial load
duke
parents:
diff changeset
   332
     *
7f561c08de6b Initial load
duke
parents:
diff changeset
   333
     * @param desc The grammar description
7f561c08de6b Initial load
duke
parents:
diff changeset
   334
     * @return     The hash code value
7f561c08de6b Initial load
duke
parents:
diff changeset
   335
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   336
    public int hashCode(XMLGrammarDescription desc) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   337
        if (desc instanceof XMLSchemaDescription) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   338
            final XMLSchemaDescription sd = (XMLSchemaDescription) desc;
7f561c08de6b Initial load
duke
parents:
diff changeset
   339
            final String targetNamespace = sd.getTargetNamespace();
7f561c08de6b Initial load
duke
parents:
diff changeset
   340
            final String expandedSystemId = sd.getExpandedSystemId();
7f561c08de6b Initial load
duke
parents:
diff changeset
   341
            int hash = (targetNamespace != null) ? targetNamespace.hashCode() : 0;
7f561c08de6b Initial load
duke
parents:
diff changeset
   342
            hash ^= (expandedSystemId != null) ? expandedSystemId.hashCode() : 0;
7f561c08de6b Initial load
duke
parents:
diff changeset
   343
            return hash;
7f561c08de6b Initial load
duke
parents:
diff changeset
   344
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   345
        return desc.hashCode();
7f561c08de6b Initial load
duke
parents:
diff changeset
   346
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   347
7f561c08de6b Initial load
duke
parents:
diff changeset
   348
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   349
     * Removes the given entry from the pool
7f561c08de6b Initial load
duke
parents:
diff changeset
   350
     *
7f561c08de6b Initial load
duke
parents:
diff changeset
   351
     * @param entry the entry to remove
7f561c08de6b Initial load
duke
parents:
diff changeset
   352
     * @return The grammar attached to this entry
7f561c08de6b Initial load
duke
parents:
diff changeset
   353
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   354
    private Grammar removeEntry(Entry entry) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   355
        if (entry.prev != null) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   356
            entry.prev.next = entry.next;
7f561c08de6b Initial load
duke
parents:
diff changeset
   357
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   358
        else {
7f561c08de6b Initial load
duke
parents:
diff changeset
   359
            fGrammars[entry.bucket] = entry.next;
7f561c08de6b Initial load
duke
parents:
diff changeset
   360
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   361
        if (entry.next != null) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   362
            entry.next.prev = entry.prev;
7f561c08de6b Initial load
duke
parents:
diff changeset
   363
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   364
        --fGrammarCount;
7f561c08de6b Initial load
duke
parents:
diff changeset
   365
        entry.grammar.entry = null;
7f561c08de6b Initial load
duke
parents:
diff changeset
   366
        return (Grammar) entry.grammar.get();
7f561c08de6b Initial load
duke
parents:
diff changeset
   367
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   368
7f561c08de6b Initial load
duke
parents:
diff changeset
   369
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   370
     * Removes stale entries from the pool.
7f561c08de6b Initial load
duke
parents:
diff changeset
   371
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   372
    private void clean() {
47359
e1a6c0168741 8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents: 47216
diff changeset
   373
        Reference<? extends Grammar> ref = fReferenceQueue.poll();
6
7f561c08de6b Initial load
duke
parents:
diff changeset
   374
        while (ref != null) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   375
            Entry entry = ((SoftGrammarReference) ref).entry;
7f561c08de6b Initial load
duke
parents:
diff changeset
   376
            if (entry != null) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   377
                removeEntry(entry);
7f561c08de6b Initial load
duke
parents:
diff changeset
   378
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   379
            ref = fReferenceQueue.poll();
7f561c08de6b Initial load
duke
parents:
diff changeset
   380
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   381
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   382
7f561c08de6b Initial load
duke
parents:
diff changeset
   383
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   384
     * This class is a grammar pool entry. Each entry acts as a node
7f561c08de6b Initial load
duke
parents:
diff changeset
   385
     * in a doubly linked list.
7f561c08de6b Initial load
duke
parents:
diff changeset
   386
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   387
    static final class Entry {
7f561c08de6b Initial load
duke
parents:
diff changeset
   388
7f561c08de6b Initial load
duke
parents:
diff changeset
   389
        public int hash;
7f561c08de6b Initial load
duke
parents:
diff changeset
   390
        public int bucket;
7f561c08de6b Initial load
duke
parents:
diff changeset
   391
        public Entry prev;
7f561c08de6b Initial load
duke
parents:
diff changeset
   392
        public Entry next;
7f561c08de6b Initial load
duke
parents:
diff changeset
   393
        public XMLGrammarDescription desc;
7f561c08de6b Initial load
duke
parents:
diff changeset
   394
        public SoftGrammarReference grammar;
7f561c08de6b Initial load
duke
parents:
diff changeset
   395
47359
e1a6c0168741 8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents: 47216
diff changeset
   396
        protected Entry(int hash, int bucket, XMLGrammarDescription desc, Grammar grammar,
e1a6c0168741 8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents: 47216
diff changeset
   397
                Entry next, ReferenceQueue<Grammar> queue) {
6
7f561c08de6b Initial load
duke
parents:
diff changeset
   398
            this.hash = hash;
7f561c08de6b Initial load
duke
parents:
diff changeset
   399
            this.bucket = bucket;
7f561c08de6b Initial load
duke
parents:
diff changeset
   400
            this.prev = null;
7f561c08de6b Initial load
duke
parents:
diff changeset
   401
            this.next = next;
7f561c08de6b Initial load
duke
parents:
diff changeset
   402
            if (next != null) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   403
                next.prev = this;
7f561c08de6b Initial load
duke
parents:
diff changeset
   404
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   405
            this.desc = desc;
7f561c08de6b Initial load
duke
parents:
diff changeset
   406
            this.grammar = new SoftGrammarReference(this, grammar, queue);
7f561c08de6b Initial load
duke
parents:
diff changeset
   407
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   408
7f561c08de6b Initial load
duke
parents:
diff changeset
   409
        // clear this entry; useful to promote garbage collection
7f561c08de6b Initial load
duke
parents:
diff changeset
   410
        // since reduces reference count of objects to be destroyed
7f561c08de6b Initial load
duke
parents:
diff changeset
   411
        protected void clear () {
7f561c08de6b Initial load
duke
parents:
diff changeset
   412
            desc = null;
7f561c08de6b Initial load
duke
parents:
diff changeset
   413
            grammar = null;
7f561c08de6b Initial load
duke
parents:
diff changeset
   414
            if(next != null) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   415
                next.clear();
7f561c08de6b Initial load
duke
parents:
diff changeset
   416
                next = null;
7f561c08de6b Initial load
duke
parents:
diff changeset
   417
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   418
        } // clear()
7f561c08de6b Initial load
duke
parents:
diff changeset
   419
7f561c08de6b Initial load
duke
parents:
diff changeset
   420
    } // class Entry
7f561c08de6b Initial load
duke
parents:
diff changeset
   421
7f561c08de6b Initial load
duke
parents:
diff changeset
   422
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   423
     * This class stores a soft reference to a grammar object. It keeps a reference
7f561c08de6b Initial load
duke
parents:
diff changeset
   424
     * to its associated entry, so that it can be easily removed from the pool.
7f561c08de6b Initial load
duke
parents:
diff changeset
   425
     */
47359
e1a6c0168741 8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents: 47216
diff changeset
   426
    static final class SoftGrammarReference extends SoftReference<Grammar> {
6
7f561c08de6b Initial load
duke
parents:
diff changeset
   427
7f561c08de6b Initial load
duke
parents:
diff changeset
   428
        public Entry entry;
7f561c08de6b Initial load
duke
parents:
diff changeset
   429
47359
e1a6c0168741 8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents: 47216
diff changeset
   430
        protected SoftGrammarReference(Entry entry, Grammar grammar, ReferenceQueue<Grammar> queue) {
6
7f561c08de6b Initial load
duke
parents:
diff changeset
   431
            super(grammar, queue);
7f561c08de6b Initial load
duke
parents:
diff changeset
   432
            this.entry = entry;
7f561c08de6b Initial load
duke
parents:
diff changeset
   433
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   434
7f561c08de6b Initial load
duke
parents:
diff changeset
   435
    } // class SoftGrammarReference
7f561c08de6b Initial load
duke
parents:
diff changeset
   436
7f561c08de6b Initial load
duke
parents:
diff changeset
   437
} // class SoftReferenceGrammarPool