- /*
- * The Apache Software License, Version 1.1
- *
- *
- * Copyright (c) 1999-2002 The Apache Software Foundation. All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- * if any, must include the following acknowledgment:
- * "This product includes software developed by the
- * Apache Software Foundation (http://www.apache.org/)."
- * Alternately, this acknowledgment may appear in the software itself,
- * if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Xerces" and "Apache Software Foundation" must
- * not be used to endorse or promote products derived from this
- * software without prior written permission. For written
- * permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- * nor may "Apache" appear in their name, without prior written
- * permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation and was
- * originally based on software copyright (c) 1999, International
- * Business Machines, Inc., http://www.apache.org. For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
- package com.sun.org.apache.xerces.internal.util;
-
- import com.sun.org.apache.xerces.internal.xni.grammars.Grammar;
- import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription;
- import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
-
- /**
- * Stores grammars in a pool associated to a specific key. This grammar pool
- * implementation stores two types of grammars: those keyed by the root element
- * name, and those keyed by the grammar's target namespace.
- *
- * This is the default implementation of the GrammarPool interface.
- * As we move forward, this will become more function-rich and robust.
- *
- * @author Jeffrey Rodriguez, IBM
- * @author Andy Clark, IBM
- * @author Neil Graham, IBM
- * @author Pavani Mukthipudi, Sun Microsystems
- * @author Neeraj Bajaj, SUN Microsystems
- *
- * @version $Id: XMLGrammarPoolImpl.java,v 1.6 2003/07/30 21:30:04 elena Exp $
- */
- public class XMLGrammarPoolImpl implements XMLGrammarPool {
-
- //
- // Constants
- //
-
- /** Default size. */
- protected static final int TABLE_SIZE = 11;
-
- //
- // Data
- //
-
- /** Grammars. */
- protected Entry[] fGrammars = null;
-
- // whether this pool is locked
- protected boolean fPoolIsLocked;
-
- // the number of grammars in the pool
- protected int fGrammarCount = 0;
-
- private static final boolean DEBUG = false ;
-
- //
- // Constructors
- //
-
- /** Constructs a grammar pool with a default number of buckets. */
- public XMLGrammarPoolImpl() {
- fGrammars = new Entry[TABLE_SIZE];
- fPoolIsLocked = false;
- } // <init>()
-
- /** Constructs a grammar pool with a specified number of buckets. */
- public XMLGrammarPoolImpl(int initialCapacity) {
- fGrammars = new Entry[initialCapacity];
- fPoolIsLocked = false;
- }
-
- //
- // XMLGrammarPool methods
- //
-
- /* <p> Retrieve the initial known set of grammars. This method is
- * called by a validator before the validation starts. The application
- * can provide an initial set of grammars available to the current
- * validation attempt. </p>
- *
- * @param grammarType The type of the grammar, from the
- * <code>com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription</code>
- * interface.
- * @return The set of grammars the validator may put in its "bucket"
- */
- public Grammar [] retrieveInitialGrammarSet (String grammarType) {
- synchronized (fGrammars) {
- int grammarSize = fGrammars.length ;
- Grammar [] tempGrammars = new Grammar[fGrammarCount];
- int pos = 0;
- for (int i = 0; i < grammarSize; i++) {
- for (Entry e = fGrammars[i]; e != null; e = e.next) {
- if (e.desc.getGrammarType().equals(grammarType)) {
- tempGrammars[pos++] = e.grammar;
- }
- }
- }
- Grammar[] toReturn = new Grammar[pos];
- System.arraycopy(tempGrammars, 0, toReturn, 0, pos);
- return toReturn;
- }
- } // retrieveInitialGrammarSet (String): Grammar[]
-
- /* <p> Return the final set of grammars that the validator ended up
- * with. This method is called after the validation finishes. The
- * application may then choose to cache some of the returned grammars.</p>
- * <p>In this implementation, we make our choice based on whether this object
- * is "locked"--that is, whether the application has instructed
- * us not to accept any new grammars.</p>
- *
- * @param grammarType The type of the grammars being returned;
- * @param grammars An array containing the set of grammars being
- * returned; order is not significant.
- */
- public void cacheGrammars(String grammarType, Grammar[] grammars) {
- if(!fPoolIsLocked) {
- for (int i = 0; i < grammars.length; i++) {
- if(DEBUG) {
- System.out.println("CACHED GRAMMAR " + (i+1) ) ;
- Grammar temp = grammars[i] ;
- //print(temp.getGrammarDescription());
- }
- putGrammar(grammars[i]);
- }
- }
- } // cacheGrammars(String, Grammar[]);
-
- /* <p> This method requests that the application retrieve a grammar
- * corresponding to the given GrammarIdentifier from its cache.
- * If it cannot do so it must return null; the parser will then
- * call the EntityResolver. </p>
- * <strong>An application must not call its EntityResolver itself
- * from this method; this may result in infinite recursions.</strong>
- *
- * This implementation chooses to use the root element name to identify a DTD grammar
- * and the target namespace to identify a Schema grammar.
- *
- * @param desc The description of the Grammar being requested.
- * @return The Grammar corresponding to this description or null if
- * no such Grammar is known.
- */
- public Grammar retrieveGrammar(XMLGrammarDescription desc) {
- if(DEBUG){
- System.out.println("RETRIEVING GRAMMAR FROM THE APPLICATION WITH FOLLOWING DESCRIPTION :");
- //print(desc);
- }
- return getGrammar(desc);
- } // retrieveGrammar(XMLGrammarDescription): Grammar
-
- //
- // Public methods
- //
-
- /**
- * Puts the specified grammar into the grammar pool and associates it to
- * its root element name or its target namespace.
- *
- * @param grammar The Grammar.
- */
- public void putGrammar(Grammar grammar) {
- if(!fPoolIsLocked) {
- synchronized (fGrammars) {
- XMLGrammarDescription desc = grammar.getGrammarDescription();
- int hash = hashCode(desc);
- int index = (hash & 0x7FFFFFFF) % fGrammars.length;
- for (Entry entry = fGrammars[index]; entry != null; entry = entry.next) {
- if (entry.hash == hash && equals(entry.desc, desc)) {
- entry.grammar = grammar;
- return;
- }
- }
- // create a new entry
- Entry entry = new Entry(hash, desc, grammar, fGrammars[index]);
- fGrammars[index] = entry;
- fGrammarCount++;
- }
- }
- } // putGrammar(Grammar)
-
- /**
- * Returns the 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 Grammar getGrammar(XMLGrammarDescription desc) {
- synchronized (fGrammars) {
- int hash = hashCode(desc);
- int index = (hash & 0x7FFFFFFF) % fGrammars.length;
- for (Entry entry = fGrammars[index] ; entry != null ; entry = entry.next) {
- if ((entry.hash == hash) && equals(entry.desc, desc)) {
- return entry.grammar;
- }
- }
- return null;
- }
- } // getGrammar(XMLGrammarDescription):Grammar
-
- /**
- * Removes the grammar associated to the specified grammar description from the
- * grammar pool and returns the removed grammar. 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.
- * @return The removed grammar.
- */
- public Grammar removeGrammar(XMLGrammarDescription desc) {
- synchronized (fGrammars) {
- int hash = hashCode(desc);
- int index = (hash & 0x7FFFFFFF) % fGrammars.length;
- for (Entry entry = fGrammars[index], prev = null ; entry != null ; prev = entry, entry = entry.next) {
- if ((entry.hash == hash) && equals(entry.desc, desc)) {
- if (prev != null) {
- prev.next = entry.next;
- }
- else {
- fGrammars[index] = entry.next;
- }
- Grammar tempGrammar = entry.grammar;
- entry.grammar = null;
- fGrammarCount--;
- return tempGrammar;
- }
- }
- 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) {
- int hash = hashCode(desc);
- int index = (hash & 0x7FFFFFFF) % fGrammars.length;
- for (Entry entry = fGrammars[index] ; entry != null ; entry = entry.next) {
- 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 gDesc1 The grammar description
- * @param gDesc2 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) {
- 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) {
- return desc.hashCode();
- }
-
- /**
- * This class is a grammar pool entry. Each entry acts as a node
- * in a linked list.
- */
- protected static final class Entry {
- public int hash;
- public XMLGrammarDescription desc;
- public Grammar grammar;
- public Entry next;
-
- protected Entry(int hash, XMLGrammarDescription desc, Grammar grammar, Entry next) {
- this.hash = hash;
- this.desc = desc;
- this.grammar = grammar;
- this.next = next;
- }
-
- // 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
-
- /* For DTD build we can't import here XSDDescription. Thus, this method is commented out.. */
- /* public void print(XMLGrammarDescription description){
- if(description.getGrammarType().equals(XMLGrammarDescription.XML_DTD)){
-
- }
- else if(description.getGrammarType().equals(XMLGrammarDescription.XML_SCHEMA)){
- XSDDescription schema = (XSDDescription)description ;
- System.out.println("Context = " + schema.getContextType());
- System.out.println("TargetNamespace = " + schema.getTargetNamespace());
- String [] temp = schema.getLocationHints();
-
- for (int i = 0 ; (temp != null && i < temp.length) ; i++){
- System.out.println("LocationHint " + i + " = "+ temp[i]);
- }
-
- System.out.println("Triggering Component = " + schema.getTriggeringComponent());
- System.out.println("EnclosingElementName =" + schema.getEnclosingElementName());
-
- }
-
- }//print
- */
-
- } // class XMLGrammarPoolImpl