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]