summaryrefslogtreecommitdiffstats
path: root/sca-cpp/tags/cpp-0.1.incubating-M1-final/sdo/runtime/core/src/commonj/sdo/SDOXMLWriter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sca-cpp/tags/cpp-0.1.incubating-M1-final/sdo/runtime/core/src/commonj/sdo/SDOXMLWriter.cpp')
-rw-r--r--sca-cpp/tags/cpp-0.1.incubating-M1-final/sdo/runtime/core/src/commonj/sdo/SDOXMLWriter.cpp1171
1 files changed, 1171 insertions, 0 deletions
diff --git a/sca-cpp/tags/cpp-0.1.incubating-M1-final/sdo/runtime/core/src/commonj/sdo/SDOXMLWriter.cpp b/sca-cpp/tags/cpp-0.1.incubating-M1-final/sdo/runtime/core/src/commonj/sdo/SDOXMLWriter.cpp
new file mode 100644
index 0000000000..baf3a762cb
--- /dev/null
+++ b/sca-cpp/tags/cpp-0.1.incubating-M1-final/sdo/runtime/core/src/commonj/sdo/SDOXMLWriter.cpp
@@ -0,0 +1,1171 @@
+/*
+ *
+ * Copyright 2005 The Apache Software Foundation or its licensors, as applicable.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Rev$ $Date: 2006/03/07 15:35:56 $ */
+
+#include "commonj/sdo/SDOXMLWriter.h"
+#include "commonj/sdo/SDOXMLString.h"
+#include "commonj/sdo/SDOString.h"
+#include "iostream"
+using namespace::std;
+#include "commonj/sdo/DASProperty.h"
+#include "commonj/sdo/XSDPropertyInfo.h"
+#include "commonj/sdo/XSDTypeInfo.h"
+#include "commonj/sdo/ChangeSummary.h"
+#include "commonj/sdo/Sequence.h"
+#include "commonj/sdo/SDORuntimeException.h"
+#include "commonj/sdo/XMLQName.h"
+#include "commonj/sdo/DataObjectImpl.h"
+
+namespace commonj
+{
+ namespace sdo
+ {
+
+
+
+
+ SDOXMLWriter::SDOXMLWriter(
+ DataFactoryPtr dataFact)
+ : dataFactory(dataFact)
+ {
+
+ }
+
+ SDOXMLWriter::~SDOXMLWriter()
+ {
+ freeWriter();
+ }
+
+ void SDOXMLWriter::setWriter(xmlTextWriterPtr textWriter)
+ {
+ writer = textWriter;
+ }
+
+ void SDOXMLWriter::freeWriter()
+ {
+ if (writer != NULL)
+ {
+ xmlFreeTextWriter(writer);
+ writer = NULL;
+ }
+ }
+
+ int SDOXMLWriter::write(XMLDocumentPtr doc, int indent)
+ {
+ if (!doc)
+ {
+ return 0;
+ }
+
+ if (writer == NULL)
+ {
+ // Throw exception
+ return -1;
+ }
+
+ int rc = 0;
+
+ //namespaceUriStack.empty();
+ //namespaceUriStack.push(SDOXMLString());
+ //namespaces.empty();
+ //namespaceStack.push(namespaces);
+ namespaceMap.empty();
+
+ if (indent >= 0)
+ {
+ xmlTextWriterSetIndent(writer, 1);
+ if (indent > 0)
+ {
+ char * chars = new char[indent+1];
+ for (int i=0;i<indent;i++)chars[i] = ' ';
+ chars[indent] = 0;
+ xmlTextWriterSetIndentString(writer, SDOXMLString(chars));
+ delete chars;
+ }
+ else
+ {
+ xmlTextWriterSetIndentString(writer, SDOXMLString(""));
+ }
+ }
+
+ if (doc->getXMLDeclaration())
+ {
+ rc = xmlTextWriterStartDocument(writer, doc->getXMLVersion(), doc->getEncoding(), NULL);
+ if (rc < 0) {
+ SDO_THROW_EXCEPTION("write", SDOXMLParserException, "xmlTextWriterStartDocument failed");
+ }
+ }
+
+ DataObjectPtr root = doc->getRootDataObject();
+ if (root)
+ {
+ bool writeXSIType = false;
+ // For the root DataObject we need to determine the element name
+ SDOXMLString elementURI = doc->getRootElementURI();
+ if (elementURI.isNull() || elementURI.equals(""))
+ {
+ elementURI = root->getType().getURI();
+ }
+ SDOXMLString elementName = doc->getRootElementName();
+ if (elementName.isNull() || elementName.equals(""))
+ {
+ elementName = root->getType().getName();
+ elementName = elementName.toLower(0,1);
+ writeXSIType = true;
+ }
+
+ writeDO(root, elementURI, elementName, true, true);
+ }
+ rc = xmlTextWriterEndDocument(writer);
+ if (rc < 0) {
+ SDO_THROW_EXCEPTION("write", SDOXMLParserException, "xmlTextWriterEndDocument failed");
+ return rc;
+ }
+
+ xmlTextWriterFlush(writer);
+ freeWriter();
+
+ return rc;
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Write Change Summary attributes
+ //////////////////////////////////////////////////////////////////////////
+
+ void SDOXMLWriter::handleChangeSummaryAttributes(
+ ChangeSummaryPtr cs,
+ DataObjectPtr dol)
+ {
+ int rc;
+
+ SettingList& sl = cs->getOldValues(dol);
+ if (sl.size() == 0)
+ {
+ // no attributes
+ return;
+ }
+ for (int j=0;j< sl.size(); j++)
+ {
+ try {
+
+ if (sl.get(j)->getProperty().isMany())
+ {
+ // manys are elements
+ continue;
+ }
+
+ if (sl.get(j)->getProperty().getType().isDataType())
+ {
+ // data types are OK
+ rc = xmlTextWriterWriteAttribute(writer,
+ SDOXMLString(sl.get(j)->getProperty().getName()),
+ SDOXMLString(sl.get(j)->getCStringValue()));
+ }
+ else
+ {
+ DataObjectPtr dob = sl.get(j)->getDataObjectValue();
+ if (dob)
+ {
+ if (cs->isDeleted(dob))
+ {
+ rc = xmlTextWriterWriteAttribute(writer,
+ SDOXMLString(sl.get(j)->getProperty().getName()),
+ SDOXMLString(cs->getOldXpath(dob)));
+ }
+ else
+ {
+ rc = xmlTextWriterWriteAttribute(writer,
+ SDOXMLString(sl.get(j)->getProperty().getName()),
+ SDOXMLString(dob->objectToXPath()));
+ }
+ }
+ else
+ {
+ rc = xmlTextWriterWriteAttribute(writer,
+ SDOXMLString(sl.get(j)->getProperty().getName()),
+ SDOXMLString(""));
+ }
+ }
+ }
+ catch (SDORuntimeException e)
+ {
+ // ignore this attribute
+ }
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Write Change Summary elements
+ //////////////////////////////////////////////////////////////////////////
+
+ void SDOXMLWriter::handleChangeSummaryElements(
+ ChangeSummaryPtr cs,
+ DataObjectPtr dob)
+ {
+ int rc;
+
+ SettingList& sl = cs->getOldValues(dob);
+
+ if (sl.size() == 0)
+ {
+ // there are no setting for this element.
+ return;
+ }
+
+ for (int j=0;j< sl.size(); j++)
+ {
+ try
+ {
+
+ // single values will have been covered by the attributes.
+ if (!sl.get(j)->getProperty().isMany()) continue;
+
+ if (sl.get(j)->getProperty().getType().isDataType())
+ {
+
+ rc = xmlTextWriterWriteElement(
+ writer,
+ SDOXMLString(sl.get(j)->getProperty().getName()),
+ SDOXMLString(sl.get(j)->getCStringValue()));
+
+ } // if datatype
+ else
+ {
+ DataObjectPtr dob2 = sl.get(j)->getDataObjectValue();
+ if (!dob2)
+ {
+ continue;
+ }
+ if (cs->isDeleted(dob2))
+ {
+ handleChangeSummaryDeletedObject(sl.get(j)->getProperty().getName(), cs,dob2);
+ }
+ else
+ {
+ rc = xmlTextWriterStartElement(
+ writer,
+ SDOXMLString(sl.get(j)->getProperty().getName()));
+ rc = xmlTextWriterWriteAttribute(
+ writer,
+ SDOXMLString("sdo:ref"),
+ SDOXMLString(dob2->objectToXPath()));
+ rc = xmlTextWriterEndElement(
+ writer);
+ }
+ }
+ }
+ catch (SDORuntimeException e)
+ {
+ // ignore this element
+ }
+ } // for
+ }
+
+
+ //////////////////////////////////////////////////////////////////////////
+ // Write a deleted object and all its props
+ //////////////////////////////////////////////////////////////////////////
+
+ void SDOXMLWriter::handleChangeSummaryDeletedObject(
+ const char* name,
+ ChangeSummaryPtr cs,
+ DataObjectPtr dob)
+ {
+
+ int rc, k; // TODO error handling
+
+ SettingList& sl = cs->getOldValues(dob);
+
+ rc = xmlTextWriterStartElement(
+ writer,
+ SDOXMLString(name));
+
+ if (sl.size() == 0)
+ {
+ rc = xmlTextWriterWriteAttribute(writer,
+ SDOXMLString("sdo:ref"),
+ SDOXMLString(cs->getOldXpath(dob)));
+ rc = xmlTextWriterEndElement(writer);
+ return;
+ }
+
+
+ try
+ {
+ // print single valued datatypes as attributes
+
+ for (int j=0;j< sl.size(); j++)
+ {
+ //if (!sl.get(j)->isSet())
+ //{
+ // // unset properties dont need recording - ah but they do!
+ //
+ // continue;
+ //}
+ if ( sl.get(j)->getProperty().isMany())
+ {
+ // manys are elements
+ continue;
+ }
+ if (!sl.get(j)->getProperty().getType().isDataType())
+ {
+ // data objects are element in a deleted data object.
+ continue;
+ }
+
+ rc = xmlTextWriterWriteAttribute(writer,
+ SDOXMLString(sl.get(j)->getProperty().getName()),
+ SDOXMLString(sl.get(j)->getCStringValue()));
+
+ } // for attributes
+
+
+ // now we are onto the many-values,
+ // and dataobject single values.
+ //
+ // handle deletions within deletions in reverse order, so they match the
+ // deletion records above.
+
+ for (k=sl.size()-1;k>=0; k--)
+ {
+
+ if ( !sl.get(k)->getProperty().getType().isDataType() &&
+ sl.get(k)->getProperty().isMany())
+ {
+ // its a dataobject type
+ DataObjectPtr dob2 = sl.get(k)->getDataObjectValue();
+ if (!dob2) continue;
+ if (!cs->isDeleted(dob2)) continue;
+ handleChangeSummaryDeletedObject(sl.get(k)->
+ getProperty().getName(),cs,dob2);
+ }
+ } // for attributes
+
+ for (k=0;k< sl.size(); k++)
+ {
+
+ if ( !sl.get(k)->getProperty().getType().isDataType())
+ {
+ if (sl.get(k)->getProperty().isMany()) continue;
+ // its a single valued dataobject type
+
+ DataObjectPtr dob2 = sl.get(k)->getDataObjectValue();
+ if (!dob2) continue;
+ if (!cs->isDeleted(dob2)) continue;
+ handleChangeSummaryDeletedObject(sl.get(k)->
+ getProperty().getName(),cs,dob2);
+
+ }
+ else
+ {
+ if ( !sl.get(k)->getProperty().isMany()) continue;
+
+ // could only be many valued data type
+
+ rc = xmlTextWriterWriteElement(writer,
+ SDOXMLString(sl.get(k)->getProperty().getName()),
+ SDOXMLString(sl.get(k)->getCStringValue()));
+ }
+ } // for attributes
+ }
+ catch (SDORuntimeException e)
+ {
+ // ignore - and write the end-element
+ }
+
+ rc = xmlTextWriterEndElement(writer);
+ }
+
+
+ //////////////////////////////////////////////////////////////////////////
+ // Write the list of elements of a change summary
+ //////////////////////////////////////////////////////////////////////////
+
+ void SDOXMLWriter::handleSummaryChange(
+ const SDOXMLString& elementName,
+ ChangeSummaryPtr cs,
+ DataObjectPtr dob)
+ {
+ int rc;
+ DataObject* temp = dob;
+ const char* name;
+ try
+ {
+ name = temp->getContainmentProperty().getName();
+ }
+ catch (SDORuntimeException e)
+ {
+ // This could be a root, and have no name.
+ name = 0;
+ }
+
+ if (name == 0)
+ {
+ rc = xmlTextWriterStartElement(
+ writer,
+ elementName);
+ }
+ else
+ {
+ rc = xmlTextWriterStartElement(
+ writer,
+ SDOXMLString(name));
+ }
+
+ if (rc != 0)
+ {
+ // failed to write an element
+ return;
+ }
+
+ try
+ {
+ name = temp->objectToXPath();
+ }
+ catch (SDORuntimeException e)
+ {
+ name = 0;
+ }
+
+ rc = xmlTextWriterWriteAttribute(writer,
+ SDOXMLString("sdo:ref"),
+ SDOXMLString(name));
+
+ handleChangeSummaryAttributes(cs, temp);
+
+ handleChangeSummaryElements(cs, temp);
+
+ rc = xmlTextWriterEndElement(writer);
+
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Write a Change Summary
+ //////////////////////////////////////////////////////////////////////////
+
+ void SDOXMLWriter::handleChangeSummary(
+ const SDOXMLString& elementName,
+ ChangeSummaryPtr cs)
+ {
+ int i;
+ int rc;
+
+ ChangedDataObjectList& changedDOs = cs->getChangedDataObjects();
+ rc = xmlTextWriterStartElementNS(writer,
+ SDOXMLString("sdo"), SDOXMLString("changeSummary"), SDOXMLString(Type::SDOTypeNamespaceURI.c_str()));
+ if (rc != 0) return;
+ if (cs->isLogging())
+ {
+ rc = xmlTextWriterWriteAttribute(writer,
+ SDOXMLString("logging"),
+ SDOXMLString("true"));
+ }
+
+ if (changedDOs.size() > 0)
+ {
+
+ // write the creates/deletes in the order they
+ // happened, as elements.
+
+ for (i=0;i< changedDOs.size();i++)
+ {
+ if (cs->isCreated(changedDOs[i])
+ && changedDOs.getType(i) == ChangedDataObjectList::Create)
+ {
+ // TODO - should work out if theres a IDREF here
+ // TODO - can we have more than one create like this?
+ try
+ {
+ rc = xmlTextWriterWriteElement(writer,
+ SDOXMLString("create"),
+ SDOXMLString(changedDOs[i]->objectToXPath()));
+ }
+ catch (SDORuntimeException e)
+ {
+ // The object was not in our tree - we ignore it.
+ }
+ }
+ if (cs->isDeleted(changedDOs[i])
+ && changedDOs.getType(i) == ChangedDataObjectList::Delete)
+ {
+ // TODO - should work out if theres a IDREF here
+ try
+ {
+ rc = xmlTextWriterWriteElement(writer,
+ SDOXMLString("delete"),
+ SDOXMLString(cs->getOldXpath(changedDOs[i])));
+ }
+ catch (SDORuntimeException e)
+ {
+ // The object was not in the deleted list - we ignore it.
+ }
+ }
+ }
+
+
+ for (i=0;i< changedDOs.size();i++)
+ {
+ if (cs->isModified(changedDOs[i]))
+ {
+ handleSummaryChange(elementName, cs, changedDOs[i]);
+ }
+ }
+
+ }
+ rc = xmlTextWriterEndElement(writer);
+ }
+
+ //////////////////////////////////////////////////////////////////////////
+ // Add to namespaces
+ //////////////////////////////////////////////////////////////////////////
+
+ void SDOXMLWriter::addToNamespaces(DataObjectImpl* dob)
+ {
+ std::map<SDOXMLString,SDOXMLString>::iterator it;
+ SDOXMLString uri = dob->getType().getURI();
+
+ it = namespaceMap.find(uri);
+ if (it == namespaceMap.end())
+ {
+ char buf[20];
+ sprintf(buf,"%d",++spacescount);
+ SDOXMLString s = SDOXMLString("tns") + buf;
+ namespaceMap.insert(make_pair(uri,s));
+ }
+
+ PropertyList pl = dob->getInstanceProperties();
+ for (int i = 0; i < pl.size(); i++)
+ {
+ if (!dob->isSet(pl[i]))continue;
+
+ if (pl[i].isMany())
+ {
+ if (!pl[i].getType().isDataType())
+ {
+ DataObjectList& dl = dob->getList(pl[i]);
+ for (int k=0;k< dl.size() ;k++)
+ {
+ DataObjectImpl* d = (DataObjectImpl*)(DataObject*)dl[k];
+ if (d != 0)addToNamespaces(d);
+ }
+ }
+ }
+ else
+ {
+ if (!pl[i].getType().isDataType())
+ {
+ DataObjectImpl* d = (DataObjectImpl*)(DataObject*)dob->getDataObject(pl[i]);
+ if (d != 0)addToNamespaces(d);
+ }
+ else
+ {
+ XSDPropertyInfo* pi = getPropertyInfo(dob->getType(), pl[i]);
+ if (pi)
+ {
+ PropertyDefinitionImpl propdef;
+ propdef = pi->getPropertyDefinition();
+ if (propdef.isElement)continue;
+ if (!propdef.isQName)continue;
+
+ SDOXMLString propertyValue = (dob->getCString(pl[i]));
+ XMLQName qname(propertyValue);
+
+ it = namespaceMap.find(qname.getURI());
+ if (it == namespaceMap.end())
+ {
+ char buf[20];
+ sprintf(buf,"%d",++spacescount);
+ SDOXMLString s = SDOXMLString("tns") + buf;
+ namespaceMap.insert(make_pair(qname.getURI(),s));
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+
+
+ //////////////////////////////////////////////////////////////////////////
+ // Write a DatObject tree
+ //////////////////////////////////////////////////////////////////////////
+
+ int SDOXMLWriter::writeDO(
+ DataObjectPtr dataObject,
+ const SDOXMLString& elementURI,
+ const SDOXMLString& elementName,
+ bool writeXSIType,
+ bool isRoot)
+ {
+
+ int rc;
+
+ if (dataObject == 0)
+ return 0;
+
+
+ //SDOXMLString uri;
+ //if (!elementURI.equals(namespaceUriStack.top()))
+ //{
+ // uri = elementURI;
+ // namespaceUriStack.push(elementURI);
+ //}
+
+ const Type& dataObjectType = dataObject->getType();
+
+ //////////////////////////////////////////////////////////////////////////
+ // suppose its a primitive type - just write the value
+ //////////////////////////////////////////////////////////////////////////
+ if (dataObjectType.isDataType())
+ {
+ if (dataObject->isNull(""))
+ {
+ rc = xmlTextWriterStartElementNS(writer,
+ NULL, elementName, elementURI);
+ if (rc < 0)
+ {
+ SDO_THROW_EXCEPTION("writeDO",
+ SDOXMLParserException,
+ "xmlTextWriterStartElementNS failed");
+ }
+ rc = xmlTextWriterWriteAttribute(writer,
+ (const unsigned char*)"xsi:nil",
+ (const unsigned char*)"true");
+ rc = xmlTextWriterEndElement(writer);
+ }
+ else
+ {
+ xmlTextWriterWriteElement(
+ writer,
+ elementName,
+ SDOXMLString(dataObject->getCString("")));
+ }
+
+ // need to pop stacks before returning
+ //if (!uri.isNull())
+ //{
+ // namespaceUriStack.pop();
+ //}
+ return 0;
+
+ }
+
+
+ //namespaceStack.push(namespaces);
+
+
+ if (isRoot)
+ {
+ tnsURI=elementURI;
+ if (elementURI.equals("")) {
+ rc = xmlTextWriterStartElementNS(writer, NULL, elementName, NULL);
+ }
+ else
+ {
+ rc = xmlTextWriterStartElementNS(writer, NULL, elementName, elementURI);
+ }
+ if (rc < 0) {
+ SDO_THROW_EXCEPTION("writeDO", SDOXMLParserException, "xmlTextWriterStartElementNS failed");
+ }
+ }
+ else
+ {
+ //xmlTextWriterWriteString(writer,SDOXMLString("\n"));
+
+ SDOXMLString theName=elementName;
+
+ if (!elementURI.isNull() && !elementURI.equals(tnsURI) && !elementURI.equals(""))
+ {
+ std::map<SDOXMLString,SDOXMLString>::iterator it = namespaceMap.find(elementURI);
+ if (it != namespaceMap.end())
+ {
+ theName = (*it).second;
+ theName += ":";
+ theName += elementName;
+ }
+ }
+
+ rc = xmlTextWriterStartElementNS(writer, NULL, theName, NULL);
+ if (rc < 0) {
+ SDO_THROW_EXCEPTION("writeDO", SDOXMLParserException, "xmlTextWriterStartElementNS failed");
+ }
+ }
+
+
+ if (writeXSIType)
+ {
+ rc = xmlTextWriterWriteAttributeNS(writer,
+ SDOXMLString("xsi"), SDOXMLString("type"),
+ NULL,
+ /*SDOXMLString("http://www.w3.org/2001/XMLSchema-instance"),*/
+ SDOXMLString(dataObject->getType().getName()));
+ if (isRoot)
+ {
+ namespaceMap.insert(make_pair(
+ SDOXMLString("http://www.w3.org/2001/XMLSchema-instance"),
+ SDOXMLString("xsi")));
+
+ }
+ }
+
+
+ if (isRoot)
+ {
+ std::map<SDOXMLString,SDOXMLString>::iterator it = namespaceMap.find(elementURI);
+ if (it == namespaceMap.end())
+ {
+ SDOXMLString s = SDOXMLString("tns");
+ namespaceMap.insert(make_pair(elementURI,s));
+ }
+ DataObjectImpl* d = (DataObjectImpl*)(DataObject*)dataObject;
+ spacescount = 1;
+ addToNamespaces(d);
+
+/////////////////////////////////////////////////////////////////////////////////////
+// // build the namespace map, and write the items out at the
+// // top of the tree.
+// int spacecount = 0;
+// DataObjectImpl* d = (DataObjectImpl*)(DataObject*)dataObject;
+// if (d != 0)
+// {
+// TypeList types = (d->getDataFactory())->getTypes();
+// std::map<SDOXMLString,SDOXMLString>::iterator it;
+//
+// for (int i = 0; i<types.size(); i++)
+// {
+// SDOXMLString uri = types[i].getURI();
+// if (uri.equals(Type::SDOTypeNamespaceURI)) continue;
+// std::map<SDOXMLString,SDOXMLString>::iterator it = namespaceMap.find(uri);
+// if (it == namespaceMap.end())
+// {
+// char buf[4];
+// if (!elementURI.isNull())
+// {
+// if (elementURI.equals(uri))
+// {
+// SDOXMLString s = SDOXMLString("tns");
+// namespaceMap.insert(make_pair(uri,s));
+// }
+// else
+// {
+// sprintf(buf,"%d",++spacecount);
+// SDOXMLString s = SDOXMLString("tns") + buf;
+// namespaceMap.insert(make_pair(uri,s));
+// }
+// }
+// }
+// }
+////////////////////////////////////////////////////////////////////////////////////
+
+ for (it = namespaceMap.begin();it != namespaceMap.end(); ++it)
+ {
+ if ((*it).first.equals("")) continue;
+ SDOXMLString space = SDOXMLString("xmlns:") + (*it).second;
+ rc = xmlTextWriterWriteAttribute(writer,
+ space, (*it).first);
+ }
+ }
+
+
+ //////////////////////////////////////////////////////////////////////////
+ // write out the type if the xsi:type if the containing type is open
+ // and the property is not one of the declared properties
+ //////////////////////////////////////////////////////////////////////////
+ DataObject* dob = dataObject;
+ DataObjectImpl* cont =
+ ((DataObjectImpl*)dob)->getContainerImpl();
+ if (cont != 0)
+ {
+ if (cont->getType().isOpenType())
+ {
+ //if (dataObject->getType().getURI() != 0)
+ //{
+ // std::string value =
+ // dataObject->getType().getURI();
+ // value += ":";
+ // value += dataObject->getType().getName();
+ // rc = xmlTextWriterWriteAttribute(writer,
+ // (const unsigned char*)"xsi:type",
+ // (const unsigned char*)value.c_str());
+ //}
+ //else
+ //{
+ if (cont->getTypeImpl().getPropertyImpl(elementName) == 0)
+ {
+ rc = xmlTextWriterWriteAttribute(writer,
+ (const unsigned char*)"xsi:type",
+ (const unsigned char*)dataObject->getType().getName());
+ }
+ }
+ }
+
+ // write nil if required
+ if (dataObject->isNull(""))
+ {
+ rc = xmlTextWriterWriteAttribute(writer,
+ (const unsigned char*)"xsi:nil",
+ (const unsigned char*)"true");
+ }
+
+
+ //////////////////////////////////////////////////////////////////////////
+ // Iterate over all the properties to find attributes
+ //////////////////////////////////////////////////////////////////////////
+ int i;
+ int j = 1;
+ PropertyList pl = dataObject->getInstanceProperties();
+ for (i = 0; i < pl.size(); i++)
+ {
+ if (dataObject->isSet(pl[i]))
+ {
+ SDOXMLString propertyName(pl[i].getName());
+ XSDPropertyInfo* pi = getPropertyInfo(dataObjectType, pl[i]);
+ PropertyDefinitionImpl propdef;
+ if (pi)
+ {
+ propdef = pi->getPropertyDefinition();
+ propertyName = propdef.localname;
+ }
+
+ // Elements are written as <element>
+ if (propdef.isElement)
+ continue;
+
+ // Many-valued properties are written as <element>
+ if (pl[i].isMany())
+ continue;
+
+ // if (pl[i].isContainment())
+ // continue;
+
+ //////////////////////////////////////////////////////////////////////
+ // Non contained properties become attributes
+ //////////////////////////////////////////////////////////////////////
+ const Type& propertyType = pl[i].getType();
+
+ if (propertyType.isDataType())
+ {
+ SDOXMLString propertyValue = (dataObject->getCString(pl[i]));
+ if (pi && pi->getPropertyDefinition().isQName)
+ {
+ XMLQName qname(propertyValue);
+
+ //{
+ //const SDOXMLString* prefix = namespaces.findPrefix(qname.getURI());
+ //if (prefix == 0)
+ //{
+ // char buffer[100];
+ // SDOXMLString pref = "tns";
+ // sprintf(buffer, "%d", i);
+ // pref += buffer;
+ // namespaces.add(pref, qname.getURI());
+ // prefix = namespaces.findPrefix(qname.getURI());
+ //}
+
+ //if (prefix != 0 && !(*prefix).equals(""))
+
+ std::map<SDOXMLString,SDOXMLString>::iterator it = namespaceMap.find(qname.getURI());
+ if (it != namespaceMap.end())
+ {
+ propertyValue = (*it).second + ":" + qname.getLocalName();
+ }
+ else
+ {
+ char buffer[20];
+ SDOXMLString pref = "tnss";
+ sprintf(buffer, "%d", j++);
+ pref += buffer;
+ rc = xmlTextWriterWriteAttributeNS(writer,
+ SDOXMLString("xmlns"), pref, NULL, qname.getURI());
+ propertyValue = pref + ":" + qname.getLocalName();
+ }
+
+ }
+ rc = xmlTextWriterWriteAttribute(writer,
+ propertyName, propertyValue);
+ }
+ else
+ {
+ // Handle non-containment reference to DataObject
+ if (pl[i].isReference())
+ {
+ writeReference(dataObject, pl[i], false);
+ }
+ }
+ }
+ }
+
+ // --------------------
+ // Handle ChangeSummary
+ // --------------------
+ if (dataObject->getType().isChangeSummaryType())
+ {
+ ChangeSummaryPtr changeSummary = dataObject->getChangeSummary();
+ if (changeSummary)
+ {
+ handleChangeSummary(elementName, changeSummary);
+ }
+ }
+
+ if (dataObjectType.isSequencedType())
+ {
+ SequencePtr sequence = dataObject->getSequence();
+ if (sequence)
+ {
+ for (i=0; i<sequence->size(); i++)
+ {
+
+ if (sequence->isText(i))
+ {
+ rc = xmlTextWriterWriteString(
+ writer,
+ SDOXMLString(sequence->getCStringValue(i)));
+ continue;
+ } // end TextType
+
+ const Property& seqProp = sequence->getProperty(i);
+ SDOXMLString seqPropName = seqProp.getName();
+ const Type& seqPropType = seqProp.getType();
+
+ if (seqPropType.isDataObjectType())
+ {
+ DataObjectPtr doValue;
+ if (seqProp.isMany())
+ {
+ int index = sequence->getListIndex(i);
+ doValue = dataObject->getList(seqProp)[index];
+ }
+ else
+ {
+ doValue = dataObject->getDataObject(seqProp);
+ }
+
+ if (doValue)
+ {
+ // Handle non-containment reference to DataObject
+ if (seqProp.isReference())
+ {
+ writeReference(dataObject, seqProp, true, doValue);
+ }
+ else
+ {
+ writeDO(doValue, doValue->getType().getURI(), seqPropName);
+ }
+ }
+ } // end DataObject
+
+
+ else
+ {
+ // Sequence member is a primitive
+ xmlTextWriterWriteElement(
+ writer,
+ seqPropName,
+ SDOXMLString(sequence->getCStringValue(i)));
+
+ } // end DataType
+ } // end - iterate over sequence
+
+ }
+
+ } // end sequence handling
+
+ else
+ {
+
+ //////////////////////////////////////////////////////////////////////////
+ // Iterate over all the properties to find elements
+ //////////////////////////////////////////////////////////////////////////
+ for (i = 0; i < pl.size(); i++)
+ {
+ if (dataObject->isSet(pl[i]))
+ {
+
+ SDOXMLString propertyName(pl[i].getName());
+ XSDPropertyInfo* pi = getPropertyInfo(dataObjectType, pl[i]);
+ if (pi)
+ {
+ if (!pi->getPropertyDefinition().isElement)
+ continue;
+ propertyName = pi->getPropertyDefinition().localname;
+ }
+
+ const Type& propertyType = pl[i].getType();
+
+ //////////////////////////////////////////////////////////////////////
+ // For a many-valued property get the list of values
+ //////////////////////////////////////////////////////////////////////
+ if (pl[i].isMany())
+ {
+ DataObjectList& dol = dataObject->getList(pl[i]);
+ for (int j = 0; j <dol.size(); j++)
+ {
+ // Handle non-containment reference to DataObject
+ if (pl[i].isReference() )
+ {
+ writeReference(dataObject, pl[i], true, dol[j]);
+ }
+ else
+ {
+ SDOXMLString typeURI = dol[j]->getType().getURI();
+ writeDO(dol[j], dol[j]->getType().getURI(), propertyName);
+ }
+ }
+ } // end IsMany
+
+ //////////////////////////////////////////////////////////////////////
+ // For a dataobject write the do
+ //////////////////////////////////////////////////////////////////////
+ else if (!propertyType.isDataType())
+ {
+ // Handle non-containment reference to DataObject
+ if (pl[i].isReference())
+ {
+ if (pi)
+ writeReference(dataObject, pl[i], true);
+ }
+ else
+ {
+ DataObjectPtr propDO = dataObject->getDataObject(pl[i]);
+ writeDO(propDO, propDO->getType().getURI(), propertyName);
+ }
+ }
+
+ //////////////////////////////////////////////////////////////////////
+ // For a primitive
+ //////////////////////////////////////////////////////////////////////
+ else
+ {
+ // Only write a primitive as an element if defined by the XSD
+ if (pi)
+ {
+ const Type& tp = dataObject->getType();
+ XSDTypeInfo* typeInfo = (XSDTypeInfo*)
+ ((DASType*)&tp)->getDASValue("XMLDAS::TypeInfo");
+ if (typeInfo && typeInfo->getTypeDefinition().isExtendedPrimitive)
+ {
+ xmlTextWriterWriteRaw(
+ writer,
+ SDOXMLString(dataObject->getCString(pl[i])));
+ }
+ else
+ {
+ if (dataObject->isNull(pl[i]))
+ {
+ rc = xmlTextWriterStartElementNS(writer,
+ NULL, elementName, elementURI);
+ if (rc < 0)
+ {
+ SDO_THROW_EXCEPTION("writeDO",
+ SDOXMLParserException,
+ "xmlTextWriterStartElementNS failed");
+ }
+ rc = xmlTextWriterWriteAttribute(writer,
+ (const unsigned char*)"xsi:nil",
+ (const unsigned char*)"true");
+ rc = xmlTextWriterEndElement(writer);
+ }
+ else
+ {
+ xmlTextWriterWriteElement(
+ writer,
+ propertyName,
+ SDOXMLString(dataObject->getCString(pl[i])));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ rc = xmlTextWriterEndElement(writer);
+ return rc;
+
+ //namespaces = namespaceStack.top();
+ //namespaceStack.pop();
+ //if (!uri.isNull())
+ //{
+ // namespaceUriStack.pop();
+ //}
+ }
+
+ XSDPropertyInfo* SDOXMLWriter::getPropertyInfo(const Type& type, const Property& property)
+ {
+ if (dataFactory)
+ {
+ return (XSDPropertyInfo*)dataFactory->getDASValue(type, property.getName(), "XMLDAS::PropertyInfo");
+ }
+ else
+ {
+ return (XSDPropertyInfo*)((DASProperty*)&property)->getDASValue("XMLDAS::PropertyInfo");
+ }
+
+ }
+
+ void SDOXMLWriter::writeReference(
+ DataObjectPtr dataObject,
+ const Property& property,
+ bool isElement,
+ DataObjectPtr refferedToObject)
+ {
+ DataObjectPtr reffedObject = refferedToObject;
+ if (reffedObject == 0)
+ {
+ reffedObject = dataObject->getDataObject(property);
+ }
+
+ // Get ID from referred to DataObject or use XPath
+ SDOXMLString refValue;
+ XSDTypeInfo* ti = (XSDTypeInfo*)((DASType*)&reffedObject->getType())->
+ getDASValue("XMLDAS::TypeInfo");
+ if (ti)
+ {
+ TypeDefinitionImpl typeDef = ti->getTypeDefinition();
+ if (!typeDef.IDPropertyName.isNull())
+ {
+ refValue = reffedObject->getCString(typeDef.IDPropertyName);
+ }
+ }
+
+ if (refValue.isNull())
+ {
+ // need to get XPATH
+ refValue = ((DataObjectImpl*)(DataObject*)reffedObject)->objectToXPath();
+ }
+
+ if (!refValue.isNull())
+ {
+ if (isElement)
+ {
+ // Set the IDREF value
+ xmlTextWriterWriteElement(writer,
+ SDOXMLString(property.getName()), refValue);
+ }
+ else
+ {
+ // Set the IDREF value
+ xmlTextWriterWriteAttribute(writer,
+ SDOXMLString(property.getName()), refValue);
+ }
+ }
+ }
+
+ } // End - namespace sdo
+} // End - namespace commonj
+