softreferencegrammarpool.java

来自「JAVA 所有包」· Java 代码 · 共 433 行 · 第 1/2 页

JAVA
433
字号
                if ((entry.hash == hash) && equals(entry.desc, desc)) {                    return removeEntry(entry);                }            }            return null;        }    } // removeGrammar(XMLGrammarDescription):Grammar        /**     * Returns true if the grammar pool contains a grammar associated     * to the specified grammar description. Currently, the root element name     * is used as the key for DTD grammars and the target namespace  is used     * as the key for Schema grammars.     *     * @param desc The Grammar Description.     */    public boolean containsGrammar(XMLGrammarDescription desc) {        synchronized (fGrammars) {            clean();            int hash = hashCode(desc);            int index = (hash & 0x7FFFFFFF) % fGrammars.length;            for (Entry entry = fGrammars[index]; entry != null ; entry = entry.next) {                Grammar tempGrammar = (Grammar) entry.grammar.get();                /** If the soft reference has been cleared, remove this entry from the pool. */                if (tempGrammar == null) {                    removeEntry(entry);                }                else if ((entry.hash == hash) && equals(entry.desc, desc)) {                    return true;                }            }            return false;        }    } // containsGrammar(XMLGrammarDescription):boolean        /* <p> Sets this grammar pool to a "locked" state--i.e.,     * no new grammars will be added until it is "unlocked".     */    public void lockPool() {        fPoolIsLocked = true;    } // lockPool()        /* <p> Sets this grammar pool to an "unlocked" state--i.e.,     * new grammars will be added when putGrammar or cacheGrammars     * are called.     */    public void unlockPool() {        fPoolIsLocked = false;    } // unlockPool()        /*     * <p>This method clears the pool-i.e., removes references     * to all the grammars in it.</p>     */    public void clear() {        for (int i=0; i<fGrammars.length; i++) {            if(fGrammars[i] != null) {                fGrammars[i].clear();                fGrammars[i] = null;            }        }        fGrammarCount = 0;    } // clear()        /**     * This method checks whether two grammars are the same. Currently, we compare     * the root element names for DTD grammars and the target namespaces for Schema grammars.     * The application can override this behaviour and add its own logic.     *     * @param desc1 The grammar description     * @param desc2 The grammar description of the grammar to be compared to     * @return      True if the grammars are equal, otherwise false     */    public boolean equals(XMLGrammarDescription desc1, XMLGrammarDescription desc2) {        if (desc1 instanceof XMLSchemaDescription) {            if (!(desc2 instanceof XMLSchemaDescription)) {                return false;            }            final XMLSchemaDescription sd1 = (XMLSchemaDescription) desc1;            final XMLSchemaDescription sd2 = (XMLSchemaDescription) desc2;            final String targetNamespace = sd1.getTargetNamespace();            if (targetNamespace != null) {                if (!targetNamespace.equals(sd2.getTargetNamespace())) {                    return false;                }            }            else if (sd2.getTargetNamespace() != null) {                return false;            }            // The JAXP 1.3 spec says that the implementation can assume that            // if two schema location hints are the same they always resolve            // to the same document. In the default grammar pool implementation            // we only look at the target namespaces. Here we also compare            // location hints.            final String expandedSystemId = sd1.getExpandedSystemId();            if (expandedSystemId != null) {                if (!expandedSystemId.equals(sd2.getExpandedSystemId())) {                    return false;                }            }            else if (sd2.getExpandedSystemId() != null) {                return false;            }            return true;        }        return desc1.equals(desc2);    }        /**     * Returns the hash code value for the given grammar description.     *     * @param desc The grammar description     * @return     The hash code value     */    public int hashCode(XMLGrammarDescription desc) {        if (desc instanceof XMLSchemaDescription) {            final XMLSchemaDescription sd = (XMLSchemaDescription) desc;            final String targetNamespace = sd.getTargetNamespace();            final String expandedSystemId = sd.getExpandedSystemId();            int hash = (targetNamespace != null) ? targetNamespace.hashCode() : 0;            hash ^= (expandedSystemId != null) ? expandedSystemId.hashCode() : 0;            return hash;             }        return desc.hashCode();    }        /**     * Removes the given entry from the pool     *      * @param entry the entry to remove     * @return The grammar attached to this entry     */    private Grammar removeEntry(Entry entry) {        if (entry.prev != null) {            entry.prev.next = entry.next;        }        else {            fGrammars[entry.bucket] = entry.next;        }        if (entry.next != null) {            entry.next.prev = entry.prev;        }        --fGrammarCount;        entry.grammar.entry = null;        return (Grammar) entry.grammar.get();    }        /**     * Removes stale entries from the pool.     */    private void clean() {        Reference ref = fReferenceQueue.poll();        while (ref != null) {            Entry entry = ((SoftGrammarReference) ref).entry;            if (entry != null) {                removeEntry(entry);            }            ref = fReferenceQueue.poll();        }    }        /**     * This class is a grammar pool entry. Each entry acts as a node     * in a doubly linked list.     */    static final class Entry {        public int hash;        public int bucket;        public Entry prev;        public Entry next;        public XMLGrammarDescription desc;        public SoftGrammarReference grammar;                        protected Entry(int hash, int bucket, XMLGrammarDescription desc, Grammar grammar, Entry next, ReferenceQueue queue) {            this.hash = hash;            this.bucket = bucket;            this.prev = null;            this.next = next;            if (next != null) {                next.prev = this;            }            this.desc = desc;            this.grammar = new SoftGrammarReference(this, grammar, queue);        }                // clear this entry; useful to promote garbage collection        // since reduces reference count of objects to be destroyed        protected void clear () {            desc = null;            grammar = null;            if(next != null) {                next.clear();                next = null;            }        } // clear()            } // class Entry        /**     * This class stores a soft reference to a grammar object. It keeps a reference     * to its associated entry, so that it can be easily removed from the pool.     */    static final class SoftGrammarReference extends SoftReference {        public Entry entry;                protected SoftGrammarReference(Entry entry, Grammar grammar, ReferenceQueue queue) {            super(grammar, queue);            this.entry = entry;        }            } // class SoftGrammarReference    } // class SoftReferenceGrammarPool

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?