Author: robbinspg
Date: Tue Nov 21 13:14:54 2006
New Revision: 477891

URL: http://svn.apache.org/viewvc?view=rev&rev=477891
Log:
TUSCANY-908 - Apply Simon Law's patch (re-factored by Geoff)

Modified:
    incubator/tuscany/cpp/sdo/runtime/core/src/commonj/sdo/PropertySetting.cpp
    incubator/tuscany/cpp/sdo/runtime/core/src/commonj/sdo/PropertySetting.h
    incubator/tuscany/cpp/sdo/runtime/core/src/commonj/sdo/SAX2Parser.cpp
    incubator/tuscany/cpp/sdo/runtime/core/src/commonj/sdo/SDOSAX2Parser.cpp
    incubator/tuscany/cpp/sdo/runtime/core/src/commonj/sdo/SDOXMLWriter.cpp
    incubator/tuscany/cpp/sdo/runtime/core/src/commonj/sdo/SDOXMLWriter.h
    incubator/tuscany/cpp/sdo/runtime/core/test/main.cpp
    incubator/tuscany/cpp/sdo/runtime/core/test/sdotest.cpp
    incubator/tuscany/cpp/sdo/runtime/core/test/sdotest.h

Modified: 
incubator/tuscany/cpp/sdo/runtime/core/src/commonj/sdo/PropertySetting.cpp
URL: 
http://svn.apache.org/viewvc/incubator/tuscany/cpp/sdo/runtime/core/src/commonj/sdo/PropertySetting.cpp?view=diff&rev=477891&r1=477890&r2=477891
==============================================================================
--- incubator/tuscany/cpp/sdo/runtime/core/src/commonj/sdo/PropertySetting.cpp 
(original)
+++ incubator/tuscany/cpp/sdo/runtime/core/src/commonj/sdo/PropertySetting.cpp 
Tue Nov 21 13:14:54 2006
@@ -20,10 +20,17 @@
 /* $Rev$ $Date$ */
 
 #include "commonj/sdo/PropertySetting.h"
+#include "SDOString.h"
+
 namespace commonj
 {
     namespace sdo
     {
+        const char *PropertySetting::CDataStartMarker    = "[EMAIL PROTECTED]";
+        const char *PropertySetting::XMLCDataStartMarker = "<![CDATA[";
+        const char *PropertySetting::CDataEndMarker      = "[EMAIL PROTECTED]";
+        const char *PropertySetting::XMLCDataEndMarker   = "]]>";
+
         PropertySetting::PropertySetting()
             : dataObject(NULL), isNULL(false), isIDREF(false), 
pendingUnknownType(false)
 
@@ -36,9 +43,64 @@
         {
         }
 
-        PropertySetting::~PropertySetting()
-        {
-        }
+       PropertySetting::~PropertySetting()
+       {
+       }
+
+       /*
+        * A local utility function that replaces one string with and another 
within a
+        * host string and adjusts the lenght of the host string accordingly.
+        */ 
+       SDOString replace(SDOString hostString, const char *fromString, const 
char *toString)
+       {
+          SDOString returnString("");
+
+          // find and replace all occurances of fromString with toString. The 
start, end
+          // and length variables are used to indicate the start, end and 
length
+          // of the text sections to be copied from the host string to the 
return
+          // string. toString is appended in between these copied sections 
because the
+          // string is broken whenever fronString is found
+          std::string::size_type start  = 0;
+          std::string::size_type end    = hostString.find(fromString, 0);
+          std::string::size_type length = 0;
+
+          while ( end != std::string::npos )
+          {
+             // copy all the text up to the fromString
+             length = end - start;
+             returnString.append(hostString.substr(start, length));
+
+             // add in the toString
+             returnString.append(toString);
+
+             // find the next fromString
+             start = end + strlen(fromString);
+             end = hostString.find(fromString, start);
+          }
+
+          // copy any text left at the end of the host string
+          returnString.append(hostString.substr(start));
+
+          return returnString;
+       }
+
+       /*
+        * The value that PropertySetting uses to hold values passing from 
+        * an input XML stream to data object properties is currently an 
SDOXMLString
+        * SDOXMLString use libxml2 functions to do it's thing and in the 
process messes
+        * up CDATA markers. To avoid this we use our own version of CDATA 
makers and 
+        * use this method to replace them with the real ones just before the 
PropertSetting
+        * gets committed to the SDO proper in SDOSAX2Parser
+        */
+       SDOString PropertySetting::getStringWithCDataMarkers()
+       {
+          SDOString valueString((const char*)value);
+                        
+          SDOString returnString = replace(valueString, CDataStartMarker, 
XMLCDataStartMarker);
+          returnString = replace(returnString, CDataEndMarker, 
XMLCDataEndMarker);
+
+          return returnString;
+       }
         
     } // End - namespace sdo
 } // End - namespace commonj

Modified: 
incubator/tuscany/cpp/sdo/runtime/core/src/commonj/sdo/PropertySetting.h
URL: 
http://svn.apache.org/viewvc/incubator/tuscany/cpp/sdo/runtime/core/src/commonj/sdo/PropertySetting.h?view=diff&rev=477891&r1=477890&r2=477891
==============================================================================
--- incubator/tuscany/cpp/sdo/runtime/core/src/commonj/sdo/PropertySetting.h 
(original)
+++ incubator/tuscany/cpp/sdo/runtime/core/src/commonj/sdo/PropertySetting.h 
Tue Nov 21 13:14:54 2006
@@ -47,6 +47,8 @@
                 bool isNull=false,
                 bool isIDREF=false);
             virtual ~PropertySetting();
+
+            SDOString getStringWithCDataMarkers();
             
             SDOXMLString name;    
             SDOXMLString value;
@@ -54,7 +56,17 @@
             bool isIDREF;
             bool isNULL;
             bool pendingUnknownType;
-                        
+
+            /*
+             * Markers used to represent the start and end of CDATA sections 
in the 
+             * settings value. The noew XML CDATA markers are not used here 
because the 
+             * XML string processing URL encodes parts of the markers
+             */
+            static SDO_API const char *CDataStartMarker;
+            static SDO_API const char *XMLCDataStartMarker;
+            static SDO_API const char *CDataEndMarker;
+            static SDO_API const char *XMLCDataEndMarker;
+
         };
     } // End - namespace sdo
 } // End - namespace commonj

Modified: incubator/tuscany/cpp/sdo/runtime/core/src/commonj/sdo/SAX2Parser.cpp
URL: 
http://svn.apache.org/viewvc/incubator/tuscany/cpp/sdo/runtime/core/src/commonj/sdo/SAX2Parser.cpp?view=diff&rev=477891&r1=477890&r2=477891
==============================================================================
--- incubator/tuscany/cpp/sdo/runtime/core/src/commonj/sdo/SAX2Parser.cpp 
(original)
+++ incubator/tuscany/cpp/sdo/runtime/core/src/commonj/sdo/SAX2Parser.cpp Tue 
Nov 21 13:14:54 2006
@@ -22,6 +22,7 @@
 #include "commonj/sdo/SAX2Parser.h"
 #include "libxml/SAX2.h"
 #include "commonj/sdo/SDORuntimeException.h"
+#include "commonj/sdo/PropertySetting.h"
 using namespace commonj::sdo;
 
 /**
@@ -167,6 +168,16 @@
 
 void sdo_cdataBlock(void *ctx, const xmlChar *value, int len)
 {
+   if (!((SAX2Parser*)ctx)->parserError) 
+   {
+      SDOXMLString valueAsString(value, 0, len);
+
+      SDOXMLString cdata(PropertySetting::CDataStartMarker);
+      cdata = cdata + valueAsString;
+      cdata = cdata + PropertySetting::CDataEndMarker;
+
+      ((SAX2Parser*)ctx)->characters(cdata);
+   }
 }
 
 void sdo_comment(void *ctx, const xmlChar *value)
@@ -515,4 +526,5 @@
         
     } // End - namespace sdo
 } // End - namespace commonj
+
 

Modified: 
incubator/tuscany/cpp/sdo/runtime/core/src/commonj/sdo/SDOSAX2Parser.cpp
URL: 
http://svn.apache.org/viewvc/incubator/tuscany/cpp/sdo/runtime/core/src/commonj/sdo/SDOSAX2Parser.cpp?view=diff&rev=477891&r1=477890&r2=477891
==============================================================================
--- incubator/tuscany/cpp/sdo/runtime/core/src/commonj/sdo/SDOSAX2Parser.cpp 
(original)
+++ incubator/tuscany/cpp/sdo/runtime/core/src/commonj/sdo/SDOSAX2Parser.cpp 
Tue Nov 21 13:14:54 2006
@@ -1179,13 +1179,13 @@
                                 if 
(currentPropertySetting.dataObject->getType().isSequencedType())
                                 {
                                     SequencePtr seq = 
currentPropertySetting.dataObject->getSequence();
-                                    seq->addCString("value", 
currentPropertySetting.value);
+                                    seq->addCString("value", 
currentPropertySetting.getStringWithCDataMarkers().c_str());
                                 }
                                 else
                                 {
                                     DataObjectList& dl = 
currentPropertySetting.dataObject->
                                     getList((const char*)"value");
-                                    dl.append((const 
char*)currentPropertySetting.value);
+                                    dl.append((const 
char*)currentPropertySetting.getStringWithCDataMarkers().c_str());
                                 }
 
                             }
@@ -1195,12 +1195,13 @@
                                 if 
(currentPropertySetting.dataObject->getType().isSequencedType())
                                 {
                                     SequencePtr seq = 
currentPropertySetting.dataObject->getSequence();
-                                    seq->addCString("value", 
currentPropertySetting.value);
+                                    seq->addCString("value", 
currentPropertySetting.getStringWithCDataMarkers().c_str());
                                 }
                                 else
                                 {
                                     currentPropertySetting.dataObject->
-                                    setCString((const char*)"value", 
currentPropertySetting.value );
+//                                    setCString((const char*)"value", 
currentPropertySetting.value );
+                                    setCString((const char*)"value", 
currentPropertySetting.getStringWithCDataMarkers().c_str() );
                                 }
                             }
                             if (dataObjectStack.size() == 0 || rootDataObject 
== dataObjectStack.top())
@@ -1231,7 +1232,7 @@
                                 if 
(currentPropertySetting.dataObject->getType().isSequencedType())
                                 {
                                     SequencePtr seq = 
currentPropertySetting.dataObject->getSequence();
-                                    
seq->addCString(currentPropertySetting.name, currentPropertySetting.value);
+                                    
seq->addCString(currentPropertySetting.name, 
currentPropertySetting.getStringWithCDataMarkers().c_str());
                                 }
                                 // Always set the property as a String. SDO 
will do the conversion
 
@@ -1244,12 +1245,13 @@
                                     {
                                         DataObjectList& dl = 
currentPropertySetting.dataObject->
                                         getList((const 
char*)currentPropertySetting.name);
-                                        dl.append((const 
char*)currentPropertySetting.value);
+                                        dl.append((const 
char*)currentPropertySetting.getStringWithCDataMarkers().c_str());
                                     }
                                     else
                                     {
                                         currentPropertySetting.dataObject->
-                                        setCString((const 
char*)currentPropertySetting.name, currentPropertySetting.value );
+//                                        setCString((const 
char*)currentPropertySetting.name, currentPropertySetting.value );
+                                        setCString((const 
char*)currentPropertySetting.name, 
currentPropertySetting.getStringWithCDataMarkers().c_str() );
                                     }
                                 }
                             }

Modified: 
incubator/tuscany/cpp/sdo/runtime/core/src/commonj/sdo/SDOXMLWriter.cpp
URL: 
http://svn.apache.org/viewvc/incubator/tuscany/cpp/sdo/runtime/core/src/commonj/sdo/SDOXMLWriter.cpp?view=diff&rev=477891&r1=477890&r2=477891
==============================================================================
--- incubator/tuscany/cpp/sdo/runtime/core/src/commonj/sdo/SDOXMLWriter.cpp 
(original)
+++ incubator/tuscany/cpp/sdo/runtime/core/src/commonj/sdo/SDOXMLWriter.cpp Tue 
Nov 21 13:14:54 2006
@@ -32,6 +32,7 @@
 #include "commonj/sdo/SDORuntimeException.h"
 #include "commonj/sdo/XMLQName.h"
 #include "commonj/sdo/DataObjectImpl.h"
+#include "commonj/sdo/PropertySetting.h"
 
 namespace commonj
 {
@@ -725,12 +726,16 @@
                     rc = xmlTextWriterEndElement(writer);
                 }
                 else
-                {
-                    xmlTextWriterWriteElement(
-                    writer,
-                    elementName,
-                    SDOXMLString(dataObject->getCString("")));
-                }
+                  {
+                    writeXMLElement(writer,
+                                    elementName,
+                                    dataObject->getCString(""));
+                    /*                                      
+                       xmlTextWriterWriteElement(writer,
+                                                 elementName,
+                                                 
SDOXMLString(dataObject->getCString("")));
+                    */
+                  }
 
                 // need to pop stacks before returning
                 //if (!uri.isNull())
@@ -742,7 +747,7 @@
             }
             
 
-                       //namespaceStack.push(namespaces);
+            //namespaceStack.push(namespaces);
 
 
             if (isRoot)
@@ -987,13 +992,13 @@
                             //    prefix = 
namespaces.findPrefix(qname.getURI());
                             //}
 
-                                                       //if (prefix != 0 && 
!(*prefix).equals(""))
+                            //if (prefix != 0 && !(*prefix).equals(""))
 
                             std::map<SDOXMLString,SDOXMLString>::iterator it = 
namespaceMap.find(qname.getURI());
                             if (it != namespaceMap.end())
                             {
-                                                               propertyValue = 
(*it).second + ":" + qname.getLocalName();
-                                                       }
+                              propertyValue = (*it).second + ":" + 
qname.getLocalName();
+                            }
                             else 
                             {
                                 char buffer[20];
@@ -1001,7 +1006,7 @@
                                 sprintf(buffer, "%d", j++);
                                 pref += buffer;
                                 rc = xmlTextWriterWriteAttributeNS(writer, 
-                                                                       
SDOXMLString("xmlns"), pref, NULL, qname.getURI());
+                                                                   
SDOXMLString("xmlns"), pref, NULL, qname.getURI());
                                 propertyValue = pref + ":" + 
qname.getLocalName();
                             }
                             
@@ -1193,10 +1198,16 @@
                                     }
                                     else
                                     {
-                                        xmlTextWriterWriteElement(
-                                        writer,
-                                        propertyName,
-                                        
SDOXMLString(dataObject->getCString(pl[i])));
+                                      writeXMLElement(writer,
+                                                      propertyName,
+                                                      
dataObject->getCString(pl[i]));
+
+
+                                      /*
+                                        xmlTextWriterWriteElement(writer,
+                                                                  propertyName,
+                                                                  
SDOXMLString(dataObject->getCString(pl[i])));
+                                      */
                                     }
                                 }
                             }
@@ -1208,8 +1219,8 @@
             rc = xmlTextWriterEndElement(writer);
             return rc;
 
-                       //namespaces = namespaceStack.top();
-                       //namespaceStack.pop();
+            //namespaces = namespaceStack.top();
+            //namespaceStack.pop();
             //if (!uri.isNull())
             //{
             //    namespaceUriStack.pop();
@@ -1276,7 +1287,74 @@
                 }
             }
         }    
+
+      /**
+       * A wrapper for the libxml2 function xmlTextWriterWriteElement
+       * it detects CDATA sections before wrting out element contents
+       */
+      int SDOXMLWriter::writeXMLElement(xmlTextWriterPtr writer, 
+                                        const xmlChar *name, 
+                                        const char *content)
+      {
+        int rc = 0;
+        rc = xmlTextWriterStartElement(writer, name);
+        rc = xmlTextWriterWriteRaw(writer, SDOXMLString(content));
+        rc = xmlTextWriterEndElement(writer);
+        /* A more complex version that doesn't work!
+           SDOString contentString(content);
+
+           // write the start of the element. we could write a mixture of
+           // text and CDATA before writing the end element
+           rc = xmlTextWriterStartElement(writer, name);
+
+           // Iterate along the string writing out text and CDATA sections 
+           // separately using the appropriate libxml2 calls
+           std::string::size_type start  = 0;
+           std::string::size_type end    = 
contentString.find(PropertySetting::XMLCDataStartMarker, 0);
+           std::string::size_type length = 0;
+                        
+           // loop while we still find a CDATA section that needs writing
+           while ( end != std::string::npos )
+           {
+           // write out text from current pos to start of CDATA section
+           length = end - start;
+           rc = xmlTextWriterWriteString(writer,
+           SDOXMLString(contentString.substr(start, length).c_str()));
+
+           // find the end of the CDATA section
+           start = end;
+           end   = contentString.find(PropertySetting::XMLCDataEndMarker, 
start);
+           
+           if ( end != std::string::npos )
+           {
+           // we only nudge the start marker on to the end of the CDATA marker 
here
+           // so that if we fail to find the end CDATA marker the whole string 
gets 
+           // printed out by virtue of the line that follows the while loop
+           start = start + strlen(PropertySetting::XMLCDataStartMarker);
+           
+           // write our the text from the CDATA section
+           length = end - start;
+           rc = xmlTextWriterWriteCDATA(writer, 
+           SDOXMLString(contentString.substr(start, length).c_str()));
+
+           // set current pos to end of CDATA section and 
+           // start looking for the start marker again
+           start = end + strlen(PropertySetting::XMLCDataEndMarker);
+           end   = contentString.find(PropertySetting::XMLCDataStartMarker, 
start);
+           }
+           } 
+
+           // write out text following the last CDATA section
+           rc = xmlTextWriterWriteString(writer,
+           SDOXMLString(contentString.substr(start).c_str()));
+
+           // close off the element
+           rc = xmlTextWriterEndElement(writer);
+        */
+        return rc;
+      }
         
     } // End - namespace sdo
 } // End - namespace commonj
+
 

Modified: incubator/tuscany/cpp/sdo/runtime/core/src/commonj/sdo/SDOXMLWriter.h
URL: 
http://svn.apache.org/viewvc/incubator/tuscany/cpp/sdo/runtime/core/src/commonj/sdo/SDOXMLWriter.h?view=diff&rev=477891&r1=477890&r2=477891
==============================================================================
--- incubator/tuscany/cpp/sdo/runtime/core/src/commonj/sdo/SDOXMLWriter.h 
(original)
+++ incubator/tuscany/cpp/sdo/runtime/core/src/commonj/sdo/SDOXMLWriter.h Tue 
Nov 21 13:14:54 2006
@@ -92,6 +92,14 @@
                 bool writeXSIType = false,
                 bool isRoot = false);
 
+            /**
+             * A wrapper for the libxml2 function xmlTextWriterWriteElement
+             * it detects CDATA sections before wrting out element contents
+             */
+            int writeXMLElement(xmlTextWriterPtr writer, 
+                                const xmlChar *name, 
+                                const char *content);
+
             SchemaInfo* schemaInfo;
             DataFactoryPtr    dataFactory;
 

Modified: incubator/tuscany/cpp/sdo/runtime/core/test/main.cpp
URL: 
http://svn.apache.org/viewvc/incubator/tuscany/cpp/sdo/runtime/core/test/main.cpp?view=diff&rev=477891&r1=477890&r2=477891
==============================================================================
--- incubator/tuscany/cpp/sdo/runtime/core/test/main.cpp (original)
+++ incubator/tuscany/cpp/sdo/runtime/core/test/main.cpp Tue Nov 21 13:14:54 
2006
@@ -174,7 +174,9 @@
     TEST (  sdotest::jira546() );
     TEST (  sdotest::testXPath() );
 
+    TEST (  sdotest::cdatatest() );
+
     cout << "Total tests:" << totaltests << " Tests passed:" << testspassed << 
endl;
-       return testspassed - totaltests;
+    return testspassed - totaltests;
 }
 }

Modified: incubator/tuscany/cpp/sdo/runtime/core/test/sdotest.cpp
URL: 
http://svn.apache.org/viewvc/incubator/tuscany/cpp/sdo/runtime/core/test/sdotest.cpp?view=diff&rev=477891&r1=477890&r2=477891
==============================================================================
--- incubator/tuscany/cpp/sdo/runtime/core/test/sdotest.cpp (original)
+++ incubator/tuscany/cpp/sdo/runtime/core/test/sdotest.cpp Tue Nov 21 13:14:54 
2006
@@ -9053,3 +9053,74 @@
         return 0;
     }
 }
+
+int sdotest::cdatatest()
+{
+   try 
+   {
+      DataFactoryPtr mdg  = DataFactory::getDataFactory();
+
+      /**
+       * Get an XSD helper to load XSD information into the
+       * data factory
+       */
+      XSDHelperPtr myXSDHelper = HelperProvider::getXSDHelper(mdg);
+      myXSDHelper->defineFile("cdata.xsd");
+
+      /**
+       * Check if there were any errors. The parse may still
+       * succeed, but errors indicate some elements were not
+       * understood 
+       */
+      int i = 0;
+      int j = 0;
+      if ((i = myXSDHelper->getErrorCount()) > 0)
+      {
+        cout << "XSD Loading reported some errors:" << endl;
+        for (j=0;j<i;j++)
+        {
+           const char *m = myXSDHelper->getErrorMessage(j);
+           if (m != 0) cout << m;
+           cout << endl;
+           return 0;
+        }
+      }
+
+      /** 
+       * Use the same data factory to load XML corresponding to
+       * data objects adhering to the previously loaded schema
+       */
+      XMLHelperPtr myXMLHelper = HelperProvider::getXMLHelper(mdg);
+      XMLDocumentPtr myXMLDocument = myXMLHelper->loadFile("cdata-in.xml", 
"http://www.example.org/test";);
+    
+      /**
+       * Check if there were any errors. The parse may still
+       * succeed, but errors indicate some elements did not match
+       * the schema, or were malformed.
+       * 
+       */
+      if ((i = myXMLHelper->getErrorCount()) > 0)
+      {
+        cout << "XML Loading reported some errors:" << endl;
+        for (j=0;j<i;j++)
+        {
+           const char *m = myXMLHelper->getErrorMessage(j);
+           if (m != 0) cout << m;
+           cout << endl;
+           return 0;
+        }
+      }
+
+      // write the XML element back out to a file
+      myXMLHelper->save(myXMLDocument, "cdata-testout.xml");
+
+      return comparefiles("cdata-out.xml","cdata-testout.xml");
+
+   }
+   catch (SDORuntimeException e)
+   {
+      cout << "Exception in interop test" <<  endl;
+      cout << e.getMessageText();
+      return 0;
+   }
+}

Modified: incubator/tuscany/cpp/sdo/runtime/core/test/sdotest.h
URL: 
http://svn.apache.org/viewvc/incubator/tuscany/cpp/sdo/runtime/core/test/sdotest.h?view=diff&rev=477891&r1=477890&r2=477891
==============================================================================
--- incubator/tuscany/cpp/sdo/runtime/core/test/sdotest.h (original)
+++ incubator/tuscany/cpp/sdo/runtime/core/test/sdotest.h Tue Nov 21 13:14:54 
2006
@@ -197,4 +197,5 @@
         static int b46617b();
         static int b45933();
         static int testXPath();
+        static int cdatatest();
 };



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to