You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by ne...@apache.org on 2002/02/19 22:03:39 UTC

cvs commit: xml-xerces/java/src/org/apache/xerces/parsers CachingParserPool.java DOMASBuilderImpl.java StandardParserConfiguration.java XMLGrammarCachingConfiguration.java

neeraj      02/02/19 13:03:39

  Modified:    java/src/org/apache/xerces/impl/validation
                        XMLGrammarPoolImpl.java
               java/src/org/apache/xerces/impl/xs XMLSchemaValidator.java
                        XSDDescription.java
               java/src/org/apache/xerces/impl/xs/traversers
                        XSDHandler.java
               java/src/org/apache/xerces/parsers CachingParserPool.java
                        DOMASBuilderImpl.java
                        StandardParserConfiguration.java
                        XMLGrammarCachingConfiguration.java
  Log:
  Adding default grammar caching implementation support. If grammar is not
  available with the parser, validator component gives a chance to the
  application
  1. to supply initial set of grammars to begin parsing with.
  2. to supply the required grammar as per description.
  3. to cache different grammars, validator component ended up with after current
  validation attempt. Application can provide these cached grammar, available
  to the parser before the next validation attempt.
  
  	Current changes include schema validator and related components. Loading
  of the schema grammar is deferred until there is actual reference to a component from
  that namespace. Default implementation caches the Schema Grammar using namespace
  as key. Application can always *over-ride* this behavior by providing its own
  version of XMLGrammarPool impl or extending default XMLGrammarPoolImpl and can
  choose to cache/supply Schema Grammars based on namespace & triggering component
  or namespace & context etc.. or other information available through XSDDescription.
  	Next set of changes (DTDValidator) need to be done for caching of DTD grammars.
  Default implementaion will cache the DTD grammar as per the root element..
  which can always be over-ridden by the application :-)
  
  Thanks to pavani for her part of changes. Pavani, i have integrated my changes
  with yours.
  
  Revision  Changes    Path
  1.3       +248 -98   xml-xerces/java/src/org/apache/xerces/impl/validation/XMLGrammarPoolImpl.java
  
  Index: XMLGrammarPoolImpl.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/validation/XMLGrammarPoolImpl.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- XMLGrammarPoolImpl.java	28 Jan 2002 19:33:35 -0000	1.2
  +++ XMLGrammarPoolImpl.java	19 Feb 2002 21:03:38 -0000	1.3
  @@ -61,6 +61,9 @@
   import org.apache.xerces.xni.grammars.XMLGrammarPool;
   import org.apache.xerces.xni.grammars.XMLGrammarDescription;
   
  +import org.apache.xerces.impl.dtd.XMLDTDDescription;
  +import org.apache.xerces.impl.xs.XSDDescription;
  +
   import java.util.Hashtable;
   import java.util.Enumeration;
   
  @@ -69,15 +72,16 @@
    * implementation stores two types of grammars: those keyed by the root element
    * name, and those keyed by the grammar's target namespace.
    *
  - * This is for now, a very simple default implementation of the GrammarPool
  - * interface.  As we move forward, this will become more function-rich and
  - * robust.
  + * 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.2 2002/01/28 19:33:35 lehors Exp $
  + * @version $Id: XMLGrammarPoolImpl.java,v 1.3 2002/02/19 21:03:38 neeraj Exp $
    */
   public class XMLGrammarPoolImpl implements XMLGrammarPool {
   
  @@ -86,12 +90,17 @@
       //
   
       /** Grammars associated with element root name. */
  -    protected Hashtable fGrammars = new Hashtable();
  +    // REVISIT : Do we want to use Internal subset also to identify DTD grammars ?
  +    protected Hashtable fDTDGrammars = new Hashtable();
   
       /** Grammars associated with namespaces. */
  -    protected Hashtable fGrammarsNS = new Hashtable();
  -    protected Grammar fNoNSGrammar = null;
  +    // REVISIT : Do we want to use some other information available with the XSDDescription 
  +    //		 along with the namespace to identify Schema grammars ? 
  +    protected Hashtable fSchemaGrammars = new Hashtable();
  +    protected Grammar fNoNSSchemaGrammar = null;
   
  +	private static final boolean DEBUG = true ;
  +	
       //
       // Constructors
       //
  @@ -100,144 +109,285 @@
       public XMLGrammarPoolImpl() {
       } // <init>()
   
  +    //
       // XMLGrammarPool methods
  -    // REVISIT:  implement these!
  +    //
  +    
  +    /* <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>org.apache.xerces.xni.grammars.XMLGrammarDescription</code> 
  +     *  		  interface.
  +     * @return 		  The set of grammars the validator may put in its "bucket"
  +     */
       public Grammar [] retrieveInitialGrammarSet (String grammarType) {
  +
  +       	if (grammarType.equals(XMLGrammarDescription.XML_DTD)) {
  +    	    return getDTDGrammars();
  +        }
  +        else if (grammarType.equals(XMLGrammarDescription.XML_SCHEMA)) {
  +    	    return getSchemaGrammars();
  +        }
           return null;
       } // 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>
  +     *
  +     * @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) {
  +    	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) {
  -        return null;
  -    } // retrieveGrammar(Grammar):  XMLGrammarDescription
  +        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 associate it to
  -     * a root element name.
  -     * 
  -     * @param rootElement Root element name.
  -     * @param grammar     The grammar.
  -     */
  -    public void putGrammar(String rootElement, Grammar grammar) {
  -        fGrammars.put(rootElement, grammar);
  -    } // putGrammar(String,Grammar)
  -
  -    /**
  -     * Puts the specified grammar into the grammar pool and associate it to
  -     * a target namespace.
  +     * Puts the specified grammar into the grammar pool and associates it to
  +     * its root element name or its target namespace.
        *
  -     * @param namespace The grammar namespace.
  -     * @param grammar   The grammar.
  +     * @param grammar The Grammar.
        */
  -    public void putGrammarNS(String namespace, Grammar grammar) {
  -        if(namespace != null) {
  -            fGrammarsNS.put(namespace, grammar);
  -        } else {
  -            fNoNSGrammar = grammar;
  +    public void putGrammar(Grammar grammar) {
  +    	if (grammar.getGrammarDescription().getGrammarType().equals(XMLGrammarDescription.XML_DTD)) {
  +            fDTDGrammars.put(((XMLDTDDescription)grammar.getGrammarDescription()).getRootName(), grammar);
           }
  -    } // putGrammarNS(String,Grammar)
  -
  -    /**
  -     * Returns the grammar associated to the specified root element name.
  -     * 
  -     * @param rootElement Root element name.
  -     */
  -    public Grammar getGrammar(String rootElement) {
  -        return (Grammar)fGrammars.get(rootElement);
  -    } // getGrammar(String):Grammar
  -
  -    /**
  -     * Returns the grammar associated to the specified target namespace.
  -     * 
  -     * @param namespace Target namespace.
  -     */
  -    public Grammar getGrammarNS(String namespace) {
  -        return ((namespace == null)?
  -            fNoNSGrammar :
  -            (Grammar)fGrammarsNS.get(namespace));
  -    } // getGrammarNS(String):Grammar
  +        else if (grammar.getGrammarDescription().getGrammarType().equals(XMLGrammarDescription.XML_SCHEMA)) {
  +            String namespace = ((XSDDescription)grammar.getGrammarDescription()).getTargetNamespace();
  +	    if (namespace != null) {
  +    	    	fSchemaGrammars.put(namespace, grammar);
  +	    }
  +	    else {
  +	    	fNoNSSchemaGrammar = grammar;
  +	    }
  +        }
  +    } // putGrammar(Grammar)
   
       /**
  -     * Removes the grammar associated to the specified root elememt name from the
  -     * grammar pool and returns the removed grammar.
  -     * 
  -     * @param rootElement Root element name.
  +     * 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 removeGrammar(String rootElement) {
  -        if (fGrammars.contains(rootElement)) {
  -            return (Grammar)fGrammars.remove(rootElement);
  +    public Grammar getGrammar(XMLGrammarDescription desc) {
  +    	if (desc.getGrammarType().equals(XMLGrammarDescription.XML_DTD)) {
  +            Grammar grammar = (Grammar)fDTDGrammars.get(((XMLDTDDescription)desc).getRootName());
  +            
  +	    // REVISIT : As of right now, calling equals(...) doesn't serve much of the purpose. It's a double check.
  +	    //		 Probably it will be useful if the way two grammars are compared in equals(...) is changed.
  +	    if (grammar != null && equals(grammar.getGrammarDescription(), desc)) {
  +            	return grammar;
  +            }
  +        }
  +        else if (desc.getGrammarType().equals(XMLGrammarDescription.XML_SCHEMA)) {
  +            String namespace = ((XSDDescription)desc).getTargetNamespace();
  +            Grammar grammar = ((namespace == null)? fNoNSSchemaGrammar : (Grammar)fSchemaGrammars.get(namespace));
  +            
  +            if (grammar != null && equals(grammar.getGrammarDescription(), desc)) {
  +            	return grammar;
  +            }
           }
           return null;
  -    } // removeGrammar(String):Grammar
  +    } // getGrammar(XMLGrammarDescription):Grammar
   
       /**
  -     * Removes the grammar associated to the specified namespace from the
  -     * grammar pool and returns the removed 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 namespace Target namespace.
  +     * @param desc The Grammar Description.
  +     * @return     The removed grammar.
        */
  -    public Grammar removeGrammarNS(String namespace) {
  -        if(namespace == null) {
  -            Grammar tempGrammar = fNoNSGrammar;
  -            fNoNSGrammar = null;
  -            return tempGrammar;
  -        } else if (fGrammarsNS.contains(namespace)) {
  -            return (Grammar)fGrammarsNS.remove(namespace);
  -        }
  -        return null;
  -    } // removeGrammarNS(String):Grammar
  +    public Grammar removeGrammar(XMLGrammarDescription desc) {
  +    	if (containsGrammar(desc)) {
  +    	    if (desc.getGrammarType().equals(XMLGrammarDescription.XML_DTD)) {
  +    	    	return (Grammar)fDTDGrammars.remove(((XMLDTDDescription)desc).getRootName());
  +	    }
  +	    else if (desc.getGrammarType().equals(XMLGrammarDescription.XML_SCHEMA)) {
  +	    	String namespace = ((XSDDescription)desc).getTargetNamespace();
  +	    	if (namespace == null) {
  +            	   Grammar tempGrammar = fNoNSSchemaGrammar;
  +            	   fNoNSSchemaGrammar = null;
  +            	   return tempGrammar;
  +            	} 
  +            	else {
  +            	   return (Grammar)fSchemaGrammars.remove(namespace);
  +            	}
  +	    }
  +    	}
  +    	return null;
  +    } // removeGrammar(XMLGrammarDescription):Grammar
   
       /**
        * Returns true if the grammar pool contains a grammar associated
  -     * to the specified root element name.
  +     * 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 rootElement Root element name.
  +     * @param desc The Grammar Description.
        */
  -    public boolean containsGrammar(String rootElement) {
  -        return fGrammars.containsKey(rootElement);
  -    } // containsGrammar(String):boolean
  +    public boolean containsGrammar(XMLGrammarDescription desc) {
  +    	if (desc.getGrammarType().equals(XMLGrammarDescription.XML_DTD)) {
  +            Grammar grammar = (Grammar)fDTDGrammars.get(((XMLDTDDescription)desc).getRootName());
  +            if (grammar != null && equals(grammar.getGrammarDescription(), desc)) {
  +            	return true;
  +            }
  +        }
  +        else if (desc.getGrammarType().equals(XMLGrammarDescription.XML_SCHEMA)) {
  +            String namespace = ((XSDDescription)desc).getTargetNamespace();
  +            Grammar grammar = ((namespace == null)? fNoNSSchemaGrammar : (Grammar)fSchemaGrammars.get(namespace));
  +            if (grammar != null && equals(grammar.getGrammarDescription(), desc)) {
  +            	return true;
  +            }
  +        }
  +    	return false;
  +    } // containsGrammar(XMLGrammarDescription):boolean
   
       /**
  -     * Returns true if the grammar pool contains a grammar associated
  -     * to the specified target namespace.
  -     *
  -     * @param namespace Target namespace.
  +     * Returns all the DTD grammars.
  +     * 
  +     * @return The set of DTD grammars in the pool
        */
  -    public boolean containsGrammarNS(String namespace) {
  -        return fGrammarsNS.containsKey(namespace);
  -    } // containsGrammarNS(String):boolean
  -
  -    public Grammar [] getGrammars() {
  -        int grammarSize = fGrammars.size() ;
  +    public Grammar [] getDTDGrammars() {
  +        int grammarSize = fDTDGrammars.size() ;
           Grammar [] toReturn = new Grammar[grammarSize];
           int pos = 0;
  -        Enumeration grammars = fGrammars.elements();
  +        Enumeration grammars = fDTDGrammars.elements();
           while (grammars.hasMoreElements()) {
               toReturn[pos++] = (Grammar)grammars.nextElement();
           }
           return toReturn;
  -    } // getGrammars()
  +    } // getDTDGrammars()
   
       /**
  -     * Returns all grammars associated with namespaces.
  +     * Returns all the Schema grammars.
        * 
  +     * @return The set of Schema grammars in the pool
        */
  -    public Grammar [] getGrammarsNS() {
  -        int grammarSize = fGrammarsNS.size() + ((fNoNSGrammar == null) ? 0 : 1);
  +    public Grammar [] getSchemaGrammars() {
  +        int grammarSize = fSchemaGrammars.size() + ((fNoNSSchemaGrammar == null) ? 0 : 1);
           Grammar [] toReturn = new Grammar[grammarSize];
           int pos = 0;
  -        Enumeration grammarsNS = fGrammarsNS.elements();
  +        Enumeration grammarsNS = fSchemaGrammars.elements();
           while (grammarsNS.hasMoreElements()) {
               toReturn[pos++] = (Grammar)grammarsNS.nextElement();
  +            if(DEBUG){
  +            	System.out.println("RETRIEVING INITIAL GRAMMAR " + pos  ) ;
  +            	Grammar temp = toReturn[pos - 1] ;
  +            	print(temp.getGrammarDescription());
  +            }
  +        }
  +        if(pos < grammarSize){ 
  +            toReturn[pos++] = fNoNSSchemaGrammar;
  +            if(DEBUG){
  +            	System.out.println("RETRIEVING INITIAL GRAMMAR " + pos  ) ;
  +            	Grammar temp = toReturn[pos - 1] ;
  +            	print(temp.getGrammarDescription());
  +            }
  +            
           }
  -        if(pos < grammarSize) 
  -            toReturn[pos++] = fNoNSGrammar;
           return toReturn; 
  -    } // getGrammarsNS()
  -} // class GrammarPool
  +    } // getSchemaGrammars()
  +    
  +    /**
  +     * 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 gDesc1, XMLGrammarDescription gDesc2) {
  +    	if (gDesc1.getGrammarType() != gDesc2.getGrammarType()) {
  +    	    return false;
  +    	}
  +    	if (gDesc1.getGrammarType().equals(XMLGrammarDescription.XML_DTD)) {
  +    	    if (((XMLDTDDescription)gDesc1).getRootName().equals(((XMLDTDDescription)gDesc2).getRootName())) {
  +    	    	return true;
  +    	    }
  +    	}
  +    	else if (gDesc1.getGrammarType().equals(XMLGrammarDescription.XML_SCHEMA)) {
  +    	    String namespace1 = ((XSDDescription)gDesc1).getTargetNamespace();
  +    	    String namespace2 = ((XSDDescription)gDesc2).getTargetNamespace();
  +    	    if (namespace1 != null && namespace1.equals(namespace2)) {
  +    	    	return true;
  +    	    }
  +    	    else if (namespace1 == null && namespace2 == null) {
  +    	    	return true;
  +    	    }
  +    	}
  +    	return false; 
  +    }
  +    
  +    public int hashCode(XMLGrammarDescription desc) {
  +    	if (desc.getGrammarType().equals(XMLGrammarDescription.XML_DTD)) {
  +            return (((XMLDTDDescription)desc).getRootName()).hashCode();
  +        }
  +        else {
  +            String namespace = ((XSDDescription)desc).getTargetNamespace();
  +            return (namespace != null) ? namespace.hashCode() : 0;
  +        }
  +    }
  +    
  +    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
  
  
  
  1.43      +361 -24   xml-xerces/java/src/org/apache/xerces/impl/xs/XMLSchemaValidator.java
  
  Index: XMLSchemaValidator.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/XMLSchemaValidator.java,v
  retrieving revision 1.42
  retrieving revision 1.43
  diff -u -r1.42 -r1.43
  --- XMLSchemaValidator.java	15 Feb 2002 16:00:30 -0000	1.42
  +++ XMLSchemaValidator.java	19 Feb 2002 21:03:38 -0000	1.43
  @@ -65,9 +65,7 @@
   import org.apache.xerces.impl.xs.identity.*;
   import org.apache.xerces.impl.Constants;
   import org.apache.xerces.impl.validation.ValidationManager;
  -import org.apache.xerces.xni.grammars.XMLGrammarPool;
   import org.apache.xerces.impl.validation.XMLGrammarPoolImpl;
  -import org.apache.xerces.xni.grammars.Grammar;
   import org.apache.xerces.impl.XMLErrorReporter;
   import org.apache.xerces.impl.xs.traversers.XSDHandler;
   import org.apache.xerces.impl.xs.traversers.XSAttributeChecker;
  @@ -75,8 +73,7 @@
   import org.apache.xerces.impl.xs.models.XSCMValidator;
   import org.apache.xerces.impl.msg.XMLMessageFormatter;
   import org.apache.xerces.impl.validation.ValidationState;
  -import org.apache.xerces.xni.parser.XMLEntityResolver;
  -import org.apache.xerces.xni.parser.XMLInputSource;
  +import org.apache.xerces.impl.XMLEntityManager;
   
   import java.io.IOException;
   import org.apache.xerces.util.AugmentationsImpl;
  @@ -99,6 +96,12 @@
   import org.apache.xerces.xni.parser.XMLComponentManager;
   import org.apache.xerces.xni.parser.XMLConfigurationException;
   import org.apache.xerces.xni.parser.XMLDocumentFilter;
  +import org.apache.xerces.xni.parser.XMLEntityResolver;
  +import org.apache.xerces.xni.parser.XMLInputSource;
  +
  +import org.apache.xerces.xni.grammars.XMLGrammarPool;
  +import org.apache.xerces.xni.grammars.Grammar;
  +import org.apache.xerces.xni.grammars.XMLGrammarDescription;
   
   
   import org.apache.xerces.xni.psvi.ElementPSVI;
  @@ -130,7 +133,7 @@
    * @author Elena Litani IBM
    * @author Andy Clark IBM
    * @author Neeraj Bajaj, Sun Microsystems, inc.
  - * @version $Id: XMLSchemaValidator.java,v 1.42 2002/02/15 16:00:30 sandygao Exp $
  + * @version $Id: XMLSchemaValidator.java,v 1.43 2002/02/19 21:03:38 neeraj Exp $
    */
   public class XMLSchemaValidator
                implements XMLComponent, XMLDocumentFilter, FieldActivator {
  @@ -355,6 +358,10 @@
       protected String fExternalSchemas = null;
       protected String fExternalNoNamespaceSchema = null;
   
  +    /** Schema Grammar Description passed,  to give a chance to application to supply the Grammar */
  +    protected final XSDDescription fXSDDescription = new XSDDescription() ;
  +    protected final Hashtable fLocationPairs = new Hashtable() ;
  +    protected String fNoNamespaceLocation = null ;
       // handlers
   
       /** Document handler. */
  @@ -743,6 +750,12 @@
       public void endDocument(Augmentations augs) throws XNIException {
   
           handleEndDocument();
  +        
  +        //return the final set of grammars validator ended up with
  +        if(fGrammarPool != null){
  +            fGrammarPool.cacheGrammars(XMLGrammarDescription.XML_SCHEMA , fGrammarBucket.getGrammars() ) ;       
  +        }
  +        
           // call handlers
           if (fDocumentHandler != null) {
               fDocumentHandler.endDocument(augs);
  @@ -1161,9 +1174,13 @@
           // clear grammars, and put the one for schema namespace there
           fGrammarBucket.reset();
           fGrammarPool = (XMLGrammarPool)componentManager.getProperty(XMLGRAMMAR_POOL);
  -        if(fGrammarPool instanceof XMLGrammarPoolImpl) {
  -            XMLGrammarPoolImpl poolImpl = (XMLGrammarPoolImpl)fGrammarPool;
  -            Grammar [] initialGrammars = poolImpl.getGrammarsNS();
  +        
  +        //we should retreive the initial grammar set given by the applicaion
  +        //to the parser and put it in local grammar bucket. 
  +        
  +        if(fGrammarPool != null) {
  +            
  +            Grammar [] initialGrammars = fGrammarPool.retrieveInitialGrammarSet(XMLGrammarDescription.XML_SCHEMA);
               for (int i = 0; i < initialGrammars.length; i++) {
                   fGrammarBucket.putGrammar((SchemaGrammar)(initialGrammars[i]));
               }
  @@ -1176,8 +1193,13 @@
           fSchemaHandler.reset(fXSIErrorReporter.fErrorReporter,
                                fEntityResolver, fSymbolTable,
                                fExternalSchemas, fExternalNoNamespaceSchema,
  -                             jaxpSchemaSource);
  +                             jaxpSchemaSource, fGrammarPool);
   
  +        //reset XSDDescripton
  +        fXSDDescription.reset() ;
  +        fLocationPairs.clear();
  +        fNoNamespaceLocation = null ;
  +        
           // initialize state
           fCurrentElemDecl = null;
           fNil = false;
  @@ -1587,12 +1609,18 @@
   
           // get xsi:schemaLocation and xsi:noNamespaceSchemaLocation attributes,
           // parse them to get the grammars
  -        // REVISIT: we'll defer this operation until there is a reference to
  -        //          a component from that namespace
   
           String sLocation = attributes.getValue(URI_XSI, XSI_SCHEMALOCATION);
           String nsLocation = attributes.getValue(URI_XSI, XSI_NONAMESPACESCHEMALOCATION);
  -        parseSchemas(sLocation, nsLocation);
  +        
  +        //store the location hints..  we need to do it so that we can defer the loading of grammar until
  +        //there is a reference to a component from that namespace. To provide location hints to the
  +        //application for a namespace
  +        storeLocations(sLocation, nsLocation) ;
  +        
  +        //REVISIT: We should do the same in XSDHandler also... we should not 
  +        //load the actual grammar (eg. import) unless there is reference to it. 
  +        //parseSchemas(sLocation, nsLocation);
   
           // REVISIT: we should not rely on presence of
           //          schemaLocation or noNamespaceSchemaLocation
  @@ -1657,8 +1685,58 @@
           // try again to get the element decl
           if (fCurrentElemDecl == null) {
               SchemaGrammar sGrammar = fGrammarBucket.getGrammar(element.uri);
  -            if (sGrammar != null)
  +            //give a chance to application to be able to retreive the grammar.
  +            if(sGrammar == null && fGrammarPool != null){
  +
  +                //application should take care of possible inclusion of xsi:type in attributes while providing grammar during 
  +                //startElement call
  +                fXSDDescription.reset() ;
  +                fXSDDescription.fContextType = XSDDescription.CONTEXT_ELEMENT ;
  +                fXSDDescription.fTargetNamespace = element.uri ;                
  +                fXSDDescription.fTriggeringComponent = element ;
  +                fXSDDescription.fAttributes = attributes ;                
  +                //REVISIT: we need to provide location hints available for the current namespace.
  +                Object locationArray = null ; 
  +                if(element.uri != null){               
  +                	locationArray = fLocationPairs.get(element.uri) ;                
  +                }
  +                if(locationArray != null){
  +                    String [] locations = ((LocationArray)locationArray).getLocationArray() ;
  +                    fXSDDescription.fLocationHints = new String [locations.length] ;
  +                    System.arraycopy(locations, 0 , fXSDDescription.fLocationHints, 0, locations.length );                    
  +                }else{
  +                	fXSDDescription.fLocationHints = new String [] {fNoNamespaceLocation} ;
  +                }                             
  +
  +                sGrammar = (SchemaGrammar)fGrammarPool.retrieveGrammar(fXSDDescription);
  +                
  +            }
  +            //try to parse the grammar.. using location hint given.. 
  +            if(sGrammar == null){
  +                String locationHint = null ;
  +                LocationArray locationArray = null ;
  +                if(element.uri != null){               
  +                    locationArray = (LocationArray)fLocationPairs.get(element.uri) ;
  +                }
  +                if(locationArray != null){                    
  +                    //REVISIT: we are returning the first location hint available for a particular namespace.. is it the right thing to do ??
  +                    locationHint = locationArray.getFirstLocation() ;
  +                }else{
  +                    locationHint = fNoNamespaceLocation ;
  +                }
  +                
  +                if(!(element.uri == null && locationHint == null)){
  +                    parseSchema( element.uri, locationHint, XSDDescription.CONTEXT_ELEMENT) ;
  +                }
  +            }
  +                
  +            //now try again to retreive it from local bucket..
  +            sGrammar = fGrammarBucket.getGrammar(element.uri);
  +            
  +            if (sGrammar != null){
                   fCurrentElemDecl = sGrammar.getGlobalElementDecl(element.localpart);
  +            }
  +            
           }
   
           // Element Locally Valid (Element)
  @@ -1676,7 +1754,7 @@
           // get type from xsi:type
           String xsiType = attributes.getValue(URI_XSI, XSI_TYPE);
           if (xsiType != null)
  -            getAndCheckXsiType(element, xsiType);
  +            getAndCheckXsiType(element, xsiType, attributes);
   
           // if the element decl is not found
           if (fCurrentType == null) {
  @@ -2010,6 +2088,93 @@
           fNamespaceSupport.declarePrefix(prefix, uri.length() != 0 ? uri : null);
       }
   
  +    private class LocationArray{
  +    
  +        int length ;
  +        String [] locations = new String[2];
  +        
  +        public void resize(int oldLength , int newLength){
  +            String [] tempLocations = new String[newLength] ;
  +            System.arraycopy(locations,0, tempLocations, 0, Math.min(oldLength, newLength));
  +            locations = tempLocations ;        
  +        }
  +        
  +        public void setLocation(String location){
  +            if(length >= locations.length - 1){
  +                resize(locations.length, locations.length*2);
  +            }                        
  +            locations[length++] = location ;                    
  +        }//setLocation()
  +        
  +        public String [] getLocationArray(){
  +	//REVISIT:should we expanded location hints before returning ??            
  +         if(length < locations.length ){
  +            resize(locations.length, length);
  +         }
  +         return locations ;
  +        }//getLocationArray()
  +        
  +        //REVISIT: we are returning the first location hint available for a particular namespace.. is it the right thing to do ??
  +        public String getFirstLocation(){
  +            return locations[0] ;
  +        }
  +        
  +        public int getLength(){
  +            return length ;
  +        }
  +        
  +    } //locationArray
  +    
  +    void storeLocations(String sLocation, String nsLocation){
  +        
  +        if (sLocation != null) {
  +            StringTokenizer t = new StringTokenizer(sLocation, " \n\t\r");
  +            String namespace, location;
  +            while (t.hasMoreTokens()) {
  +                namespace = fSymbolTable.addSymbol(t.nextToken ());
  +                
  +                if (!t.hasMoreTokens()) {
  +                    fXSIErrorReporter.reportError(XSMessageFormatter.SCHEMA_DOMAIN,
  +                                                  "SchemaLocation",
  +                                                  new Object[]{sLocation},
  +                                                  XMLErrorReporter.SEVERITY_WARNING);
  +                    break;
  +                }
  +                
  +                Object locationArray = fLocationPairs.get(namespace) ;
  +                
  +                if(locationArray == null){
  +                    locationArray = new LocationArray() ;
  +                    //add it into hashtable...
  +                    fLocationPairs.put(namespace, locationArray);
  +                }
  +                                
  +                location = t.nextToken();
  +                ((LocationArray)locationArray).setLocation(location);
  +            }
  +            
  +        }
  +        if (nsLocation != null) {
  +        	fNoNamespaceLocation = nsLocation ;
  +	/**        	
  +            Object locationArray = fLocationPairs.get("") ;                
  +            if(locationArray == null){
  +                locationArray = new LocationArray() ;
  +                //add it into hashtable...
  +                fLocationPairs.put("", locationArray);
  +            }
  +            //there would always be only one location...
  +            ((LocationArray)locationArray).setLocation(nsLocation);
  +        */
  +                                
  +        }
  +            
  +    }//storeLocations
  +    
  +    void parseSchema(String nameSpace, String location, short reference){
  +        fSchemaHandler.parseSchema(nameSpace, location, reference);    
  +    }
  +    
       void parseSchemas(String sLocation, String nsLocation) {
           if (sLocation != null) {
               StringTokenizer t = new StringTokenizer(sLocation, " \n\t\r");
  @@ -2024,20 +2189,63 @@
                       break;
                   }
                   location = t.nextToken();
  -                if (fGrammarBucket.getGrammar(namespace) == null) {
  +                
  +                if (fGrammarBucket.getGrammar(namespace) == null) {                
                       fSchemaHandler.parseSchema(namespace, location,
  -                                               XSDDescription.CONTEXT_INSTANCE);
  +                                           XSDDescription.CONTEXT_INSTANCE);
                   }
  +                
  +                /** this function will only be called in case of externalSchemaLocation property is specified...
  +                
  +                // We would like to give chance to application to be able to provide this grammar...
  +                if (fGrammarBucket.getGrammar(namespace) == null) {                
  +                    Grammar retrievedGrammar = null ;                	
  +                    if(fGrammarPool != null){   
  +                            //REVISIT: how to set the values of XSDDescription ??
  +                            fXSDDescription.fTargetNamespace = namespace ;
  +                            fXSDDescription.fContext = XSDDescription.CONTEXT_INSTANCE ;
  +                            retrievedGrammar = fGrammarPool.retrieveGrammar(fXSDDescription);
  +
  +                    }                	
  +                    if(retrievedGrammar != null){
  +                            fGrammarBucket.putGrammar(retrievedGrammar) ;
  +                    }
  +                    else{
  +                            fSchemaHandler.parseSchema(namespace, location,
  +                                           XSDDescription.CONTEXT_INSTANCE);
  +                    }
  +                */                                
               }
           }
           if (nsLocation != null) {
  -            if (fGrammarBucket.getGrammar(null) == null)
  -                fSchemaHandler.parseSchema(null, nsLocation,
  -                                           XSDDescription.CONTEXT_INSTANCE);
  +            if (fGrammarBucket.getGrammar(null) == null){  
  +                fSchemaHandler.parseSchema(null, nsLocation, XSDDescription.CONTEXT_INSTANCE);
  +                
  +                /*** this funcion should only be called from external SchemaLocation...
  +                 
  +                Grammar retrievedGrammar = null ;                	
  +                //if grammar pool is provided by the application....
  +                if(fGrammarPool != null){                        
  +                        //REVISIT: how to set the values of XSDDescription ??
  +                        fXSDDescription.fTargetNamespace = null;
  +                        fXSDDescription.fContext = XSDDescription.INSTANCE ;
  +                        retrievedGrammar = fGrammarPool.retrieveGrammar(fXSDDescription);
  +
  +                }                	
  +                if(retrievedGrammar != null){
  +                        fGrammarBucket.putGrammar(retrievedGrammar) ;
  +                }
  +                else{
  +                        fSchemaHandler.parseSchema(null, nsLocation,
  +                                   XSDDescription.CONTEXT_INSTANCE);
  +                }    
  +                **/            	                	            
  +            }
           }
  -    }
  +        
  +    }//parseSchemas(String,String)
   
  -    void getAndCheckXsiType(QName element, String xsiType) {
  +    void getAndCheckXsiType(QName element, String xsiType, XMLAttributes attributes) {
           // This method also deals with clause 1.2.1.2 of the constraint
           // Validation Rule: Schema-Validity Assessment (Element)
   
  @@ -2062,6 +2270,56 @@
           // if it's not schema built-in types, then try to get a grammar
           if (type == null) {
               SchemaGrammar grammar = fGrammarBucket.getGrammar(typeName.uri);
  +            //give a chance to application to be able to retreive the grammar.
  +            if(grammar == null && fGrammarPool != null){
  +                       
  +                fXSDDescription.reset();         
  +                fXSDDescription.fContextType = XSDDescription.CONTEXT_XSITYPE ;
  +                fXSDDescription.fTargetNamespace = typeName.uri ;                
  +                fXSDDescription.fTriggeringComponent = typeName ;
  +                fXSDDescription.fEnclosedElementName = element ;
  +                fXSDDescription.fAttributes = attributes ;
  +                // we need to provide location hints available to the application for a namespace
  +                LocationArray locationArray = null ;
  +                
  +                if(typeName.uri != null){
  +                	locationArray = (LocationArray)fLocationPairs.get(typeName.uri) ;
  +                }
  +                                
  +                if(locationArray != null){
  +                    String [] locations = locationArray.getLocationArray() ;
  +                    fXSDDescription.fLocationHints = new String [locations.length] ;
  +                    System.arraycopy(locations, 0 , fXSDDescription.fLocationHints, 0, locations.length );                    
  +		}else{
  +                	fXSDDescription.fLocationHints = new String [] {fNoNamespaceLocation} ;
  +                }                                             
  +                grammar = (SchemaGrammar)fGrammarPool.retrieveGrammar(fXSDDescription);
  +            }
  +            
  +            //try to parse the grammar.. using location hint given.. 
  +            if(grammar == null){
  +                String locationHint = null ;
  +                LocationArray locationArray = null ;
  +                
  +                if(typeName.uri != null ){
  +                    locationArray = (LocationArray)fLocationPairs.get(typeName.uri) ;
  +                }
  +                
  +                if(locationArray != null){
  +                    //REVISIT: we are returning the first location hint available for a particular namespace.. is it the right thing to do ??
  +                    locationHint = locationArray.getFirstLocation() ;
  +                }else{
  +                    locationHint = fNoNamespaceLocation ;
  +                }
  +                
  +                if(!(typeName.uri == null && locationHint == null)){                
  +                    parseSchema( typeName.uri, locationHint, XSDDescription.CONTEXT_XSITYPE) ;
  +               	}
  +            }
  +                
  +            //now try again to retreive it from local bucket..
  +            grammar = fGrammarBucket.getGrammar(typeName.uri);
  +
               if (grammar != null)
                   type = grammar.getGlobalTypeDecl(typeName.localpart);
           }
  @@ -2083,7 +2341,7 @@
           }
   
           fCurrentType = type;
  -    }
  +    }//getAndCheckXsiType
   
       void getXsiNil(QName element, String xsiNil) {
           // Element Locally Valid (Element)
  @@ -2262,8 +2520,57 @@
                       continue;
                   // now get the grammar and attribute decl
                   SchemaGrammar grammar = fGrammarBucket.getGrammar(fTempQName.uri);
  -                if (grammar != null)
  +                
  +                //give a chance to application to be able to retreive the grammar.
  +                if(grammar == null && fGrammarPool != null){
  +                    fXSDDescription.reset();
  +                    fXSDDescription.fContextType = XSDDescription.CONTEXT_ATTRIBUTE ;
  +                    fXSDDescription.fTargetNamespace = fTempQName.uri ;                    
  +                    fXSDDescription.fTriggeringComponent = fTempQName ;
  +                    fXSDDescription.fEnclosedElementName = element ;
  +                    fXSDDescription.fAttributes = attributes ;
  +                    //REVISIT: we need to provide the location hints available for the namespace 
  +                    LocationArray locationArray = null ;
  +                    if(fTempQName.uri != null){
  +                        locationArray = (LocationArray)fLocationPairs.get(fTempQName.uri) ;                
  +                    }
  +                    if(locationArray != null){
  +                        String [] locations = locationArray.getLocationArray() ;
  +                        fXSDDescription.fLocationHints = new String [locations.length] ;
  +                        System.arraycopy(locations, 0 , fXSDDescription.fLocationHints, 0, locations.length );                    
  +                    }else{
  +                	fXSDDescription.fLocationHints = new String [] {fNoNamespaceLocation} ;
  +                    }
  +                    
  +                    grammar = (SchemaGrammar)fGrammarPool.retrieveGrammar(fXSDDescription);
  +                }
  +                
  +                //try to parse the grammar.. using location hint given.. 
  +                if(grammar == null){
  +                    String locationHint = null;
  +                    LocationArray locationArray = null ;
  +                    
  +                    if(fTempQName.uri != null){
  +                        locationArray = (LocationArray)fLocationPairs.get(fTempQName.uri) ;
  +                    }
  +                    if(locationArray != null){
  +                        //REVISIT: we are returning the first location hint available for a particular namespace.. is it the right thing to do ??
  +                        locationHint = locationArray.getFirstLocation() ;
  +                    }else{
  +                        locationHint = fNoNamespaceLocation ;
  +                    }
  +                    
  +                    if(!(fTempQName.uri == null && locationHint == null)){
  +                        parseSchema( fTempQName.uri, locationHint, XSDDescription.CONTEXT_ATTRIBUTE) ;
  +                    }
  +                }
  +                //now try again to retreive it from local bucket..
  +                grammar = fGrammarBucket.getGrammar(fTempQName.uri);
  +                
  +                if (grammar != null){
                       currDecl = grammar.getGlobalAttributeDecl(fTempQName.localpart);
  +                }
  +                
                   // if can't find
                   if (currDecl == null) {
                       // if strict, report error
  @@ -2332,6 +2639,36 @@
                       ((XSAtomicSimpleType)attDV).getPrimitiveKind() == XSAtomicSimpleType.PRIMITIVE_NOTATION){
                      QName qName = (QName)actualValue;
                      SchemaGrammar grammar = fGrammarBucket.getGrammar(qName.uri);
  +                   
  +                   
  +                   //REVISIT: is it possible for the notation to be in different namespace than the attribute 
  +                   //with which it is associated, CHECK !!  <fof n1:att1 = "n2:notation1" ..>
  +                   // should we give chance to the application to be able to  retrieve a grammar - nb
  +                   //REVISIT: what would be the triggering component here.. if it is attribute value that 
  +                   // triggered the loading of grammar ?? -nb
  +                   
  +                   /**
  +                   //give a chance to application to be able to retreive the grammar...
  +                    if(grammar == null && fGrammarPool != null ){                        
  +                        fXSDDescription.reset() ;
  +                        fXSDDescription.fContextType = ?? ; //attribute value
  +                        fXSDDescription.fTargetNamespace = qName.uri ;                        
  +                        fXSDDescription.fTriggeringComponent = typeName ;
  +                        fXSDDescription.fEnclosedElementName = element ;
  +                        //fXSDDescription.fLocationHints ;
  +                        LocationArray locationArray = (LocationArray)fLocationPairs.get(qName.uri) ;
  +                
  +                        if(locationArray != null){
  +                            String [] locations = locationArray.getLocationArray() ;
  +                            fXSDDescription.fLocationHints = new String [locations.length] ;
  +                            System.arraycopy(locations, 0 , fXSDDescription.fLocationHints, 0, locations.legth );                    
  +                        }                                
  +
  +
  +                        grammar = (SchemaGrammar)fGrammarPool.retrieveGrammar(fXSDDescription);
  +                   }  
  +                    */
  +                   
                      if (grammar != null)
                          fCurrentPSVI.fNotation = grammar.getNotationDecl(qName.localpart);
                   }
  @@ -2460,7 +2797,7 @@
       XMLString processElementContent(QName element) {
           // fCurrentElemDecl: default value; ...
           XMLString defaultValue = null;
  -        // 1 If the item is �valid� with respect to an element declaration as per Element Locally Valid (Element) (�3.3.4) and the {value constraint} is present, but clause 3.2 of Element Locally Valid (Element) (�3.3.4) above is not satisfied and the item has no element or character information item [children], then schema. Furthermore, the post-schema-validation infoset has the canonical lexical representation of the {value constraint} value as the item's [schema normalized value] property.
  +        // 1 If the item is ?valid? with respect to an element declaration as per Element Locally Valid (Element) (?3.3.4) and the {value constraint} is present, but clause 3.2 of Element Locally Valid (Element) (?3.3.4) above is not satisfied and the item has no element or character information item [children], then schema. Furthermore, the post-schema-validation infoset has the canonical lexical representation of the {value constraint} value as the item's [schema normalized value] property.
           if (fCurrentElemDecl != null && fCurrentElemDecl.fDefault != null &&
               fBuffer.toString().length() == 0 && fChildCount == 0 && !fNil) {
   
  
  
  
  1.3       +31 -8     xml-xerces/java/src/org/apache/xerces/impl/xs/XSDDescription.java
  
  Index: XSDDescription.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/XSDDescription.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- XSDDescription.java	9 Feb 2002 20:55:21 -0000	1.2
  +++ XSDDescription.java	19 Feb 2002 21:03:38 -0000	1.3
  @@ -66,7 +66,9 @@
    * All information specific to XML Schema grammars.
    *
    * @author Neil Graham, IBM
  - * @version $Id: XSDDescription.java,v 1.2 2002/02/09 20:55:21 neilg Exp $
  + * @author Neeraj Bajaj, SUN Microsystems.
  + *
  + * @version $Id: XSDDescription.java,v 1.3 2002/02/19 21:03:38 neeraj Exp $
    */
   public class XSDDescription extends XMLResourceIdentifierImpl 
   		implements XMLGrammarDescription {
  @@ -122,6 +124,15 @@
        */
       public final static short CONTEXT_XSITYPE   = 7;
   
  +    // REVISIT: write description of these fields	
  +    protected short fContextType;
  +    protected String fTargetNamespace;
  +    protected String [] fLocationHints ;
  +    protected QName fTriggeringComponent;
  +    protected QName fEnclosedElementName;
  +    protected XMLAttributes  fAttributes;
  +
  +        
       /**
        * the type of the grammar (e.g., DTD or XSD);
        *  
  @@ -138,7 +149,7 @@
        * @return  the value indicating the context
        */
       public short getContextType() {
  -        return 0;
  +        return fContextType ;
       }
   
       /**
  @@ -149,7 +160,7 @@
        * @return  the expected/enclosing target namespace
        */
       public String getTargetNamespace() {
  -        return null;
  +        return fTargetNamespace ;
       }
   
       /**
  @@ -159,9 +170,9 @@
        * 
        * @return  an array of all location hints associated to the expected
        *          target namespace
  -     */
  +     */          
       public String[] getLocationHints() {
  -        return null;
  +        return fLocationHints ;
       }
   
       /**
  @@ -172,7 +183,7 @@
        * @return  the name of the triggering component
        */
       public QName getTriggeringComponent() {
  -        return null;
  +        return fTriggeringComponent ;
       }
   
       /**
  @@ -182,7 +193,7 @@
        * @return  the name of the enclosing element
        */
       public QName getEnclosingElementName() {
  -        return null;
  +        return fEnclosedElementName ;
       }
       
       /**
  @@ -192,7 +203,19 @@
        * @return  all attributes of the tiggering/enclosing element
        */
       public XMLAttributes getAttributes() {
  -        return null;
  +        return fAttributes;
  +    }
  +    
  +    /**
  +     *  resets all the fields
  +     */
  +    protected void reset(){
  +        fContextType = 0 ;
  +        fTargetNamespace = null ;
  +        fLocationHints  = null ;
  +        fTriggeringComponent = null ;
  +        fEnclosedElementName = null ;
  +        fAttributes = null ;    
       }
       
   } // XSDDescription
  
  
  
  1.27      +112 -25   xml-xerces/java/src/org/apache/xerces/impl/xs/traversers/XSDHandler.java
  
  Index: XSDHandler.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/xs/traversers/XSDHandler.java,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- XSDHandler.java	18 Feb 2002 22:30:25 -0000	1.26
  +++ XSDHandler.java	19 Feb 2002 21:03:38 -0000	1.27
  @@ -74,9 +74,12 @@
   import org.apache.xerces.impl.XMLEntityManager;
   import org.apache.xerces.xni.QName;
   import org.apache.xerces.xni.XMLResourceIdentifier;
  +import org.apache.xerces.xni.XMLAttributes;
   import org.apache.xerces.xni.parser.XMLConfigurationException;
   import org.apache.xerces.xni.parser.XMLEntityResolver;
   import org.apache.xerces.xni.parser.XMLInputSource;
  +import org.apache.xerces.xni.grammars.Grammar;
  +import org.apache.xerces.xni.grammars.XMLGrammarPool;
   import org.apache.xerces.util.XMLResourceIdentifierImpl;
   import org.apache.xerces.util.SymbolTable;
   import org.apache.xerces.util.SymbolHash;
  @@ -113,7 +116,8 @@
    * schema, other grammars may be constructed as a side-effect.
    *
    * @author Neil Graham, IBM
  - * @version $Id: XSDHandler.java,v 1.26 2002/02/18 22:30:25 sandygao Exp $
  + * @author Pavani Mukthipudi, Sun Microsystems
  + * @version $Id: XSDHandler.java,v 1.27 2002/02/19 21:03:38 neeraj Exp $
    */
   public class XSDHandler {
   
  @@ -284,6 +288,12 @@
   
       // the GrammarResolver
       private XSGrammarBucket fGrammarBucket;
  +    
  +    // the Grammar description
  +    private SchemaGrammarDescription fSchemaGrammarDescription;
  +    
  +    // the Grammar Pool
  +    private XMLGrammarPool fGrammarPool;
   
       //************ Traversers **********
       XSDAttributeGroupTraverser fAttributeGroupTraverser;
  @@ -498,21 +508,36 @@
           // a schema document can always access it's own target namespace
           currSchemaInfo.addAllowedNS(currSchemaInfo.fTargetNamespace);
   
  -        if (fGrammarBucket.getGrammar(currSchemaInfo.fTargetNamespace) == null) {
  -            // REVISIT:  the grammar bucket should have been called
  -            // already, when we first tried to do the import (not with
  -            // preparse of course).  So this code should be moved!  - NG
  -            SchemaGrammar sg = new SchemaGrammar(fSymbolTable, currSchemaInfo.fTargetNamespace, new XSDDescription());
  +        SchemaGrammar sg = null;
  +        SchemaGrammarDescription grammarDescription = null;
  +        
  +        // In the case of preparse, if the grammar is not available in the bucket we ask the pool
  +        // If the context is instance, the validator would have already consulted the pool
  +        if ((sg = fGrammarBucket.getGrammar(currSchemaInfo.fTargetNamespace)) == null && referType == XSDDescription.CONTEXT_PREPARSE) {
  +            if (fGrammarPool != null) {
  +            	grammarDescription = new SchemaGrammarDescription();
  +            	grammarDescription.setContextType(referType);
  +            	grammarDescription.setTargetNamespace(currSchemaInfo.fTargetNamespace);
  +            	grammarDescription.setLocationHints(new String[] {locationHint});
  +            	sg = (SchemaGrammar)fGrammarPool.retrieveGrammar(grammarDescription);
  +             	if (sg != null) {
  +             	    fGrammarBucket.putGrammar(sg);
  +             	}
  +	    }
  +	}
  +	if (sg == null) {
  +	    grammarDescription = new SchemaGrammarDescription();
  +	    grammarDescription.setContextType(referType);
  +	    grammarDescription.setTargetNamespace(currSchemaInfo.fTargetNamespace);
  +            grammarDescription.setLocationHints(new String[] {locationHint});
  +	    sg = new SchemaGrammar(fSymbolTable, currSchemaInfo.fTargetNamespace, grammarDescription);
               fGrammarBucket.putGrammar(sg);
  -        }
  -        // we got a grammar of the samenamespace in the bucket, should ignore this one
  -        else if (referType == XSDDescription.CONTEXT_INSTANCE ||
  -                 referType == XSDDescription.CONTEXT_IMPORT ||
  -                 referType == XSDDescription.CONTEXT_PREPARSE) {
  +	}
  +	// we got a grammar of the same namespace in the bucket, should ignore this one 
  +	else if (referType == XSDDescription.CONTEXT_PREPARSE) {
               return null;
  -        }
  -
  -        // Modified by Pavani Mukthipudi, Sun Microsystems Inc.
  +	}
  +	    
           fDoc2XSDocumentMap.put(schemaRoot, currSchemaInfo);
   
           Vector dependencies = new Vector();
  @@ -543,18 +568,31 @@
                       reportSchemaError("src-import.1.1", new Object [] {schemaNamespace}, child);
                   }
                   fAttributeChecker.returnAttrArray(includeAttrs, currSchemaInfo);
  +                
                   // a schema document can access it's imported namespaces
                   currSchemaInfo.addAllowedNS(schemaNamespace);
  -                // consciously throw away whether was a duplicate; don't care.
  -                // pass the systemId of the current document as the base systemId
  -                // REVISIT:  We must consult the gtrammar bucket, then the gramar
  -                // pool, and only then the entity resolver; this *must* be the
  -                // order.  Therefore, the current sequence is *wrong*, since we
  -                // consult the EntityResolver, only when we call constructTrees
  -                // again consulting Grammar bucket.  So this code needs to be
  -                // reworked - NG
  -                // i.e., we need to create an XSDDescription, ask Grammar
  -                // bucket, ask GrammarPool, then pass that along...
  +                
  +                // We first ask the GrammarBucket, then the GrammarPool and only then the EntityResolver is consulted
  +                
  +                if (fGrammarBucket.getGrammar(schemaNamespace) != null) {
  +                    continue;
  +                }
  +                else {
  +                    if (fGrammarPool != null) {
  +                    	fSchemaGrammarDescription.reset();
  +                    	fSchemaGrammarDescription.setTargetNamespace(schemaNamespace);
  +                    	sg = (SchemaGrammar)fGrammarPool.retrieveGrammar(fSchemaGrammarDescription);
  +                    	if (sg != null) {
  +			    fGrammarBucket.putGrammar(sg);
  +			    continue;
  +			}
  +                    }
  +                }
  +                grammarDescription = new SchemaGrammarDescription();
  +                grammarDescription.setTargetNamespace(schemaNamespace);
  +                grammarDescription.setLocationHints(new String[] {schemaHint});
  +                sg = new SchemaGrammar(fSymbolTable, schemaNamespace, grammarDescription);
  +                fGrammarBucket.putGrammar(sg);
                   newSchemaRoot = getSchema(schemaNamespace, schemaHint, (String)fDoc2SystemId.get(schemaRoot), false, XSDDescription.CONTEXT_IMPORT, child);
               }
               else if ((localName.equals(SchemaSymbols.ELT_INCLUDE)) ||
  @@ -1277,10 +1315,11 @@
                         SymbolTable symbolTable,
                         String externalSchemaLocation,
                         String externalNoNSSchemaLocation,
  -                      Object jaxpSchemaSource) {
  +                      Object jaxpSchemaSource, XMLGrammarPool grammarPool) {
   
           fErrorReporter = errorReporter;
           fSymbolTable = symbolTable;
  +        fGrammarPool = grammarPool;
   
           EMPTY_STRING = fSymbolTable.addSymbol(SchemaSymbols.EMPTY_STRING);
   
  @@ -1925,4 +1964,52 @@
               return true;
           }
       }
  +    
  +    /**
  +     * This inner class extends XSDDescription and provides set methods for setting the
  +     * protected fields of XSDDescription. It is declared private, so as, not to expose set*
  +     * methods outside this class. XSDDescription is for providing the read only information 
  +     * to the application about Schema Grammar required by the parser. Application uses this info
  +     * in making decisions about caching/retrieving appropriate grammar. XSDHanlder will make use 
  +     * of this class to provide information and give a chance to application to supply 
  +     * SchemaGrammar required by parser.     
  +     *
  +     * @author Neeraj Bajaj SUN Microsystems.
  +     *
  +     */
  +    private class SchemaGrammarDescription extends XSDDescription {
  +    
  +        
  +        public void setContextType(short contextType){
  +            fContextType = contextType ;
  +        }
  +
  +        public void setTargetNamespace(String targetNamespace){
  +            fTargetNamespace = targetNamespace ;
  +        }
  +
  +        public void setLocationHints(String [] locationHints){
  +            int length = locationHints.length ;
  +            fLocationHints  = new String[length];
  +            System.arraycopy(locationHints, 0, fLocationHints, 0, length);
  +            //fLocationHints = locationHints ;
  +        }
  +
  +        public void setTriggeringComponent(QName triggeringComponent){
  +            fTriggeringComponent = triggeringComponent ;
  +        }
  +
  +        public void setEnclosingElementName(QName enclosedElementName){
  +            fEnclosedElementName = enclosedElementName ;
  +        }
  +
  +        public void setAttributes(XMLAttributes attributes){
  +            fAttributes = attributes ;    
  +        }
  +        
  +        public void reset(){
  +            super.reset();
  +        }
  +    
  +    }//SchemaGrammarDescription
   } // XSDHandler
  
  
  
  1.9       +34 -26    xml-xerces/java/src/org/apache/xerces/parsers/CachingParserPool.java
  
  Index: CachingParserPool.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/parsers/CachingParserPool.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- CachingParserPool.java	7 Feb 2002 22:15:09 -0000	1.8
  +++ CachingParserPool.java	19 Feb 2002 21:03:39 -0000	1.9
  @@ -94,7 +94,7 @@
    *
    * @author Andy Clark, IBM
    *
  - * @version $Id: CachingParserPool.java,v 1.8 2002/02/07 22:15:09 neilg Exp $
  + * @version $Id: CachingParserPool.java,v 1.9 2002/02/19 21:03:39 neeraj Exp $
    */
   public class CachingParserPool {
   
  @@ -470,32 +470,40 @@
           // GrammarPool methods
           //
   
  -        // retrieve the initial set of grammars for the validator
  -        // to work with.
  -        // REVISIT:  does this need to be synchronized since it's just reading?
  -        // @param grammarType type of the grammars to be retrieved.
  -        // @return the initial grammar set the validator may place in its "bucket"
  +        /**
  +         * Retrieve the initial set of grammars for the validator to work with.
  +         * REVISIT:  does this need to be synchronized since it's just reading?
  +         * 
  +         * @param grammarType Type of the grammars to be retrieved.
  +         * @return            The initial grammar set the validator may place in its "bucket"
  +         */
           public Grammar [] retrieveInitialGrammarSet(String grammarType ) {
               Grammar [] grammars = super.retrieveInitialGrammarSet(grammarType);
               if (grammars != null) return grammars;
               return fGrammarPool.retrieveInitialGrammarSet(grammarType);
           } // retrieveInitialGrammarSet(String):  Grammar[]
   
  -        // retrieve a particular grammar.
  -        // REVISIT:  does this need to be synchronized since it's just reading?
  -        // @param gDesc description of the grammar to be retrieved
  -        // @return Grammar corresponding to gDesc, or null if none exists.
  +        /**
  +         * Retrieve a particular grammar.
  +         * REVISIT:  does this need to be synchronized since it's just reading?
  +         *
  +         * @param gDesc Description of the grammar to be retrieved
  +         * @return      Grammar corresponding to gDesc, or null if none exists.
  +         */
           public Grammar retrieveGrammar(XMLGrammarDescription gDesc) {
               Grammar g = super.retrieveGrammar(gDesc);
               if(g != null) return g;
               return fGrammarPool.retrieveGrammar(gDesc);
           } // retrieveGrammar(XMLGrammarDesc):  Grammar
   
  -        // give the grammarPool the option of caching these grammars.
  -        // This certainly must be synchronized.
  -        // @param grammarType The type of the grammars to be cached.
  -        // @param grammars the Grammars that may be cached (unordered, Grammars previously
  -        //  given to the validator may be included).
  +        /** 
  +         * Give the grammarPool the option of caching these grammars.
  +         * This certainly must be synchronized.
  +         * 
  +         * @param grammarType The type of the grammars to be cached.
  +         * @param grammars    The Grammars that may be cached (unordered, Grammars previously
  +         *  		      given to the validator may be included).
  +         */
           public void cacheGrammars(String grammarType, Grammar[] grammars) { 
              // better give both grammars a shot...
              super.cacheGrammars(grammarType, grammars);
  @@ -503,28 +511,28 @@
           } // cacheGrammars(grammarType, Grammar[]);
   
           /**
  -         * Returns the grammar associated to the specified key.
  +         * Returns the grammar associated to the specified description.
            * 
  -         * @param key The key of the grammar.
  +         * @param desc The description of the grammar.
            */
  -        public Grammar getGrammar(String key) {
  +        public Grammar getGrammar(XMLGrammarDescription desc) {
   
  -            if (super.containsGrammar(key)) {
  -                return super.getGrammar(key);
  +            if (super.containsGrammar(desc)) {
  +                return super.getGrammar(desc);
               }
               return null;
   
  -        } // getGrammar(String):Grammar
  +        } // getGrammar(XMLGrammarDescription):Grammar
   
           /**
            * Returns true if the grammar pool contains a grammar associated
  -         * to the specified key.
  +         * to the specified description.
            *
  -         * @param key The key of the grammar.
  +         * @param desc The description of the grammar.
            */
  -        public boolean containsGrammar(String key) {
  -            return super.containsGrammar(key);
  -        } // containsGrammar(String):boolean
  +        public boolean containsGrammar(XMLGrammarDescription desc) {
  +            return super.containsGrammar(desc);
  +        } // containsGrammar(XMLGrammarDescription):boolean
   
       } // class ShadowedGrammarPool
   
  
  
  
  1.10      +15 -14    xml-xerces/java/src/org/apache/xerces/parsers/DOMASBuilderImpl.java
  
  Index: DOMASBuilderImpl.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/parsers/DOMASBuilderImpl.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- DOMASBuilderImpl.java	4 Feb 2002 05:34:19 -0000	1.9
  +++ DOMASBuilderImpl.java	19 Feb 2002 21:03:39 -0000	1.10
  @@ -80,6 +80,7 @@
   import org.apache.xerces.xni.parser.XMLParserConfiguration;
   
   import org.apache.xerces.xni.grammars.XMLGrammarPool;
  +import org.apache.xerces.xni.grammars.Grammar;
   import org.apache.xerces.impl.validation.XMLGrammarPoolImpl;
   import org.apache.xerces.impl.xs.traversers.XSDHandler;
   import org.apache.xerces.impl.xs.XSDDescription;
  @@ -105,7 +106,7 @@
    *
    * @author Pavani Mukthipudi, Sun Microsystems Inc.
    * @author Neil Graham, IBM
  - * @version $Id: DOMASBuilderImpl.java,v 1.9 2002/02/04 05:34:19 edwingo Exp $
  + * @version $Id: DOMASBuilderImpl.java,v 1.10 2002/02/19 21:03:39 neeraj Exp $
    *
    */
   
  @@ -216,7 +217,9 @@
           if (fGrammarPool == null) {
               fGrammarPool = (XMLGrammarPool)fConfiguration.getProperty(StandardParserConfiguration.XMLGRAMMAR_POOL);
           }
  -        initGrammarPool(fAbstractSchema);
  +        if (fAbstractSchema != null) {
  +            initGrammarPool(fAbstractSchema);
  +        }
       }
   
   
  @@ -344,7 +347,7 @@
   
          initGrammarBucket();
          fSubGroupHandler.reset();
  -       fSchemaHandler.reset(fErrorReporter, fEntityResolver, fSymbolTable, externalSchemas, noNamespaceExternalSchemas, null);
  +       fSchemaHandler.reset(fErrorReporter, fEntityResolver, fSymbolTable, externalSchemas, noNamespaceExternalSchemas, null, fGrammarPool);
   
          // Should check whether the grammar with this namespace is already in
          // the grammar resolver. But since we don't know the target namespace
  @@ -388,17 +391,15 @@
   
       private void initGrammarPool(ASModelImpl currModel) {
           // put all the grammars in fAbstractSchema into the grammar pool.
  -        // REVISIT:  straighten this out when grammar caching's properly implemented!
  -        if(!(fGrammarPool instanceof XMLGrammarPoolImpl)) return;
  -        XMLGrammarPoolImpl poolImpl = (XMLGrammarPoolImpl)fGrammarPool;
  -        SchemaGrammar grammar = null;
  -        if((grammar = currModel.getGrammar()) != null) {
  -            String tns = grammar.getTargetNamespace();
  -            poolImpl.putGrammarNS(tns, grammar);
  -        }
  -        Vector modelStore = currModel.getInternalASModels();
  -        for (int i = 0; i < modelStore.size(); i++) {
  -            initGrammarPool((ASModelImpl)modelStore.elementAt(i));
  +        if (fGrammarPool != null) {
  +            Grammar[] grammars = new Grammar[1];
  +            if ((grammars[0] = (Grammar)currModel.getGrammar()) != null) {
  +            	fGrammarPool.cacheGrammars(grammars[0].getGrammarDescription().getGrammarType(), grammars);
  +            }
  +            Vector modelStore = currModel.getInternalASModels();
  +            for (int i = 0; i < modelStore.size(); i++) {
  +            	initGrammarPool((ASModelImpl)modelStore.elementAt(i));
  +            }
           }
       }
   } // class DOMASBuilderImpl
  
  
  
  1.21      +13 -3     xml-xerces/java/src/org/apache/xerces/parsers/StandardParserConfiguration.java
  
  Index: StandardParserConfiguration.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/parsers/StandardParserConfiguration.java,v
  retrieving revision 1.20
  retrieving revision 1.21
  diff -u -r1.20 -r1.21
  --- StandardParserConfiguration.java	15 Feb 2002 16:00:30 -0000	1.20
  +++ StandardParserConfiguration.java	19 Feb 2002 21:03:39 -0000	1.21
  @@ -121,7 +121,7 @@
    * @author Arnaud  Le Hors, IBM
    * @author Andy Clark, IBM
    *
  - * @version $Id: StandardParserConfiguration.java,v 1.20 2002/02/15 16:00:30 sandygao Exp $
  + * @version $Id: StandardParserConfiguration.java,v 1.21 2002/02/19 21:03:39 neeraj Exp $
    */
   public class StandardParserConfiguration
       extends BasicParserConfiguration 
  @@ -355,12 +355,17 @@
           };
           addRecognizedProperties(recognizedProperties);
   
  +	/** //REVISIT: why to create a pool.. when application doesn't want it to create -nb
           // create and register missing components
           if (grammarPool == null) {
               grammarPool = new XMLGrammarPoolImpl();
           }
  +	*/
  +	
           fGrammarPool = grammarPool;
  -        setProperty(XMLGRAMMAR_POOL, fGrammarPool);
  +        if(fGrammarPool != null){
  +        	setProperty(XMLGRAMMAR_POOL, fGrammarPool);
  +        }
   
           fEntityManager = createEntityManager();
           setProperty(ENTITY_MANAGER, fEntityManager);
  @@ -588,7 +593,12 @@
               if (PRINT_EXCEPTION_STACK_TRACE)
                   ex.printStackTrace();
               throw ex;
  -        } 
  +        }
  +        catch (RuntimeException ex) {
  +            if (PRINT_EXCEPTION_STACK_TRACE)
  +                ex.printStackTrace();
  +            throw ex;
  +        }              
           catch (Exception ex) {
               if (PRINT_EXCEPTION_STACK_TRACE)
                   ex.printStackTrace();
  
  
  
  1.3       +2 -2      xml-xerces/java/src/org/apache/xerces/parsers/XMLGrammarCachingConfiguration.java
  
  Index: XMLGrammarCachingConfiguration.java
  ===================================================================
  RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/parsers/XMLGrammarCachingConfiguration.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- XMLGrammarCachingConfiguration.java	9 Feb 2002 20:55:21 -0000	1.2
  +++ XMLGrammarCachingConfiguration.java	19 Feb 2002 21:03:39 -0000	1.3
  @@ -104,7 +104,7 @@
    *
    * @author Neil Graham, IBM
    *
  - * @version $Id: XMLGrammarCachingConfiguration.java,v 1.2 2002/02/09 20:55:21 neilg Exp $
  + * @version $Id: XMLGrammarCachingConfiguration.java,v 1.3 2002/02/19 21:03:39 neeraj Exp $
    */
   public class XMLGrammarCachingConfiguration 
       extends StandardParserConfiguration {
  @@ -301,7 +301,7 @@
          for(int i=0; i<grammars.length; i++ )
               fXSGrammarBucket.putGrammar(grammars[i]);
          fSubGroupHandler.reset();
  -       fSchemaHandler.reset(fErrorReporter, fEntityManager, fSymbolTable, externalSchemas, noNamespaceExternalSchemas, null);
  +       fSchemaHandler.reset(fErrorReporter, fEntityManager, fSymbolTable, externalSchemas, noNamespaceExternalSchemas, null, fGrammarPool);
   
          // Should check whether the grammar with this namespace is already in
          // the grammar resolver. But since we don't know the target namespace
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-cvs-help@xml.apache.org