From 9be69cb7107bb9941d9f3a384467322ec79e87fc Mon Sep 17 00:00:00 2001
From: Boris Kolpackov <borisk@apache.org>
Date: Thu, 19 Nov 2009 14:57:34 +0000
Subject: [PATCH] Implement loading of multiple schemas with the same namespace
 in loadGrammar() when multi-import is enabled.

git-svn-id: https://svn.apache.org/repos/asf/xerces/c/trunk@882166 13f79535-47bb-0310-9956-ffa450edef68
---
 src/xercesc/internal/IGXMLScanner2.cpp | 27 ++++++++++++++++++++------
 src/xercesc/internal/SGXMLScanner.cpp  | 24 ++++++++++++++++++-----
 2 files changed, 40 insertions(+), 11 deletions(-)

diff --git a/src/xercesc/internal/IGXMLScanner2.cpp b/src/xercesc/internal/IGXMLScanner2.cpp
index 33f06fbcf..8717f81b9 100644
--- a/src/xercesc/internal/IGXMLScanner2.cpp
+++ b/src/xercesc/internal/IGXMLScanner2.cpp
@@ -2035,7 +2035,7 @@ InputSource* IGXMLScanner::resolveSystemId(const XMLCh* const sysId
 //  IGXMLScanner: Private grammar preparsing methods
 // ---------------------------------------------------------------------------
 Grammar* IGXMLScanner::loadXMLSchemaGrammar(const InputSource& src,
-                                          const bool toCache)
+                                            const bool toCache)
 {
    // Reset the validators
     fSchemaValidator->reset();
@@ -2080,8 +2080,21 @@ Grammar* IGXMLScanner::loadXMLSchemaGrammar(const InputSource& src,
         DOMElement* root = document->getDocumentElement();// This is what we pass to TraverserSchema
         if (root != 0)
         {
-            SchemaGrammar* grammar = new (fGrammarPoolMemoryManager) SchemaGrammar(fGrammarPoolMemoryManager);
-            XMLSchemaDescription* gramDesc = (XMLSchemaDescription*) grammar->getGrammarDescription();
+            const XMLCh* nsUri = root->getAttribute(SchemaSymbols::fgATT_TARGETNAMESPACE);
+            Grammar* grammar = fGrammarResolver->getGrammar(nsUri);
+
+            bool grammarFound = grammar &&
+              grammar->getGrammarType() == Grammar::SchemaGrammarType &&
+              getHandleMultipleImports();
+
+            SchemaGrammar* schemaGrammar;
+
+            if (grammarFound)
+              schemaGrammar = (SchemaGrammar*) grammar;
+            else
+              schemaGrammar = new (fGrammarPoolMemoryManager) SchemaGrammar(fGrammarPoolMemoryManager);
+
+            XMLSchemaDescription* gramDesc = (XMLSchemaDescription*) schemaGrammar->getGrammarDescription();
             gramDesc->setContextType(XMLSchemaDescription::CONTEXT_PREPARSE);
             gramDesc->setLocationHints(src.getSystemId());
 
@@ -2089,28 +2102,30 @@ Grammar* IGXMLScanner::loadXMLSchemaGrammar(const InputSource& src,
             (
                 root
                 , fURIStringPool
-                , grammar
+                , schemaGrammar
                 , fGrammarResolver
                 , this
                 , src.getSystemId()
                 , fEntityHandler
                 , fErrorReporter
                 , fMemoryManager
+                , grammarFound
             );
 
             if (fValidate) {
                 //  validate the Schema scan so far
-                fValidator->setGrammar(grammar);
+                fValidator->setGrammar(schemaGrammar);
                 fValidator->preContentValidation(false, true);
             }
 
             if (toCache) {
                 fGrammarResolver->cacheGrammars();
             }
+
             if(getPSVIHandler())
                 fModel = fGrammarResolver->getXSModel();
 
-            return grammar;
+            return schemaGrammar;
         }
     }
 
diff --git a/src/xercesc/internal/SGXMLScanner.cpp b/src/xercesc/internal/SGXMLScanner.cpp
index c0d9f36f9..46b366809 100644
--- a/src/xercesc/internal/SGXMLScanner.cpp
+++ b/src/xercesc/internal/SGXMLScanner.cpp
@@ -3856,8 +3856,21 @@ Grammar* SGXMLScanner::loadXMLSchemaGrammar(const InputSource& src,
         DOMElement* root = document->getDocumentElement();// This is what we pass to TraverserSchema
         if (root != 0)
         {
-            SchemaGrammar* grammar = new (fGrammarPoolMemoryManager) SchemaGrammar(fGrammarPoolMemoryManager);
-            XMLSchemaDescription* gramDesc = (XMLSchemaDescription*) grammar->getGrammarDescription();
+            const XMLCh* nsUri = root->getAttribute(SchemaSymbols::fgATT_TARGETNAMESPACE);
+            Grammar* grammar = fGrammarResolver->getGrammar(nsUri);
+
+            bool grammarFound = grammar &&
+              grammar->getGrammarType() == Grammar::SchemaGrammarType &&
+              getHandleMultipleImports();
+
+            SchemaGrammar* schemaGrammar;
+
+            if (grammarFound)
+              schemaGrammar = (SchemaGrammar*) grammar;
+            else
+              schemaGrammar = new (fGrammarPoolMemoryManager) SchemaGrammar(fGrammarPoolMemoryManager);
+
+            XMLSchemaDescription* gramDesc = (XMLSchemaDescription*) schemaGrammar->getGrammarDescription();
             gramDesc->setContextType(XMLSchemaDescription::CONTEXT_PREPARSE);
             gramDesc->setLocationHints(src.getSystemId());
 
@@ -3865,18 +3878,19 @@ Grammar* SGXMLScanner::loadXMLSchemaGrammar(const InputSource& src,
             (
                 root
                 , fURIStringPool
-                , (SchemaGrammar*) grammar
+                , schemaGrammar
                 , fGrammarResolver
                 , this
                 , src.getSystemId()
                 , fEntityHandler
                 , fErrorReporter
                 , fMemoryManager
+                , grammarFound
             );
 
             if (fValidate) {
                 //  validate the Schema scan so far
-                fValidator->setGrammar(grammar);
+                fValidator->setGrammar(schemaGrammar);
                 fValidator->preContentValidation(false, true);
             }
 
@@ -3887,7 +3901,7 @@ Grammar* SGXMLScanner::loadXMLSchemaGrammar(const InputSource& src,
             if(getPSVIHandler())
                 fModel = fGrammarResolver->getXSModel();
 
-            return grammar;
+            return schemaGrammar;
         }
     }
 
-- 
GitLab