summaryrefslogtreecommitdiff
path: root/cpp/src/Freeze/Transform.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/Freeze/Transform.cpp')
-rw-r--r--cpp/src/Freeze/Transform.cpp2047
1 files changed, 0 insertions, 2047 deletions
diff --git a/cpp/src/Freeze/Transform.cpp b/cpp/src/Freeze/Transform.cpp
deleted file mode 100644
index b86db6a0f2e..00000000000
--- a/cpp/src/Freeze/Transform.cpp
+++ /dev/null
@@ -1,2047 +0,0 @@
-// **********************************************************************
-//
-// Copyright (c) 2001
-// MutableRealms, Inc.
-// Huntsville, AL, USA
-//
-// All Rights Reserved
-//
-// **********************************************************************
-
-#include <Freeze/Transform.h>
-
-#include <vector>
-#include <assert.h>
-#include <iostream>
-#include <Freeze/Print.h>
-
-#include <Freeze/ErrorHandler.h>
-#include <parsers/DOMParser.hpp>
-
-using namespace std;
-
-ostream&
-operator<<(ostream& os, const IllegalTransform& ex)
-{
- os << "IllegalTransform: file: " << ex.file() << " line: " << ex.line();
- return os;
-}
-
-ostream&
-operator<<(ostream& os, const IncompatibleSchema& ex)
-{
- os << "IncompatibleSchema: file: " << ex.file() << " line: " << ex.line();
- return os;
-}
-
-ostream&
-operator<<(ostream& os, const InvalidSchema& ex)
-{
- os << "InvalidSchema: file: " << ex.file() << " line: " << ex.line();
- return os;
-}
-
-ostream&
-operator<<(ostream& os, const SchemaViolation& ex)
-{
- os << "SchemaViolation: file: " << ex.file() << " line: " << ex.line();
- return os;
-}
-
-static string
-toString(const DOMString& s)
-{
- char* t = s.transcode();
- string r(t);
- delete[] t;
- return r;
-}
-
-
-typedef ::std::map< ::std::string, DocumentInfo*> DocumentMap;
-
-typedef ::std::map< ::std::string, ::std::string> PrefixURIMap;
-
-struct DocumentInfo
-{
- DOM_Document document;
- PrefixURIMap nsMap;
- ::std::string targetNamespace;
-};
-
-//
-// Convert a QName from prefix:local to local@namespaceURI.
-//
-static string
-convertQName(const string& qname, const DocumentInfo* info)
-{
- size_t pos = qname.find(':');
- string prefix;
- string localName;
- if (pos != string::npos)
- {
- prefix = qname.substr(0, pos);
- localName = qname.substr(pos+1);
- }
- else
- {
- localName = qname;
- }
-
- PrefixURIMap::const_iterator q = info->nsMap.find(prefix);
- if (q == info->nsMap.end())
- {
- cout << qname << endl;
- //
- // No namespace - TODO: not InvalidSchema - it's an
- // invalid instance document.
- //
- throw InvalidSchema(__FILE__, __LINE__);
- }
-
- string n = localName;
- n += '@';
- n += q->second;
-
- return n;
-}
-
-static void
-createNSMap(DocumentInfo* info, DOM_Node& root)
-{
- static const string targetNamespaceAttrName = "targetNamespace";
- static const string xmlnsAttrName = "xmlns";
-
- DOM_NamedNodeMap attributes = root.getAttributes();
- unsigned int max = attributes.getLength();
- for (unsigned int i = 0; i < max; ++i)
- {
- DOM_Node attribute = attributes.item(i);
- string attrName = toString(attribute.getNodeName());
- if (attrName.substr(0, 5) == xmlnsAttrName)
- {
- string ns;
- if (attrName.size() > 5)
- {
- ns = attrName.substr(6);
- }
- string uri = toString(attribute.getNodeValue());
- //cout << "adding: " << ns << " " << uri << endl;
- info->nsMap.insert(make_pair(ns, uri));
- }
- else if (attrName == targetNamespaceAttrName)
- {
- info->targetNamespace = toString(attribute.getNodeValue());
- }
- }
-}
-
-static DOM_Node
-findChild(const DOM_Node& parent, const string& namespaceURI, const string& localname)
-{
- DOM_NodeList children = parent.getChildNodes();
- for (unsigned int i = 0; i < children.getLength(); ++i)
- {
- DOM_Node child = children.item(i);
- if (toString(child.getNamespaceURI()) == namespaceURI && toString(child.getLocalName()) == localname)
- {
- return child;
- }
- }
-
- return DOM_Node();
-}
-
-//
-// TODO: This is used for abuse. Replace by a real search.
-//
-static DOM_Node
-findChild(const DOM_Node& parent, const string& name)
-{
- DOM_NodeList children = parent.getChildNodes();
- for (unsigned int i = 0; i < children.getLength(); ++i)
- {
- DOM_Node child = children.item(i);
- if (toString(child.getNodeName()) == name)
- {
- return child;
- }
- }
- return DOM_Node();
-}
-
-static string
-getAttributeByName(DOM_Node& node, const string& name)
-{
- DOM_NamedNodeMap attributes = node.getAttributes();
- unsigned int max = attributes.getLength();
- for (unsigned int i = 0; i < max; ++i)
- {
- DOM_Node attribute = attributes.item(i);
- string nodeName = toString(attribute.getNodeName());
- if (nodeName == name)
- {
- return toString(attribute.getNodeValue());
- }
- }
-
- return string("");
-}
-
-static string
-getLengthAttribute(DOM_Node& node)
-{
- static const string lengthName = "length";
- return getAttributeByName(node, lengthName);
-}
-
-static string
-getTypeAttribute(DOM_Node& node)
-{
- static const string typeName = "type";
- return getAttributeByName(node, typeName);
-}
-
-static string
-getNameAttribute(DOM_Node& node)
-{
- static const string nameName = "name";
- return getAttributeByName(node, nameName);
-}
-
-static string
-getValueAttribute(DOM_Node& node)
-{
- static const string valueName = "value";
- return getAttributeByName(node, valueName);
-}
-
-static string
-findAppinfoType(DOM_Node& node)
-{
- DOM_Node child = findChild(node, "xs:annotation");
- if (!child.isNull())
- {
- child = findChild(child, "xs:appinfo");
- if (!child.isNull())
- {
- child = findChild(child, "type");
- if (!child.isNull())
- {
- child = child.getFirstChild();
- if (!child.isNull())
- {
- return toString(child.getNodeValue());
- }
- }
- }
- }
-
- return string("");
-}
-
-//
-// Specific transforms.
-//
-class NilTransform : public Transform
-{
-public:
-
- NilTransform()
- {
- }
-
- virtual void
- transform(ostream& os, const DocumentInfo*, const string&, DOM_Node node)
- {
- if (node.isNull())
- {
- throw SchemaViolation(__FILE__, __LINE__);
- }
-
- os << node;
- }
-
- virtual ostream&
- print(ostream& os)
- {
- os << "[nil transform]";
- return os;
- }
-};
-
-//
-// This transform is the root transform for marshaled documents.
-//
-// TODO: complete, rename
-//
-class InternalTransform : public Transform
-{
-public:
-
- InternalTransform()
- {
- }
-
- virtual void
- transform(ostream& os, const DocumentInfo*, const string&, DOM_Node node)
- {
- }
-
- virtual ostream&
- print(ostream& os)
- {
- os << "[internal transform]";
- return os;
- }
-};
-
-class ElementTransform : public Transform
-{
-public:
-
- ElementTransform(const string& namespaceURI, const string& name, Transform* transform) :
- _ns(namespaceURI),
- _name(name),
- _transform(transform)
- {
- }
-
- virtual void
- transform(ostream& os, const DocumentInfo* info, const string&, DOM_Node node)
- {
- _transform->transform(os, info, _name, node);
- }
-
- virtual ostream&
- print(ostream& os)
- {
- os << "[ element: " << name() << ": " << _transform->print(os) << "]";
- return os;
- }
-
- const string& namespaceURI() const { return _ns; }
- const string& name() const { return _name; }
-
-private:
-
- string _ns;
- string _name;
-
- Transform* _transform;
-};
-
-class ValidateEnumerationTransform : public Transform
-{
-public:
-
- ValidateEnumerationTransform(const vector<string>& values) :
- _values(values)
- {
- }
-
- virtual void
- transform(ostream& os, const DocumentInfo*, const string&, DOM_Node node)
- {
- if (node.isNull())
- {
- throw SchemaViolation(__FILE__, __LINE__);
- }
-
- DOM_Node child = node.getFirstChild();
- if (child.isNull() || child.getNodeType() != DOM_Node::TEXT_NODE)
- {
- throw SchemaViolation(__FILE__, __LINE__);
- }
- string value = toString(child.getNodeValue());
- if (find(_values.begin(), _values.end(), value) == _values.end())
- {
- throw IllegalTransform(__FILE__, __LINE__);
- }
- os << node;
- }
-
- virtual ostream&
- print(ostream& os)
- {
- os << "[validate enumeration]";
- return os;
- }
-
-private:
-
- vector<string> _values;
-};
-
-class ValidateIntegerTransform : public Transform
-{
-public:
-
- ValidateIntegerTransform(const string& from, const string& to) :
- _from(from),
- _to(to)
- {
- }
-
- virtual void
- transform(ostream& os, const DocumentInfo*, const string&, DOM_Node node)
- {
- if (node.isNull())
- {
- throw SchemaViolation(__FILE__, __LINE__);
- }
-
- DOM_Node child = node.getFirstChild();
- if (child.isNull() || child.getNodeType() != DOM_Node::TEXT_NODE)
- {
- throw SchemaViolation(__FILE__, __LINE__);
- }
- string value = toString(child.getNodeValue());
- long v = atol(value.c_str());
- if (_to == "xs:byte")
- {
- if (v < SCHAR_MIN || v > SCHAR_MAX)
- {
- throw IllegalTransform(__FILE__, __LINE__);
- }
- }
- else if (_to == "xs:short")
- {
- if (v < SHRT_MIN || v > SHRT_MAX)
- {
- throw IllegalTransform(__FILE__, __LINE__);
- }
- }
- else if (_to == "xs:int")
- {
- if (v < INT_MIN || v > INT_MAX)
- {
- throw IllegalTransform(__FILE__, __LINE__);
- }
- }
- else if (_to == "xs:long")
- {
- }
- os << node;
- }
-
- virtual ostream&
- print(ostream& os)
- {
- os << "[validate integer: from=" << _from << " to=" << _to << " ]";
- return os;
- }
-
-private:
-
- string _from;
- string _to;
-};
-
-class ValidateFloatTransform : public Transform
-{
-public:
-
- ValidateFloatTransform(const string& from, const string& to) :
- _from(from),
- _to(to)
- {
- }
-
- virtual void
- transform(ostream& os, const DocumentInfo*, const string&, DOM_Node node)
- {
- if (node.isNull())
- {
- throw SchemaViolation(__FILE__, __LINE__);
- }
-
- DOM_Node child = node.getFirstChild();
- if (child.isNull() || child.getNodeType() != DOM_Node::TEXT_NODE)
- {
- throw SchemaViolation(__FILE__, __LINE__);
- }
- os << node;
- }
-
- virtual ostream&
- print(ostream& os)
- {
- os << "[validate float: from=" << _from << " to=" << _to << " ]";
- return os;
- }
-
-private:
-
- string _from;
- string _to;
-};
-
-class SequenceTransform : public Transform
-{
-public:
-
- SequenceTransform(Transform* transform) :
- _transform(transform)
- {
- }
-
- virtual void
- transform(ostream& os, const DocumentInfo* info, const string&, DOM_Node node)
- {
- if (node.isNull())
- {
- throw SchemaViolation(__FILE__, __LINE__);
- }
- string name = toString(node.getNodeName());
- os << "<" << name;
- string length = getLengthAttribute(node);
- os << " length=\"" << length << "\"";
- // TODO: print attributes
- os << ">";
-
- long l = atol(length.c_str());
-
- DOM_NodeList children = node.getChildNodes();
- for (unsigned int i = 0; i < children.getLength(); ++i)
- {
- DOM_Node child = children.item(i);
- if (child.getNodeType() != DOM_Node::ELEMENT_NODE)
- {
- continue;
- }
-
- static const string sequenceElementName = "e";
- string nodeName = toString(child.getNodeName());
- if (l == 0 || nodeName != sequenceElementName)
- {
- throw SchemaViolation(__FILE__, __LINE__);
- }
- _transform->transform(os, info, nodeName, child);
- --l;
- }
-
- os << "</" << name << ">";
- }
-
- virtual ostream&
- print(ostream& os)
- {
- os << "[sequence]\n";
- os << "\telement:" << _transform->print(os);
- os << "[sequence]\n";
- return os;
- }
-
-private:
-
- Transform* _transform;
-};
-
-class StructTransform : public Transform
-{
-public:
-
- StructTransform()
- {
- }
-
- virtual void
- transform(ostream& os, const DocumentInfo* info, const string&, DOM_Node node)
- {
- if (node.isNull())
- {
- throw SchemaViolation(__FILE__, __LINE__);
- }
- string name = toString(node.getNodeName());
- os << "<" << name;
- // TODO: print attributes
- os << ">";
-
- DOM_NodeList children = node.getChildNodes();
- for (vector<ElementTransform*>::const_iterator p = _transforms.begin(); p != _transforms.end(); ++p)
- {
- DOM_Node child = findChild(node, (*p)->namespaceURI(), (*p)->name());
- (*p)->transform(os, info, (*p)->name(), child);
- }
-
- os << "</" << name << ">";
- }
-
- virtual ostream&
- print(ostream& os)
- {
- os << "[struct start]\n";
- for (unsigned int i = 0; i < _transforms.size(); ++i)
- {
- os << "\t";
- _transforms[i]->print(os);
- os << "\n";
- }
- os << "[struct end]\n";
- return os;
- }
-
- void
- append(ElementTransform* transform)
- {
- _transforms.push_back(transform);
- }
-
-private:
-
- vector<ElementTransform*> _transforms;
-};
-
-class DefaultInitializedStructTransform : public Transform
-{
-public:
-
- DefaultInitializedStructTransform()
- {
- }
-
- virtual void
- transform(ostream& os, const DocumentInfo* info, const string& name, DOM_Node node)
- {
- os << "<" << name;
- // TODO: print attributes
- os << ">";
-
- DOM_Node child; // Nil
-
- for (vector<ElementTransform*>::const_iterator p = _transforms.begin(); p != _transforms.end(); ++p)
- {
- (*p)->transform(os, info, (*p)->name(), child);
- }
-
- os << "</" << name << ">";
- }
-
- virtual ostream&
- print(ostream& os)
- {
- os << "[empty struct start]\n";
- for (unsigned int i = 0; i < _transforms.size(); ++i)
- {
- os << "\t";
- _transforms[i]->print(os);
- os << "\n";
- }
- os << "[struct end]\n";
- return os;
- }
-
- void
- append(ElementTransform* transform)
- {
- _transforms.push_back(transform);
- }
-
-private:
-
- vector<ElementTransform*> _transforms;
-};
-
-class ClassTransform : public Transform
-{
-public:
-
- ClassTransform(TransformMap& transforms) :
- _transforms(transforms)
- {
- }
-
- virtual void
- transform(ostream& os, const DocumentInfo* info, const string& name, DOM_Node node)
- {
- static const string xsitypeAttrName = "xsi:type";
- string type = getAttributeByName(node, xsitypeAttrName);
- if (type.empty())
- {
- static const string xsinilAttrName = "xsi:nil";
- string nil = getAttributeByName(node, xsinilAttrName);
- if (nil.empty())
- {
- throw SchemaViolation(__FILE__, __LINE__);
- }
- //
- // Act as NilTransform
- //
- os << node;
- return;
- }
-
- string n = convertQName(type, info);
-
- //
- // Technically this is only permitted to be a more derived
- // type - however, this will not be enforced here.
- //
- TransformMap::const_iterator p = _transforms.find(n);
- if (p == _transforms.end())
- {
- cout << n << endl;
- throw SchemaViolation(__FILE__, __LINE__);
- }
- p->second->transform(os, info, name, node);
- }
-
- virtual ostream&
- print(ostream& os)
- {
- os << "[class]\n";
- return os;
- }
-
-private:
-
- TransformMap& _transforms;
-
-};
-
-class EmitStringTransform : public Transform
-{
-public:
-
- EmitStringTransform(const string& s) :
- _s(s)
- {
- }
-
- virtual void
- transform(ostream& os, const DocumentInfo*, const string& name, DOM_Node)
- {
- if (!_s.empty())
- {
- os << "<" << name << ">" << _s << "</" << name << ">";
- }
- else
- {
- os << "<" << name << "/>";
- }
- }
-
- virtual ostream&
- print(ostream& os)
- {
- os << "[emit string: \"" << _s << "\"]";
- return os;
- }
-
-private:
-
- string _s;
-};
-
-class EmitAttributeTransform : public Transform
-{
-public:
-
- EmitAttributeTransform(const string& s) :
- _s(s)
- {
- }
-
- virtual void
- transform(ostream& os, const DocumentInfo*, const string& name, DOM_Node)
- {
- os << "<" << name << " " << _s << "/>";
- }
-
- virtual ostream&
- print(ostream& os)
- {
- os << "[emit attribute: \"" << _s << "\"]";
- return os;
- }
-
-private:
-
- string _s;
-
-};
-
-//
-// TODO: all the references are dangerous (DOM_Node&). Should either
-// be const DOM_Node& or DOM_Node.
-//
-class TransformFactory
-{
-public:
-
- TransformFactory(DOM_Document&, DOM_Document&, TransformMap&, TransformMap&);
- ~TransformFactory();
-
- enum Type
- {
- TypeInteger, // byte, short, int, long
- TypeFloat, // float, double
- TypeString,
- TypeEnumeration,
- TypeStruct,
- TypeClass,
- TypeException,
- TypeDictionary,
- TypeDictionaryContent,
- TypeSequence,
- TypeProxy,
- TypeReference,
- TypeInternal
- };
-
-private:
-
- DOM_Node findTypeInDocument(DOM_Document& doc, const ::std::string& local);
- void findType(const DocumentMap&, const DocumentInfo*, const ::std::string&, DOM_Node&, DocumentInfo*&);
-
- Transform* createTransform(const DocumentInfo*, DOM_Node&, Type, const ::std::string&,
- const DocumentInfo*, DOM_Node&, Type, const ::std::string&);
-
- Transform* createTransformByTypeName(const DocumentInfo*, const ::std::string&,
- const DocumentInfo*, const ::std::string&);
-
- Transform* createComplexTypeTransform(DOM_Node&, DOM_Node&);
- Transform* createSimpleTypeTransform(DOM_Node&, DOM_Node&);
-
- Transform* createStructTransform(const DocumentInfo*, DOM_Node&, const DocumentInfo*, DOM_Node&);
- Transform* createStaticClassTransform(DOM_Node&, DOM_Node&);
- Transform* createClassTransform(const DocumentInfo*, DOM_Node&, const DocumentInfo*, DOM_Node&);
- Transform* createSequenceTransform(const DocumentInfo*, DOM_Node&, const DocumentInfo*, DOM_Node&);
- Transform* createDictionaryTransform(const DocumentInfo*, DOM_Node&, const DocumentInfo*, DOM_Node&);
- void createEnumValues(DOM_Node&, ::std::vector< ::std::string>&);
- Transform* createEnumerationTransform(DOM_Node&);
-
- void createSequenceElementTransform(const DocumentInfo*, DOM_Node&, const DocumentInfo*, DOM_Node&,
- ::std::vector<ElementTransform*>&);
- void createClassContentTransform(const DocumentInfo*, DOM_Node&,
- const DocumentInfo*, DOM_Node&,
- ::std::vector<ElementTransform*>&);
-
- Transform* createDefaultInitializedStructTransform(const DocumentInfo*, DOM_Node&);
- void createDefaultInitializedSequenceElementTransform(const DocumentInfo*,
- DOM_Node&, ::std::vector<ElementTransform*>&);
- Transform* createDefaultInitializedTransform(const DocumentInfo*, const ::std::string&);
-
- Type getType(DOM_Node&);
- Type getTypeByName(const DocumentMap&, const DocumentInfo*, const ::std::string&, DOM_Node&, DocumentInfo*&);
-
- DOM_Node findSchemaRoot(const DOM_Document&);
-
- void import(DocumentMap&, const ::std::string&, const ::std::string&);
- void processImport(DOM_Document&, DocumentMap&);
-
- void processElements(const DocumentInfo* info);
-
- //
- // Set of documents. The set of all documents is the entire
- // document set.
- //
- // The map maps from targetNamespace to DocumentInfo.
- //
- DocumentMap _fromDocs;
- DocumentMap _toDocs;
-
- //
- // Map of local@uri element names to transforms. Needed for actual
- // transform.
- //
- TransformMap& _elements;
-
- //
- // Map of local@uri type names to transform. This information
- // cached for creation of the transform.
- //
- TransformMap _types;
-
- //
- // Map of local@uri class transforms (based on static type). This
- // information cached for creation of the transform.
- //
- TransformMap& _staticClassTransforms;
-
- //
- // Map of local@uri transforms for creating new types. This
- // information cached for creation of the transform.
- //
- TransformMap _defaultInitializedTransforms;
-};
-
-TransformFactory::TransformFactory(DOM_Document& fromDoc, DOM_Document& toDoc,
- TransformMap& elements,
- TransformMap& staticClassTransforms) :
- _elements(elements),
- _staticClassTransforms(staticClassTransforms)
-{
- DocumentInfo* fromInfo = new DocumentInfo();
- fromInfo->document = fromDoc;
-
- DocumentInfo* toInfo = new DocumentInfo();
- toInfo->document = toDoc;
-
- DOM_Node fromSchema = findSchemaRoot(fromDoc);
- assert(!fromSchema.isNull());
-
- DOM_Node toSchema = findSchemaRoot(toDoc);
- assert(!toSchema.isNull());
-
- //
- // Create the namespace maps for the two schemas.
- //
- createNSMap(fromInfo, fromSchema);
- createNSMap(toInfo, toSchema);
-
- //
- // Add the root document to the document map.
- //
- _fromDocs.insert(make_pair(fromInfo->targetNamespace, fromInfo));
- _toDocs.insert(make_pair(toInfo->targetNamespace, toInfo));
-
- processImport(fromDoc, _fromDocs);
- processImport(toDoc, _toDocs);
-
- for (DocumentMap::const_iterator p = _fromDocs.begin(); p != _fromDocs.end(); ++p)
- {
- processElements(p->second);
- }
-}
-
-TransformFactory::~TransformFactory()
-{
-}
-
-struct StringTypeTable
-{
- string name;
- TransformFactory::Type type;
-
- bool operator==(const string& rhs) const { return name == rhs; }
-};
-
-TransformFactory::Type
-TransformFactory::getType(DOM_Node& node)
-{
- //
- // Check the appinfo element for the actual type.
- //
- static const StringTypeTable items[] =
- {
- { "enumeration", TypeEnumeration },
- { "struct", TypeStruct },
- { "class", TypeClass },
- { "exception", TypeException },
- { "dictionary", TypeDictionary },
- { "dictionaryContent", TypeDictionaryContent },
- { "sequence", TypeSequence },
- { "proxy", TypeProxy },
- { "reference", TypeReference },
- { "internal", TypeInternal }
- };
- static const StringTypeTable* begin = &items[0];
- static const StringTypeTable* end = &items[sizeof(items)/sizeof(items[0])];
-
- string type = findAppinfoType(node);
-
- const StringTypeTable* p = find(begin, end, type);
- if (p == end)
- {
- throw InvalidSchema(__FILE__, __LINE__);
- }
-
- return p->type;
-}
-
-TransformFactory::Type
-TransformFactory::getTypeByName(const DocumentMap& docs, const DocumentInfo* info, const string& type,
- DOM_Node& n, DocumentInfo*& nInfo)
-{
- //
- // First check to see if the type is a primitive schema type.
- //
- static const StringTypeTable items[] =
- {
- { "xs:byte", TypeInteger },
- { "xs:short", TypeInteger },
- { "xs:int", TypeInteger },
- { "xs:long", TypeInteger },
- { "xs:float", TypeFloat },
- { "xs:double", TypeFloat },
- { "xs:string", TypeString },
- };
- static const StringTypeTable* begin = &items[0];
- static const StringTypeTable* end = &items[sizeof(items)/sizeof(items[0])];
-
- const StringTypeTable* p = find(begin, end, type);
- if (p != end)
- {
- return p->type;
- }
-
- findType(docs, info, type, n, nInfo);
- if (n.isNull())
- {
- throw InvalidSchema(__FILE__, __LINE__);
- }
-
- return getType(n);
-}
-
-Transform*
-TransformFactory::createTransformByTypeName(const DocumentInfo* fromTypeInfo, const string& fromTypeName,
- const DocumentInfo* toTypeInfo, const string& toTypeName)
-{
- DOM_Node from;
- DocumentInfo* fromInfo;
- Type fromType = getTypeByName(_fromDocs, fromTypeInfo, fromTypeName, from, fromInfo);
-
- DOM_Node to;
- DocumentInfo* toInfo;
- Type toType = getTypeByName(_toDocs, toTypeInfo, toTypeName, to, toInfo);
-
- return createTransform(fromInfo, from, fromType, fromTypeName, toInfo, to, toType, toTypeName);
-}
-
-//
-// This really needs to do more or less depending on the type of
-// transform (element, or dealing with complexType/simpleType.
-//
-Transform*
-TransformFactory::createTransform(const DocumentInfo* fromInfo, DOM_Node& from,
- Type fromType, const string& fromTypeName,
- const DocumentInfo* toInfo, DOM_Node& to,
- Type toType, const string& toTypeName)
-{
-
- TransformMap::const_iterator p = _types.find(fromTypeName);
- if (p != _types.end())
- {
- //cout << "returning previously cached transform: " << fromTypeName << endl;
- return p->second;
- }
-
- Transform* transform = 0;
-
- //
- // First handle transforms where the types are equivalent.
- //
- if (fromType == toType)
- {
- switch(fromType)
- {
- case TypeInteger:
- {
- transform = new ValidateIntegerTransform(fromTypeName, toTypeName);
- break;
- }
-
- case TypeFloat:
- {
- transform = new ValidateFloatTransform(fromTypeName, toTypeName);
- break;
- }
-
- case TypeString:
- case TypeProxy: // Same as string
- case TypeReference: // Same as string
- {
- transform = new NilTransform();
- break;
- }
-
- case TypeEnumeration:
- {
- //
- // If the type names are not the same then it's illegal.
- //
- // TODO: This doesn't allow the renaming of types. By
- // removing this comparison renaming of types would be
- // permitted. Should this be permitted?
- //
- if (fromTypeName != toTypeName)
- {
- throw IllegalTransform(__FILE__, __LINE__);
- }
-
- transform = createEnumerationTransform(to);
- break;
- }
-
- case TypeStruct:
- {
- //
- // If the type names are not the same then it's illegal.
- //
- // TODO: This doesn't allow the renaming of types. By
- // removing this comparison renaming of types would be
- // permitted. Should this be permitted?
- //
- if (fromTypeName != toTypeName)
- {
- throw IllegalTransform(__FILE__, __LINE__);
- }
-
- transform = createStructTransform(fromInfo, from, toInfo, to);
- break;
- }
-
- case TypeDictionaryContent:
- {
- //
- // If the type names are not the same then it's illegal.
- //
- // TODO: This doesn't allow the renaming of types. By
- // removing this comparison renaming of types would be
- // permitted. Should this be permitted?
- //
- if (fromTypeName != toTypeName)
- {
- throw IllegalTransform(__FILE__, __LINE__);
- }
-
- transform = createStructTransform(fromInfo, from, toInfo, to);
- break;
- }
-
- case TypeDictionary:
- {
- //
- // If the type names are not the same then it's illegal.
- //
- // TODO: This doesn't allow the renaming of types. By
- // removing this comparison renaming of types would be
- // permitted. Should this be permitted?
- //
- if (fromTypeName != toTypeName)
- {
- throw IllegalTransform(__FILE__, __LINE__);
- }
-
- transform = createDictionaryTransform(fromInfo, from, toInfo, to);
- break;
- }
-
- case TypeSequence:
- {
- //
- // If the type names are not the same then it's illegal.
- //
- // TODO: This doesn't allow the renaming of types. By
- // removing this comparison renaming of types would be
- // permitted. Should this be permitted?
- //
- if (fromTypeName != toTypeName)
- {
- throw IllegalTransform(__FILE__, __LINE__);
- }
-
- transform = createSequenceTransform(fromInfo, from, toInfo, to);
- break;
- }
-
- case TypeClass:
- {
- //
- // If the type names are not the same then it's illegal.
- //
- // TODO: This doesn't allow the renaming of types. By
- // removing this comparison renaming of types would be
- // permitted. Should this be permitted?
- //
- if (fromTypeName != toTypeName)
- {
- throw IllegalTransform(__FILE__, __LINE__);
- }
-
- Transform* staticTransform = createClassTransform(fromInfo, from, toInfo, to);
- return new ClassTransform(_staticClassTransforms);
- break;
- }
-
- case TypeInternal:
- {
- //
- // No transformation created for internal stuff.
- //
- transform = new InternalTransform();
- break;
- }
-
- case TypeException:
- default:
- throw IllegalTransform(__FILE__, __LINE__);
- }
- }
-
- if (transform == 0)
- {
- //
- // Next we have transforms from type-to-type.
- //
- if (fromType == TypeString && toType == TypeEnumeration)
- {
- //
- // String to enumeration transform needs to validate the
- // string as a member of the enumeration values.
- //
- transform = createEnumerationTransform(to);
- }
- else if (fromType == TypeEnumeration && toType == TypeString)
- {
- //
- // Enumeration to string transform is nil transform.
- //
- transform = new NilTransform();
- }
- }
-
- //
- // TODO: struct->class, class->struct.
- //
-
- if (transform == 0)
- {
- throw IllegalTransform(__FILE__, __LINE__);
- }
-
- _types.insert(make_pair(fromTypeName, transform));
-
- return transform;
-}
-
-Transform*
-TransformFactory::createStructTransform(const DocumentInfo* fromInfo, DOM_Node& from,
- const DocumentInfo* toInfo, DOM_Node& to)
-{
- static const string sequenceName = "xs:sequence";
-
- DOM_Node fromSeq = findChild(from, sequenceName);
- DOM_Node toSeq = findChild(to, sequenceName);
- if (fromSeq.isNull() || toSeq.isNull())
- {
- throw InvalidSchema(__FILE__, __LINE__);
- }
-
- StructTransform* nodeTransform = new StructTransform();
-
- vector<ElementTransform*> v;
- createSequenceElementTransform(fromInfo, fromSeq, toInfo, toSeq, v);
- for(vector<ElementTransform*>::const_iterator p = v.begin(); p != v.end(); ++p)
- {
- nodeTransform->append(*p);
- }
-
- return nodeTransform;
-}
-
-void
-TransformFactory::createSequenceElementTransform(const DocumentInfo* fromInfo, DOM_Node& from,
- const DocumentInfo* toInfo, DOM_Node& to,
- vector<ElementTransform*>& v)
-{
- //
- // Allowable transforms:
- //
- // * Node added.
- // * Node removed.
- // * Node moved.
- //
-
- DOM_NodeList fromSeqChildren = from.getChildNodes();
- DOM_NodeList toSeqChildren = to.getChildNodes();
-
- //
- // First run through the to set. This loop handles the node
- // remove, and node changed transforms (plus allowable type
- // changes).
- //
- for (unsigned int i = 0; i < toSeqChildren.getLength(); ++i)
- {
- ElementTransform* transform = 0;
- DOM_Node toChild = toSeqChildren.item(i);
- if (toChild.getNodeType() != DOM_Node::ELEMENT_NODE)
- {
- continue;
- }
-
- static const string element = "xs:element";
- if (toString(toChild.getNodeName()) != element)
- {
- throw InvalidSchema(__FILE__, __LINE__);
- }
-
- string toElementName = getNameAttribute(toChild);
- string toTypeName = getTypeAttribute(toChild);
-
- //
- // Search for the node in the fromSeqChildren list.
- //
- for (unsigned int j = 0; j < fromSeqChildren.getLength(); ++j)
- {
- DOM_Node fromChild = fromSeqChildren.item(j);
-
- if (fromChild.getNodeType() != DOM_Node::ELEMENT_NODE)
- {
- // Skip non element nodes.
- continue;
- }
-
- if (toString(fromChild.getNodeName()) != element)
- {
- throw InvalidSchema(__FILE__, __LINE__);
- }
-
- string fromElementName = getNameAttribute(fromChild);
-
- if (fromElementName == toElementName)
- {
- string fromTypeName = getTypeAttribute(fromChild);
- Transform* t = createTransformByTypeName(fromInfo, fromTypeName, toInfo, toTypeName);
-
- transform = new ElementTransform(toInfo->targetNamespace, toElementName, t);
- assert(transform);
- }
- }
-
- //
- // If there is no transform then this is a new node
- // type. Create a transform to add an empty element of the
- // appropriate type.
- //
- if (!transform)
- {
- Transform* t = createDefaultInitializedTransform(toInfo, toTypeName);
- transform = new ElementTransform(toInfo->targetNamespace, toElementName, t);
- }
-
- v.push_back(transform);
- }
-}
-
-void
-TransformFactory::createClassContentTransform(const DocumentInfo* fromInfo, DOM_Node& from,
- const DocumentInfo* toInfo, DOM_Node& to,
- vector<ElementTransform*>& v)
-{
- static const string complexContentName = "xs:complexContent";
- static const string sequenceName = "xs:sequence";
- static const string extension = "xs:extension";
- static const string baseAttrName = "base";
-
- DOM_Node fromContent = findChild(from, complexContentName);
- DOM_Node toContent = findChild(to, complexContentName);
-
- if (fromContent.isNull() && toContent.isNull())
- {
- //
- // Must be base of a class heirarchy (while this
- // implementation is a little more flexible, with Ice it is
- // limited to ::Ice::Object).
- //
-
- //
- // Look for xs:sequence
- //
- DOM_Node fromSeq = findChild(from, sequenceName);
- DOM_Node toSeq = findChild(from, sequenceName);
-
- if (fromSeq.isNull() || toSeq.isNull())
- {
- throw InvalidSchema(__FILE__, __LINE__);
- }
-
- //
- // TODO: Create cache of base class transforms
- //
- createSequenceElementTransform(fromInfo, fromSeq, toInfo, toSeq, v);
- return;
- }
-
- if (fromContent.isNull() || toContent.isNull())
- {
- throw InvalidSchema(__FILE__, __LINE__);
- }
-
- DOM_Node fromExtension = findChild(fromContent, extension);
- DOM_Node toExtension = findChild(toContent, extension);
-
- if (fromExtension.isNull() || toExtension.isNull())
- {
- throw InvalidSchema(__FILE__, __LINE__);
- }
-
- // TOOD: getAttributeBase?
- string fromBaseName = getAttributeByName(fromExtension, baseAttrName);
- string toBaseName = getAttributeByName(toExtension, baseAttrName);
-
- //
- // Cannot change base class.
- //
- if (fromBaseName != toBaseName)
- {
- throw IllegalTransform(__FILE__, __LINE__);
- }
-
- DOM_Node fromBaseNode;
- DocumentInfo* fromBaseInfo;
- findType(_fromDocs, fromInfo, fromBaseName, fromBaseNode, fromBaseInfo);
- DOM_Node toBaseNode;
- DocumentInfo* toBaseInfo;
- findType(_toDocs, toInfo, toBaseName, toBaseNode, toBaseInfo);
-
- if (fromBaseNode.isNull() || toBaseNode.isNull())
- {
- throw SchemaViolation(__FILE__, __LINE__);
- }
-
- //
- // Find the content transform for the base type.
- //
- createClassContentTransform(fromBaseInfo, fromBaseNode, toBaseInfo, toBaseNode, v);
-
- //
- // Look for xs:sequence
- //
- DOM_Node fromSeq = findChild(fromExtension, sequenceName);
- DOM_Node toSeq = findChild(toExtension, sequenceName);
-
- if (fromSeq.isNull() || toSeq.isNull())
- {
- throw InvalidSchema(__FILE__, __LINE__);
- }
-
- createSequenceElementTransform(fromInfo, fromSeq, toInfo, toSeq, v);
-}
-
-//
-// Schema for class looks like:
-//
-// <xs:complexContent>
-// <xs:extension base=...>
-// <xs:sequence> ...
-//
-Transform*
-TransformFactory::createClassTransform(const DocumentInfo* fromInfo, DOM_Node& from,
- const DocumentInfo* toInfo, DOM_Node& to)
-{
- string type = getNameAttribute(to);
- type += '@';
- type += toInfo->targetNamespace;
-
- TransformMap::const_iterator p = _staticClassTransforms.find(type);
- if (p != _staticClassTransforms.end())
- {
- cout << "returning cached static class transform: " << type << endl;
- return p->second;
- }
-
- vector<ElementTransform*> v;
- createClassContentTransform(fromInfo, from, toInfo, to, v);
-
- StructTransform* nodeTransform = new StructTransform();
- for(vector<ElementTransform*>::const_iterator p = v.begin(); p != v.end(); ++p)
- {
- nodeTransform->append(*p);
- }
-
- _staticClassTransforms.insert(make_pair(type, nodeTransform));
-
- return nodeTransform;
-}
-
-Transform*
-TransformFactory::createSequenceTransform(const DocumentInfo* fromInfo, DOM_Node& from,
- const DocumentInfo* toInfo, DOM_Node& to)
-{
- static const string sequenceName = "xs:sequence";
-
- DOM_Node fromSeq = findChild(from, sequenceName);
- DOM_Node toSeq = findChild(to, sequenceName);
- if (fromSeq.isNull() || toSeq.isNull())
- {
- throw InvalidSchema(__FILE__, __LINE__);
- }
-
- //
- // Sequences have one element - which contains the type of the sequence.
- //
- static const string element = "xs:element";
-
- DOM_Node fromElement = findChild(fromSeq, element);
- DOM_Node toElement = findChild(toSeq, element);
-
- if (fromElement.isNull() || toElement.isNull())
- {
- throw InvalidSchema(__FILE__, __LINE__);
- }
-
- string fromTypeName = getTypeAttribute(fromElement);
- string toTypeName = getTypeAttribute(toElement);
-
- Transform* transform = createTransformByTypeName(fromInfo, fromTypeName, toInfo, toTypeName);
- return new SequenceTransform(transform);
-}
-
-Transform*
-TransformFactory::createDictionaryTransform(const DocumentInfo* fromInfo, DOM_Node& from,
- const DocumentInfo* toInfo, DOM_Node& to)
-{
- static const string sequenceName = "xs:sequence";
-
- DOM_Node fromSeq = findChild(from, sequenceName);
- DOM_Node toSeq = findChild(to, sequenceName);
- if (fromSeq.isNull() || toSeq.isNull())
- {
- throw InvalidSchema(__FILE__, __LINE__);
- }
-
- //
- // Sequences have one element - which contains the type of the sequence.
- //
- static const string element = "xs:element";
-
- DOM_Node fromElement = findChild(fromSeq, element);
- DOM_Node toElement = findChild(toSeq, element);
-
- if (fromElement.isNull() || toElement.isNull())
- {
- throw InvalidSchema(__FILE__, __LINE__);
- }
-
- string fromTypeName = getTypeAttribute(fromElement);
- string toTypeName = getTypeAttribute(toElement);
-
- Transform* transform = createTransformByTypeName(fromInfo, fromTypeName, toInfo, toTypeName);
- return new SequenceTransform(transform);
-}
-
-void
-TransformFactory::createEnumValues(DOM_Node& to, vector<string>& values)
-{
- static const string restriction = "xs:restriction";
-
- DOM_Node toRes = findChild(to, restriction);
- if (toRes.isNull())
- {
- throw InvalidSchema(__FILE__, __LINE__);
- }
-
- //
- // Gather up a list of allowable values.
- //
- DOM_NodeList toResChildren = toRes.getChildNodes();
-
- for (unsigned int i = 0; i < toResChildren.getLength(); ++i)
- {
- DOM_Node toChild = toResChildren.item(i);
-
- if (toChild.getNodeType() != DOM_Node::ELEMENT_NODE)
- {
- continue;
- }
-
- if (toString(toChild.getNodeName()) != "xs:enumeration")
- {
- throw InvalidSchema(__FILE__, __LINE__);
- }
-
- string value = getValueAttribute(toChild);
- if (value.empty())
- {
- throw InvalidSchema(__FILE__, __LINE__);
- }
-
- values.push_back(value);
- }
-}
-
-Transform*
-TransformFactory::createEnumerationTransform(DOM_Node& to)
-{
- vector<string> values;
- createEnumValues(to, values);
-
- return new ValidateEnumerationTransform(values);
-}
-
-void
-TransformFactory::createDefaultInitializedSequenceElementTransform(const DocumentInfo* info, DOM_Node& node,
- vector<ElementTransform*>& v)
-{
- //
- // Allowable transforms:
- //
- // * Node added.
- // * Node removed.
- // * Node moved.
- //
-
- DOM_NodeList seqChild = node.getChildNodes();
- for (unsigned int i = 0; i < seqChild.getLength(); ++i)
- {
- DOM_Node child = seqChild.item(i);
- if (child.getNodeType() != DOM_Node::ELEMENT_NODE)
- {
- continue;
- }
-
- static const string element = "xs:element";
- if (toString(child.getNodeName()) != element)
- {
- throw InvalidSchema(__FILE__, __LINE__);
- }
-
- string elementName = getNameAttribute(child);
- string typeName = getTypeAttribute(child);
-
- Transform* t = createDefaultInitializedTransform(info, typeName);
- ElementTransform* transform = new ElementTransform(info->targetNamespace, elementName, t);
-
- v.push_back(transform);
- }
-}
-
-Transform*
-TransformFactory::createDefaultInitializedStructTransform(const DocumentInfo* info, DOM_Node& node)
-{
- static const string sequenceName = "xs:sequence";
-
- DOM_Node seq = findChild(node, sequenceName);
- if (seq.isNull())
- {
- throw InvalidSchema(__FILE__, __LINE__);
- }
-
- DefaultInitializedStructTransform* transform = new DefaultInitializedStructTransform();
-
- vector<ElementTransform*> v;
- createDefaultInitializedSequenceElementTransform(info, seq, v);
- for(vector<ElementTransform*>::const_iterator p = v.begin(); p != v.end(); ++p)
- {
- transform->append(*p);
- }
-
- return transform;
-}
-
-Transform*
-TransformFactory::createDefaultInitializedTransform(const DocumentInfo* info, const string& typeName)
-{
- string fullTypeName = convertQName(typeName, info);
- TransformMap::const_iterator p = _defaultInitializedTransforms.find(fullTypeName);
- if (p != _defaultInitializedTransforms.end())
- {
- //
- // Return cached empty transform.
- //
- return p->second;
- }
-
- DOM_Node n;
- DocumentInfo* nInfo;
- Type type = getTypeByName(_toDocs, info, typeName, n, nInfo);
-
- Transform* transform = 0;
- switch(type)
- {
- case TypeInteger:
- transform = new EmitStringTransform("0");
- break;
-
- case TypeFloat:
- transform = new EmitStringTransform("0.0");
- break;
-
- case TypeProxy:
- case TypeReference:
- case TypeString:
- //
- // Default string, reference & proxy is empty.
- //
- transform = new EmitStringTransform("");
- break;
-
- case TypeEnumeration:
- {
- vector<string> values;
- createEnumValues(n, values);
- transform = new EmitStringTransform(values[0]);
- break;
- }
-
- case TypeStruct:
- {
- if (n.isNull())
- {
- throw InvalidSchema(__FILE__, __LINE__);
- }
- transform = createDefaultInitializedStructTransform(info, n);
- break;
- }
-
- case TypeDictionary:
- case TypeSequence:
- {
- if (n.isNull())
- {
- throw InvalidSchema(__FILE__, __LINE__);
- }
- transform = new EmitAttributeTransform("length=\"0\"");
- break;
- }
-
- case TypeInternal:
- case TypeException:
- case TypeDictionaryContent:
- case TypeClass:
- default:
- throw IllegalTransform(__FILE__, __LINE__);
- }
-
- if (transform == 0)
- {
- throw IllegalTransform(__FILE__, __LINE__);
- }
-
- _defaultInitializedTransforms.insert(make_pair(fullTypeName, transform));
-
- return transform;
-}
-
-void
-print(DOM_Node& node, unsigned int level)
-{
- if (node.isNull())
- {
- return;
- }
- unsigned int i;
- for (i = 0; i < level; ++i)
- {
- cout << " ";
- }
- ++level;
- cout << toString(node.getNodeName()) << endl;
-
- DOM_NodeList children = node.getChildNodes();
-
- for (i = 0; i < children.getLength(); ++i)
- {
- for (unsigned int l = 0; l < level; ++l)
- {
- cout << " ";
- }
- DOM_Node child = children.item(i);
- print(child, level);
- }
-}
-
-DOM_Node
-TransformFactory::findTypeInDocument(DOM_Document& doc, const string& local)
-{
- DOM_Node schema = findSchemaRoot(doc);
-
- DOM_NodeList children = schema.getChildNodes();
- unsigned int i;
- for (i = 0; i < children.getLength(); ++i)
- {
- DOM_Node child = children.item(i);
- if (child.getNodeType() == DOM_Node::ELEMENT_NODE)
- {
- string na = getNameAttribute(child);
- if (na == local)
- {
- return child;
- }
- }
- }
-
- return DOM_Node();
-}
-
-//
-// This find method takes the type QName and then maps the prefix
-// portion to a namespace in the current document (info). Next the
-// documents which have the given targetNamespace are searched for an
-// element node with that name.
-//
-void
-TransformFactory::findType(const DocumentMap& docs, const DocumentInfo* info, const string& type,
- DOM_Node& n, DocumentInfo*& nInfo)
-{
- string uri;
- string local;
-
- size_t pos = type.find(':');
- if (pos != string::npos)
- {
- string prefix = type.substr(0, pos);
- PrefixURIMap::const_iterator p = info->nsMap.find(prefix);
- if (p == info->nsMap.end())
- {
- throw InvalidSchema(__FILE__, __LINE__);
- }
- uri = p->second;
- local = type.substr(pos+1);
-
- //cout << "looking for : " << local << " @ " << uri << endl;
- }
- else
- {
- uri = info->targetNamespace;
- local = type;
-
- //cout << "looking for : " << local << " @ " << uri << endl;
- }
-
- //
- // Find all documents with targetNamespace == uri
- //
- // TODO: multimap
- //
- DocumentMap::const_iterator p = docs.find(uri);
- if (p != docs.end())
- {
- n = findTypeInDocument(p->second->document, local);
- nInfo = p->second;
- }
-}
-
-DOM_Node
-TransformFactory::findSchemaRoot(const DOM_Document& root)
-{
- //
- // TODO: Can this be static const?
- //
- DOMString schemaURI("http://www.w3.org/2001/XMLSchema");
- DOMString schemaLocalName("schema");
- DOM_Node n;
-
- DOM_NodeList nodes = root.getElementsByTagNameNS(schemaURI, schemaLocalName);
- if (nodes.getLength() != 1)
- {
- throw InvalidSchema(__FILE__, __LINE__);
- }
- return nodes.item(0);
-}
-
-void
-TransformFactory::import(DocumentMap& documents, const string& ns, const string& loc)
-{
- DOMTreeErrorReporter errorReporter;
- DOMParser parser;
- parser.setValidationScheme(DOMParser::Val_Never);
- parser.setDoNamespaces(true);
- parser.setErrorHandler(&errorReporter);
- // Entity resolver?
-
- try
- {
- parser.parse(loc.c_str());
- if (errorReporter.getSawErrors())
- {
- throw InvalidSchema(__FILE__, __LINE__);
- }
- }
- catch (const XMLException& toCatch)
- {
- cout << "Exception message is: \n"
- << DOMString(toCatch.getMessage()) << "\n" ;
- throw InvalidSchema(__FILE__, __LINE__);
- }
- catch (const SAXParseException& toCatch)
- {
- cout << "Exception message is: \n"
- << DOMString(toCatch.getMessage()) << "\n" ;
- throw InvalidSchema(__FILE__, __LINE__);
- }
- catch (...)
- {
- cout << "Unexpected Exception \n" ;
- throw InvalidSchema(__FILE__, __LINE__);
- }
- DOM_Document document = parser.getDocument();
-
- DOM_Node schema = findSchemaRoot(document);
-
- DocumentInfo* info = new DocumentInfo();
- info->document = document;
-
- createNSMap(info, schema);
-
- //
- // Rename the targetNamespace:
- //
- info->targetNamespace = ns;
-
- documents.insert(make_pair(info->targetNamespace, info));
-
- //
- // Process any imports in the imported document.
- //
- processImport(document, documents);
-}
-
-void
-TransformFactory::processImport(DOM_Document& parent, DocumentMap& documents)
-{
- DOM_Node schema = findSchemaRoot(parent);
- assert(!schema.isNull());
-
- DOM_Node child = schema.getFirstChild();
- while (!child.isNull())
- {
- static const string importName = "xs:import";
- string nodeName = toString(child.getNodeName());
- if (nodeName == importName)
- {
- string ns = getAttributeByName(child, "namespace");
- string loc = getAttributeByName(child, "schemaLocation");
-
- import(documents, ns, loc);
- }
- child = child.getNextSibling();
- }
-}
-
-void
-TransformFactory::processElements(const DocumentInfo* info)
-{
- DOM_Node schema = findSchemaRoot(info->document);
-
- DOM_NodeList children = schema.getChildNodes();
- unsigned int i;
- for (i = 0; i < children.getLength(); ++i)
- {
- DOM_Node child = children.item(i);
- if (child.getNodeType() != DOM_Node::ELEMENT_NODE)
- {
- continue;
- }
- string nodeName = toString(child.getNodeName());
-
- static const string element = "xs:element";
-
- if (nodeName != element)
- {
- continue;
- }
-
- string nameAttr = getNameAttribute(child);
-
- DOM_Node to;
- DocumentInfo* toNodeInfo; // Overrides the top-level toInfo.
-
- //
- // In this case info is correct since the element name must be
- // an unqualified name.
- //
- assert(nameAttr.find(':') == string::npos);
-
- findType(_toDocs, info, nameAttr, to, toNodeInfo);
- if (to.isNull())
- {
- cout << "ignoring " << nameAttr << endl;
- //
- // No equivalent in the new schema.
- //
- continue;
- }
-
- string toNodeName = toString(to.getNodeName());
- string toNameAttr = getNameAttribute(to);
-
- //
- // Sanity check.
- //
- assert(toNameAttr == nameAttr);
-
- //
- // Construct the full element name - local@uri
- //
- string fullElementName = nameAttr;
- fullElementName += '@';
- fullElementName += info->targetNamespace;
-
- if (_elements.find(fullElementName) != _elements.end())
- {
- cout << "redefinition of element: " << fullElementName << endl;
- throw InvalidSchema(__FILE__, __LINE__);
- }
-
- string fromTypeName = getTypeAttribute(child);
- string toTypeName = getTypeAttribute(to);
-
- //
- // Ignore anonymous elements (operation contents).
- //
- if (fromTypeName.empty() && toTypeName.empty())
- {
- continue;
- }
-
- //
- // However, it's not legal for an element to change
- // type.
- //
- if (fromTypeName.empty() || toTypeName.empty())
- {
- throw InvalidSchema(__FILE__, __LINE__);
- }
-
- Transform* transform = createTransformByTypeName(info, fromTypeName, toNodeInfo, toTypeName);
- //cout << "new element: " << fullElementName << endl;
-
- //
- // Add association between name & transform
- //
- _elements.insert(make_pair(fullElementName, transform));
- }
-}
-
-
-Transformer::Transformer(DOM_Document& fromDoc, DOM_Document& toDoc)
-{
- TransformFactory factory(fromDoc, toDoc, _elements, _staticClassTransforms);
-}
-
-Transformer::~Transformer()
-{
-}
-
-void
-Transformer::transform(ostream& os, DOM_Document& doc)
-{
- DOM_Node root = doc.getFirstChild();
- DocumentInfo info;
- info.document = doc;
- createNSMap(&info, root);
-
- DOM_NodeList children = root.getChildNodes();
- for (unsigned int i = 0; i < children.getLength(); ++i)
- {
- DOM_Node child = children.item(i);
- if (child.getNodeType() != DOM_Node::ELEMENT_NODE)
- {
- continue;
- }
-
- string nodeName = toString(child.getNodeName());
-
- //
- // Create local@namespace version of the element name.
- //
- string n = convertQName(nodeName, &info);
-
- //cout << "looking for : " << n << endl;
-
- TransformMap::const_iterator p = _elements.find(n);
- if (p == _elements.end())
- {
- cerr << "cannot find element: " << n << endl;
- throw SchemaViolation(__FILE__, __LINE__);
- }
-
- p->second->transform(os, &info, nodeName, child);
- }
-}
-