Bladeren bron

Merge branch 'jira12246' into candidate-5.0.4

Signed-off-by: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 10 jaren geleden
bovenliggende
commit
d68b35e3e0
3 gewijzigde bestanden met toevoegingen van 227 en 37 verwijderingen
  1. 6 0
      esp/tools/soapplus/main.cpp
  2. 220 37
      esp/tools/soapplus/xmldiff.cpp
  3. 1 0
      esp/tools/soapplus/xmldiff.hpp

+ 6 - 0
esp/tools/soapplus/main.cpp

@@ -69,6 +69,7 @@ void usage()
     puts("   -gf : the output filename for generated message");
     puts("   -delay <min-milli-seconds> <max-milli-seconds> : randomly delay between requests in stress test. By default requests are sent without stop.");
     puts("   -ooo : the 2 input files to diff are Out-Of-Order, so do the best-match calculation while comparing them. (this will slow it down dramatically for big xml files).");
+    puts("   -ordsen : order sensitive. Even if there're matching tags, but if the tags in the files are not in the same order, they'll be deemed different.");
     puts("   -y: use default answers to yes or no prompts.");
     puts("   -wiz: ECL to ESP wizard mode.");
     puts("   -soapaction <url>: specify the soapaction.");
@@ -673,6 +674,11 @@ int main(int argc, char** argv)
             globals->setProp("ooo", "1");
             i++;
         }
+        else if(stricmp(argv[i], "-ordsen") == 0)
+        {
+            globals->setProp("ordsen", "1");
+            i++;
+        }
         else if(stricmp(argv[i], "-wiz") == 0)
         {
             i++;

+ 220 - 37
esp/tools/soapplus/xmldiff.cpp

@@ -23,6 +23,16 @@
 
 #include "jliball.hpp"
 
+static int compInt(const int* a, const int* b)
+{
+    if(*a == *b)
+        return 0;
+    else if(*a > *b)
+        return 1;
+    else 
+        return -1;
+}
+
 CXmlDiff::CXmlDiff(IProperties* globals, const char* left, const char* right, IPropertyTree* cfgtree)
 {
     m_globals = globals;
@@ -42,6 +52,11 @@ CXmlDiff::CXmlDiff(IProperties* globals, const char* left, const char* right, IP
     else
         m_ooo = false;
 
+    if(globals && globals->hasProp("ordsen"))
+        m_ordsen = true;
+    else
+        m_ordsen = false;
+
     if(cfgtree)
     {
         Owned<IPropertyTreeIterator> xpaths = m_cfgtree->getElements("Ignore/XPath");
@@ -371,6 +386,7 @@ bool CXmlDiff::cmpPtree(const char* xpath, IPropertyTree* t1, IPropertyTree* t2,
     }
 
     bool isDS = isDataset(xpath);
+    ArrayOf<int> A;
     if(t1->hasChildren() && t2->hasChildren())
     {
         int num1 = t1->numChildren();
@@ -453,6 +469,7 @@ bool CXmlDiff::cmpPtree(const char* xpath, IPropertyTree* t1, IPropertyTree* t2,
                                 else
                                 {
                                     foundmatch = true;
+                                    A.append(j);
                                     ptrs1[i] = NULL;
                                     ptrs2[j] = NULL;
                                     break;
@@ -466,6 +483,7 @@ bool CXmlDiff::cmpPtree(const char* xpath, IPropertyTree* t1, IPropertyTree* t2,
                                 ptrs1[i] = NULL;
                                 ptrs2[j] = NULL;
                                 foundmatch = true;
+                                A.append(j);
                                 break;
                             }
                         }
@@ -506,8 +524,24 @@ bool CXmlDiff::cmpPtree(const char* xpath, IPropertyTree* t1, IPropertyTree* t2,
 
         delete[] ptrs1;
         delete[] ptrs2;
-        m_compcache.setValue(keybuf,true);
-        return true;
+
+        bool cmpResult = true;
+        if(m_ordsen)
+        {
+            ArrayOf<int> B;
+            ForEachItemIn(x, A)
+                B.append(x);
+            B.sort(compInt);
+            for(unsigned int k = 0; k < A.length(); k++)
+                if(A[k] != B[k])
+                {
+                    cmpResult = false;
+                    break;
+                }
+        }
+
+        m_compcache.setValue(keybuf,cmpResult);
+        return cmpResult;
     }
     else if((t1->hasChildren() && !t2->hasChildren()) || (!t1->hasChildren() && t2->hasChildren()))
     {
@@ -917,61 +951,210 @@ bool CXmlDiff::diffPtree(const char* xpath, IPropertyTree* t1, IPropertyTree* t2
             }
         }
 
-        for(i = 0; i < num1; i++)
+        if(m_ordsen)
         {
-            if(!ptrs1[i])
-                continue;
-            const char* name1 = ptrs1[i]->queryName();
+            IPropertyTree** tmpptrs1 = new IPropertyTree*[num1];
+            IPropertyTree** tmpptrs2 = new IPropertyTree*[num2];
+            int i;
+            for(i = 0; i < num1; i++)
+                tmpptrs1[i] = ptrs1[i];
+            for(i = 0; i < num2; i++)
+            tmpptrs2[i] = ptrs2[i];
+            ArrayOf<int> A;
+            for(i = 0; i < num1; i++)
+            {
+                if(!tmpptrs1[i])
+                    continue;
+                const char* name1 = tmpptrs1[i]->queryName();
 
-            const char* did = NULL;
-            if(isDS && stricmp(name1, "Row") == 0 && ptrs1[i]->hasProp("did"))
+                const char* did = NULL;
+                if(isDS && stricmp(name1, "Row") == 0 && tmpptrs1[i]->hasProp("did"))
+                {
+                    did = tmpptrs1[i]->queryProp("did");
+                }
+
+                for(int j = 0; j < num2; j++)
+                {
+                    if(tmpptrs2[j])
+                    {
+                        const char* name2 = tmpptrs2[j]->queryName();
+                        if(name1 && name2 && strcmp(name1, name2) == 0)
+                        {
+                            StringBuffer xpathbuf(xpath);
+                            xpathbuf.append("/").append(name1);
+                            
+                            StringBuffer xpathFullBuf(xpathFull);
+                            xpathFullBuf.append("/").append(name1);
+                            StringBuffer attrString;
+                            getAttrString(tmpptrs2[j], attrString);
+                            if(attrString.length())
+                                xpathFullBuf.appendf("[%s]", attrString.str());
+
+                            if(did && *did)
+                            {
+                                const char* did2 = tmpptrs2[j]->queryProp("did");
+                                if(did2 && *did2 && strcmp(did, did2) == 0)
+                                {
+                                    tmpptrs1[i] = NULL;
+                                    tmpptrs2[j] = NULL;
+                                    A.append(j);
+                                    break;
+                                }
+                            }
+                            else
+                            {
+                                bool isEqual = cmpPtree(xpathbuf.str(), tmpptrs1[i], tmpptrs2[j], xpathFullBuf.str());
+                                if(isEqual)
+                                {
+                                    tmpptrs1[i] = NULL;
+                                    tmpptrs2[j] = NULL;
+                                    A.append(j);
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            delete[] tmpptrs1;
+            delete[] tmpptrs2;
+
+            ArrayOf<int> B;
+            for(unsigned k = 0; k < A.length(); k++)
             {
-                did = ptrs1[i]->queryProp("did");
+                B.append(A[k]);
+            }
+            B.sort(compInt);
+            //printf("--------------\n");
+            for(unsigned k = 0; k < B.length(); k++)
+            {
+                //printf("%d %d\n", A[k], B[k]);
+                if(A.item(k) != B.item(k))
+                    A[k] = -1;
             }
 
-            for(int j = 0; j < num2; j++)
+            int ind = 0;
+            for(i = 0; i < num1; i++)
             {
-                if(ptrs2[j])
+                if(!ptrs1[i])
+                    continue;
+                const char* name1 = ptrs1[i]->queryName();
+
+                const char* did = NULL;
+                if(isDS && stricmp(name1, "Row") == 0 && ptrs1[i]->hasProp("did"))
                 {
-                    const char* name2 = ptrs2[j]->queryName();
-                    if(name1 && name2 && strcmp(name1, name2) == 0)
-                    {
-                        StringBuffer xpathbuf(xpath);
-                        xpathbuf.append("/").append(name1);
-                        
-                        StringBuffer xpathFullBuf(xpathFull);
-                        xpathFullBuf.append("/").append(name1);
-                        StringBuffer attrString;
-                        getAttrString(ptrs2[j], attrString);
-                        if(attrString.length())
-                            xpathFullBuf.appendf("[%s]", attrString.str());
+                    did = ptrs1[i]->queryProp("did");
+                }
 
-                        if(did && *did)
+                for(int j = 0; j < num2; j++)
+                {
+                    if(ptrs2[j])
+                    {
+                        const char* name2 = ptrs2[j]->queryName();
+                        if(name1 && name2 && strcmp(name1, name2) == 0)
                         {
-                            const char* did2 = ptrs2[j]->queryProp("did");
-                            if(did2 && *did2 && strcmp(did, did2) == 0)
+                            StringBuffer xpathbuf(xpath);
+                            xpathbuf.append("/").append(name1);
+                            
+                            StringBuffer xpathFullBuf(xpathFull);
+                            xpathFullBuf.append("/").append(name1);
+                            StringBuffer attrString;
+                            getAttrString(ptrs2[j], attrString);
+                            if(attrString.length())
+                                xpathFullBuf.appendf("[%s]", attrString.str());
+
+                            if(did && *did)
                             {
-                                diffPtree(xpathbuf.str(), ptrs1[i], ptrs2[j], xpathFullBuf.str());
-                                ptrs1[i] = NULL;
-                                ptrs2[j] = NULL;
-                                break;
+                                const char* did2 = ptrs2[j]->queryProp("did");
+                                if(did2 && *did2 && strcmp(did, did2) == 0)
+                                {
+                                    if(A[ind] != -1)
+                                    {
+                                        diffPtree(xpathbuf.str(), ptrs1[i], ptrs2[j], xpathFullBuf.str());
+                                        ptrs1[i] = NULL;
+                                        ptrs2[j] = NULL;
+                                    }
+                                    ind++;
+                                    break;
+                                }
+                            }
+                            else
+                            {
+                                bool isEqual = cmpPtree(xpathbuf.str(), ptrs1[i], ptrs2[j], xpathFullBuf.str());
+                                if(isEqual)
+                                {
+                                    if(A[ind] != -1)
+                                    {
+                                        ptrs1[i] = NULL;
+                                        ptrs2[j] = NULL;
+                                    }
+                                    ind++;
+                                    break;
+                                }
                             }
                         }
-                        else
+                    }
+                }
+            }
+        }
+        else
+        {
+            for(i = 0; i < num1; i++)
+            {
+                if(!ptrs1[i])
+                    continue;
+                const char* name1 = ptrs1[i]->queryName();
+
+                const char* did = NULL;
+                if(isDS && stricmp(name1, "Row") == 0 && ptrs1[i]->hasProp("did"))
+                {
+                    did = ptrs1[i]->queryProp("did");
+                }
+
+                for(int j = 0; j < num2; j++)
+                {
+                    if(ptrs2[j])
+                    {
+                        const char* name2 = ptrs2[j]->queryName();
+                        if(name1 && name2 && strcmp(name1, name2) == 0)
                         {
-                            bool isEqual = cmpPtree(xpathbuf.str(), ptrs1[i], ptrs2[j], xpathFullBuf.str());
-                            if(isEqual)
+                            StringBuffer xpathbuf(xpath);
+                            xpathbuf.append("/").append(name1);
+                            
+                            StringBuffer xpathFullBuf(xpathFull);
+                            xpathFullBuf.append("/").append(name1);
+                            StringBuffer attrString;
+                            getAttrString(ptrs2[j], attrString);
+                            if(attrString.length())
+                                xpathFullBuf.appendf("[%s]", attrString.str());
+
+                            if(did && *did)
                             {
-                                ptrs1[i] = NULL;
-                                ptrs2[j] = NULL;
-                                break;
+                                const char* did2 = ptrs2[j]->queryProp("did");
+                                if(did2 && *did2 && strcmp(did, did2) == 0)
+                                {
+                                    diffPtree(xpathbuf.str(), ptrs1[i], ptrs2[j], xpathFullBuf.str());
+                                    ptrs1[i] = NULL;
+                                    ptrs2[j] = NULL;
+                                    break;
+                                }
+                            }
+                            else
+                            {
+                                bool isEqual = cmpPtree(xpathbuf.str(), ptrs1[i], ptrs2[j], xpathFullBuf.str());
+                                if(isEqual)
+                                {
+                                    ptrs1[i] = NULL;
+                                    ptrs2[j] = NULL;
+                                    break;
+                                }
                             }
                         }
                     }
                 }
             }
         }
-        
+
         int cost = 0;
 
         //calculate cost only if m_difflimit is non-zero

+ 1 - 0
esp/tools/soapplus/xmldiff.hpp

@@ -43,6 +43,7 @@ private:
     MapStringTo<bool> m_compcache;
     int m_difflimit;
     bool m_ooo;
+    bool m_ordsen;
     IProperties* m_globals;
 
     void printPtree(const char* prefix, const char* xpath, IPropertyTree* t, const char* xpathFull);