From 23a8874b5e9c6859405ff7d6f9652c59ff957e9f Mon Sep 17 00:00:00 2001
From: Alberto Massari <amassari@apache.org>
Date: Wed, 12 Aug 2009 13:40:40 +0000
Subject: [PATCH] When an identity constraint involves a QName, store the value
 using its Clark name so that values using different prefixes can be matched

git-svn-id: https://svn.apache.org/repos/asf/xerces/c/trunk@803507 13f79535-47bb-0310-9956-ffa450edef68
---
 src/xercesc/internal/IGXMLScanner.cpp         |  3 +
 src/xercesc/internal/SGXMLScanner.cpp         |  3 +
 .../schema/identity/IC_Selector.cpp           | 14 +++--
 .../schema/identity/IC_Selector.hpp           | 18 +++---
 .../identity/IdentityConstraintHandler.cpp    |  9 +--
 .../identity/IdentityConstraintHandler.hpp    |  4 +-
 .../schema/identity/XPathMatcher.cpp          | 58 +++++++++++++++++--
 .../schema/identity/XPathMatcher.hpp          |  7 ++-
 8 files changed, 91 insertions(+), 25 deletions(-)

diff --git a/src/xercesc/internal/IGXMLScanner.cpp b/src/xercesc/internal/IGXMLScanner.cpp
index 9daec7a26..7851f2759 100644
--- a/src/xercesc/internal/IGXMLScanner.cpp
+++ b/src/xercesc/internal/IGXMLScanner.cpp
@@ -1133,6 +1133,7 @@ void IGXMLScanner::scanEndTag(bool& gotData)
                              (
                               (SchemaElementDecl *) topElem->fThisElement
                             , fContent.getRawBuffer()
+                            , fValidationContext
                              );
             }
 
@@ -2605,6 +2606,7 @@ bool IGXMLScanner::scanStartTagNS(bool& gotData)
                         , fPrefixBuf.getRawBuffer()
                         , *fAttrList
                         , attCount
+                        , fValidationContext
                         );
     }
 
@@ -2713,6 +2715,7 @@ bool IGXMLScanner::scanStartTagNS(bool& gotData)
                                    (
                                     (SchemaElementDecl *) elemDecl
                                   , fContent.getRawBuffer()
+                                  , fValidationContext
                                    );
                 }
 
diff --git a/src/xercesc/internal/SGXMLScanner.cpp b/src/xercesc/internal/SGXMLScanner.cpp
index f5a4fbf19..0b7070fc4 100644
--- a/src/xercesc/internal/SGXMLScanner.cpp
+++ b/src/xercesc/internal/SGXMLScanner.cpp
@@ -981,6 +981,7 @@ void SGXMLScanner::scanEndTag(bool& gotData)
                         (
                          (SchemaElementDecl *) topElem->fThisElement
                        , fContent.getRawBuffer()
+                       , fValidationContext
                         );
         }
 
@@ -1602,6 +1603,7 @@ bool SGXMLScanner::scanStartTag(bool& gotData)
                         , fPrefixBuf.getRawBuffer()
                         , *fAttrList
                         , attCount
+                        , fValidationContext
                         );
 
     }
@@ -1709,6 +1711,7 @@ bool SGXMLScanner::scanStartTag(bool& gotData)
                        (
                         (SchemaElementDecl *) elemDecl
                       , fContent.getRawBuffer()
+                      , fValidationContext
                        );
             }
 
diff --git a/src/xercesc/validators/schema/identity/IC_Selector.cpp b/src/xercesc/validators/schema/identity/IC_Selector.cpp
index d42e17653..cb7ec9fc0 100644
--- a/src/xercesc/validators/schema/identity/IC_Selector.cpp
+++ b/src/xercesc/validators/schema/identity/IC_Selector.cpp
@@ -61,9 +61,11 @@ void SelectorMatcher::startElement(const XMLElementDecl& elemDecl,
                                    const unsigned int urlId,
                                    const XMLCh* const elemPrefix,
                                    const RefVectorOf<XMLAttr>& attrList,
-                                   const XMLSize_t attrCount) {
+                                   const XMLSize_t attrCount,
+                                   ValidationContext* validationContext /*=0*/) 
+{
 
-    XPathMatcher::startElement(elemDecl, urlId, elemPrefix, attrList, attrCount);
+    XPathMatcher::startElement(elemDecl, urlId, elemPrefix, attrList, attrCount, validationContext);
     fElementDepth++;
 
     // activate the fields, if selector is matched
@@ -80,15 +82,17 @@ void SelectorMatcher::startElement(const XMLElementDecl& elemDecl,
         for (XMLSize_t i = 0; i < count; i++) {
 
             XPathMatcher* matcher = fFieldActivator->activateField(ic->getFieldAt(i), fInitialDepth);
-            matcher->startElement(elemDecl, urlId, elemPrefix, attrList, attrCount);
+            matcher->startElement(elemDecl, urlId, elemPrefix, attrList, attrCount, validationContext);
         }
     }
 }
 
 void SelectorMatcher::endElement(const XMLElementDecl& elemDecl,
-                                 const XMLCh* const elemContent) {
+                                 const XMLCh* const elemContent, 
+                                 ValidationContext* validationContext /*=0*/) 
+{
 
-    XPathMatcher::endElement(elemDecl, elemContent);
+    XPathMatcher::endElement(elemDecl, elemContent, validationContext);
 
     if (fElementDepth-- == fMatchedDepth) {
 
diff --git a/src/xercesc/validators/schema/identity/IC_Selector.hpp b/src/xercesc/validators/schema/identity/IC_Selector.hpp
index 7c523eb78..635264169 100644
--- a/src/xercesc/validators/schema/identity/IC_Selector.hpp
+++ b/src/xercesc/validators/schema/identity/IC_Selector.hpp
@@ -102,14 +102,16 @@ public:
     // -----------------------------------------------------------------------
     //  XMLDocumentHandler methods
     // -----------------------------------------------------------------------
-    void startDocumentFragment();
-    void startElement(const XMLElementDecl& elemDecl,
-                      const unsigned int urlId,
-                      const XMLCh* const elemPrefix,
-		              const RefVectorOf<XMLAttr>& attrList,
-                      const XMLSize_t attrCount);
-    void endElement(const XMLElementDecl& elemDecl,
-                    const XMLCh* const elemContent);
+    virtual void startDocumentFragment();
+    virtual void startElement(const XMLElementDecl& elemDecl,
+                              const unsigned int urlId,
+                              const XMLCh* const elemPrefix,
+		                      const RefVectorOf<XMLAttr>& attrList,
+                              const XMLSize_t attrCount,
+                              ValidationContext* validationContext = 0);
+    virtual void endElement(const XMLElementDecl& elemDecl,
+                            const XMLCh* const elemContent,
+                            ValidationContext* validationContext = 0);
 
 private:
     // -----------------------------------------------------------------------
diff --git a/src/xercesc/validators/schema/identity/IdentityConstraintHandler.cpp b/src/xercesc/validators/schema/identity/IdentityConstraintHandler.cpp
index 0833970df..d559a2868 100644
--- a/src/xercesc/validators/schema/identity/IdentityConstraintHandler.cpp
+++ b/src/xercesc/validators/schema/identity/IdentityConstraintHandler.cpp
@@ -76,7 +76,8 @@ IdentityConstraintHandler::~IdentityConstraintHandler()
 //  IdentityConstraintHandler:  methods
 // ---------------------------------------------------------------------------
 void IdentityConstraintHandler::deactivateContext(      SchemaElementDecl* const elem
-                                                , const XMLCh*             const content)
+                                                , const XMLCh*             const content
+                                                , ValidationContext*       validationContext /*=0*/)
 {
 
     XMLSize_t oldCount = fMatcherStack->getMatcherCount();
@@ -87,7 +88,7 @@ void IdentityConstraintHandler::deactivateContext(      SchemaElementDecl* const
         for (XMLSize_t i = oldCount; i > 0; i--) 
         {
             XPathMatcher* matcher = fMatcherStack->getMatcherAt(i-1);
-            matcher->endElement(*(elem), content);
+            matcher->endElement(*(elem), content, validationContext);
         }
 
         if (fMatcherStack->size() > 0) 
@@ -136,7 +137,7 @@ void IdentityConstraintHandler::activateIdentityConstraint
                      , const XMLCh*                 const elemPrefix
                      , const RefVectorOf<XMLAttr>&        attrList
                      , const XMLSize_t                    attrCount
-                      )
+                     , ValidationContext*                 validationContext /*=0*/)
 {
 
     XMLSize_t count = elem->getIdentityConstraintCount();
@@ -159,7 +160,7 @@ void IdentityConstraintHandler::activateIdentityConstraint
         for (XMLSize_t j = 0; j < count; j++) 
         {
             XPathMatcher* matcher = fMatcherStack->getMatcherAt(j);
-            matcher->startElement(*elem, uriId, elemPrefix, attrList, attrCount);
+            matcher->startElement(*elem, uriId, elemPrefix, attrList, attrCount, validationContext);
         }
     }
 }
diff --git a/src/xercesc/validators/schema/identity/IdentityConstraintHandler.hpp b/src/xercesc/validators/schema/identity/IdentityConstraintHandler.hpp
index 1811c0c0a..009c71a7b 100644
--- a/src/xercesc/validators/schema/identity/IdentityConstraintHandler.hpp
+++ b/src/xercesc/validators/schema/identity/IdentityConstraintHandler.hpp
@@ -72,7 +72,7 @@ public:
                              (
                                     SchemaElementDecl* const elem
                             , const XMLCh*             const content
-                              );
+                            , ValidationContext*       validationContext = 0);
 
             void         activateIdentityConstraint
                                (
@@ -82,7 +82,7 @@ public:
                              , const XMLCh*                 const elemPrefix
                              , const RefVectorOf<XMLAttr>&        attrList
                              , const XMLSize_t                    attrCount
-                               );
+                             , ValidationContext*                 validationContext = 0 );
 
             void         reset();
 
diff --git a/src/xercesc/validators/schema/identity/XPathMatcher.cpp b/src/xercesc/validators/schema/identity/XPathMatcher.cpp
index 0d49d1f87..004910d87 100644
--- a/src/xercesc/validators/schema/identity/XPathMatcher.cpp
+++ b/src/xercesc/validators/schema/identity/XPathMatcher.cpp
@@ -29,6 +29,7 @@
 #include <xercesc/validators/schema/SchemaSymbols.hpp>
 #include <xercesc/util/RuntimeException.hpp>
 #include <xercesc/util/OutOfMemoryException.hpp>
+#include <xercesc/framework/ValidationContext.hpp>
 
 XERCES_CPP_NAMESPACE_BEGIN
 
@@ -149,7 +150,8 @@ void XPathMatcher::startElement(const XMLElementDecl& elemDecl,
                                 const unsigned int urlId,
                                 const XMLCh* const elemPrefix,
 								const RefVectorOf<XMLAttr>& attrList,
-                                const XMLSize_t attrCount) {
+                                const XMLSize_t attrCount,
+                                ValidationContext* validationContext /*=0*/) {
 
     for (XMLSize_t i = 0; i < fLocationPathSize; i++) {
 
@@ -263,7 +265,31 @@ void XPathMatcher::startElement(const XMLElementDecl& elemDecl,
 
                                 SchemaAttDef* attDef = ((SchemaElementDecl&) elemDecl).getAttDef(curDef->getName(), curDef->getURIId());
                                 DatatypeValidator* dv = (attDef) ? attDef->getDatatypeValidator() : 0;
-                                matched(curDef->getValue(), dv, false);
+                                const XMLCh* value = curDef->getValue();
+                                // store QName using their Clark name
+                                if(dv && dv->getType()==DatatypeValidator::QName)
+                                {
+                                    int index=XMLString::indexOf(value, chColon);
+                                    if(index==-1)
+                                        matched(value, dv, false);
+                                    else
+                                    {
+                                        XMLBuffer buff(1023, fMemoryManager);
+                                        buff.append(chOpenCurly);
+                                        if(validationContext)
+                                        {
+                                            XMLCh* prefix=(XMLCh*)fMemoryManager->allocate((index+1)*sizeof(XMLCh));
+                                            ArrayJanitor<XMLCh> janPrefix(prefix, fMemoryManager);
+                                            XMLString::subString(prefix, value, 0, (XMLSize_t)index, fMemoryManager);
+                                            buff.append(validationContext->getURIForPrefix(prefix));
+                                        }
+                                        buff.append(chCloseCurly);
+                                        buff.append(value+index+1);
+                                        matched(buff.getRawBuffer(), dv, false);
+                                    }
+                                }
+                                else
+                                    matched(value, dv, false);
                             }
                         }
                         break;
@@ -286,7 +312,8 @@ void XPathMatcher::startElement(const XMLElementDecl& elemDecl,
 }
 
 void XPathMatcher::endElement(const XMLElementDecl& elemDecl,
-                              const XMLCh* const elemContent) {
+                              const XMLCh* const elemContent,
+                              ValidationContext* validationContext /*=0*/) {
 
     for(XMLSize_t i = 0; i < fLocationPathSize; i++) {
 
@@ -314,7 +341,30 @@ void XPathMatcher::endElement(const XMLElementDecl& elemDecl,
             DatatypeValidator* dv = ((SchemaElementDecl*) &elemDecl)->getDatatypeValidator();
             bool isNillable = (((SchemaElementDecl *) &elemDecl)->getMiscFlags() & SchemaSymbols::XSD_NILLABLE) != 0;
 
-            matched(elemContent, dv, isNillable);
+            // store QName using their Clark name
+            if(dv && dv->getType()==DatatypeValidator::QName)
+            {
+                int index=XMLString::indexOf(elemContent, chColon);
+                if(index==-1)
+                    matched(elemContent, dv, isNillable);
+                else
+                {
+                    XMLBuffer buff(1023, fMemoryManager);
+                    buff.append(chOpenCurly);
+                    if(validationContext)
+                    {
+                        XMLCh* prefix=(XMLCh*)fMemoryManager->allocate((index+1)*sizeof(XMLCh));
+                        ArrayJanitor<XMLCh> janPrefix(prefix, fMemoryManager);
+                        XMLString::subString(prefix, elemContent, 0, (XMLSize_t)index, fMemoryManager);
+                        buff.append(validationContext->getURIForPrefix(prefix));
+                    }
+                    buff.append(chCloseCurly);
+                    buff.append(elemContent+index+1);
+                    matched(buff.getRawBuffer(), dv, isNillable);
+                }
+            }
+            else
+                matched(elemContent, dv, isNillable);
             fMatched[i] = 0;
         }
     }
diff --git a/src/xercesc/validators/schema/identity/XPathMatcher.hpp b/src/xercesc/validators/schema/identity/XPathMatcher.hpp
index bde58e2b9..cbb80f3bc 100644
--- a/src/xercesc/validators/schema/identity/XPathMatcher.hpp
+++ b/src/xercesc/validators/schema/identity/XPathMatcher.hpp
@@ -44,6 +44,7 @@ class XercesLocationPath;
 class XMLAttr;
 class XercesNodeTest;
 class QName;
+class ValidationContext;
 
 class VALIDATORS_EXPORT XPathMatcher : public XMemory
 {
@@ -81,9 +82,11 @@ public:
                               const unsigned int urlId,
                               const XMLCh* const elemPrefix,
                               const RefVectorOf<XMLAttr>& attrList,
-                              const XMLSize_t attrCount);
+                              const XMLSize_t attrCount,
+                              ValidationContext* validationContext = 0);
     virtual void endElement(const XMLElementDecl& elemDecl,
-                            const XMLCh* const elemContent);
+                            const XMLCh* const elemContent,
+                            ValidationContext* validationContext = 0);
 
     enum
     {
-- 
GitLab