summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
authorMark Spruiell <mes@zeroc.com>2002-11-26 20:08:31 +0000
committerMark Spruiell <mes@zeroc.com>2002-11-26 20:08:31 +0000
commitb5dd927787cba09d11ed8980b9620c9a6518b099 (patch)
tree00577631abbc989c4c70cd5d45cb904e0f9be44f /cpp
parentFix (diff)
downloadice-b5dd927787cba09d11ed8980b9620c9a6518b099.tar.bz2
ice-b5dd927787cba09d11ed8980b9620c9a6518b099.tar.xz
ice-b5dd927787cba09d11ed8980b9620c9a6518b099.zip
check for missing class types in object instances add optional removal of
object references and instances for missing types transaction fixes
Diffstat (limited to 'cpp')
-rw-r--r--cpp/include/XMLTransform/XMLTransform.h52
-rw-r--r--cpp/src/XMLTransform/TransformDB.cpp19
-rw-r--r--cpp/src/XMLTransform/XMLTransform.cpp493
-rw-r--r--cpp/test/XMLTransform/transform/Populate.cpp104
4 files changed, 516 insertions, 152 deletions
diff --git a/cpp/include/XMLTransform/XMLTransform.h b/cpp/include/XMLTransform/XMLTransform.h
index 97ad5f34775..b455b70d484 100644
--- a/cpp/include/XMLTransform/XMLTransform.h
+++ b/cpp/include/XMLTransform/XMLTransform.h
@@ -20,6 +20,8 @@
#include <xercesc/dom/DOM.hpp>
+#include <map>
+
#ifdef WIN32
# ifdef XML_TRANSFORM_API_EXPORTS
# define XML_TRANSFORM_API __declspec(dllexport)
@@ -102,6 +104,23 @@ public:
};
//
+// Raised if a type was not found in the new schema.
+//
+class XML_TRANSFORM_API MissingTypeException : public ::IceUtil::Exception
+{
+public:
+
+ MissingTypeException(const char*, int);
+
+ virtual ::std::string ice_name() const;
+ virtual void ice_print(::std::ostream&) const;
+ virtual ::IceUtil::Exception* ice_clone() const;
+ virtual void ice_throw() const;
+
+ ::std::string reason;
+};
+
+//
// Raised in the case of a general transformation failure.
//
class XML_TRANSFORM_API TransformException : public ::IceUtil::Exception
@@ -158,7 +177,12 @@ public:
Transform();
virtual ~Transform();
- virtual void transform(::IceUtil::XMLOutput&, const DocumentInfoPtr&, const ::std::string&, DOMNode*) = 0;
+ typedef ::std::map< ::std::string, ::std::string > MissingTypeMap;
+
+ virtual void transform(::IceUtil::XMLOutput&, const DocumentInfoPtr&, const ::std::string&, DOMNode*,
+ const MissingTypeMap&) = 0;
+ virtual void checkMissingTypes(const DocumentInfoPtr&, DOMNode*, const MissingTypeMap&) { }
+ virtual void collectMissingTypes(const DocumentInfoPtr&, DOMNode*, MissingTypeMap&) { }
virtual ::std::ostream& print(::std::ostream&) = 0;
};
@@ -181,7 +205,7 @@ public:
DOMDocument*, DOMDocument*);
~Transformer();
- void transform(::IceUtil::XMLOutput&, DOMDocument*, bool = true);
+ void transform(::IceUtil::XMLOutput&, DOMDocument*, bool, bool = true);
private:
@@ -200,28 +224,36 @@ private:
class XML_TRANSFORM_API DBTransformer
{
- void transform(const Freeze::DBEnvironmentPtr&, const Freeze::DBPtr&, const Ice::StringSeq&, const Ice::StringSeq&,
- const Ice::StringSeq&, const Ice::StringSeq&, DOMDocument*, DOMDocument*);
-
public:
- DBTransformer();
+ DBTransformer(const Freeze::DBEnvironmentPtr&, const Freeze::DBPtr&, const Ice::StringSeq&, const Ice::StringSeq&,
+ const Ice::StringSeq&, const Ice::StringSeq&, bool);
~DBTransformer();
//
// This version allows the caller to specify the filenames for the
// old and new schemas.
//
- void transform(const Freeze::DBEnvironmentPtr&, const Freeze::DBPtr&, const Ice::StringSeq&, const Ice::StringSeq&,
- const Ice::StringSeq&, const Ice::StringSeq&, const std::string&, const std::string&);
+ void transform(const std::string&, const std::string&);
//
// This version allows the caller to specify a single schema for
// transformation. This is commonly used for schemas whose formal
// types don't change, but whose actual (instance) types do change.
//
- void transform(const Freeze::DBEnvironmentPtr&, const Freeze::DBPtr&, const Ice::StringSeq&, const Ice::StringSeq&,
- const Ice::StringSeq&, const Ice::StringSeq&, const std::string&);
+ void transform(const std::string&);
+
+private:
+
+ void transform(DOMDocument*, DOMDocument*);
+
+ Freeze::DBEnvironmentPtr _dbEnv;
+ Freeze::DBPtr _db;
+ Ice::StringSeq _loadOld;
+ Ice::StringSeq _loadNew;
+ Ice::StringSeq _pathOld;
+ Ice::StringSeq _pathNew;
+ bool _force;
};
} // End namespace XMLTransform
diff --git a/cpp/src/XMLTransform/TransformDB.cpp b/cpp/src/XMLTransform/TransformDB.cpp
index d34bf79d6b7..cfee8e9184b 100644
--- a/cpp/src/XMLTransform/TransformDB.cpp
+++ b/cpp/src/XMLTransform/TransformDB.cpp
@@ -31,6 +31,7 @@ usage(const string& appName)
"--load-new PATH Load new schema from the given file or directory.\n"
"--path-old DIR Add directory DIR to the old schema import search path.\n"
"--path-new DIR Add directory DIR to the new schema import search path.\n"
+ "--force Force removal of objects whose types cannot be found.\n"
"-h, --help Show this message.\n"
"-v, --version Display the Ice version.\n"
;
@@ -51,6 +52,7 @@ main(int argc, char* argv[])
bool evictor = false;
Ice::StringSeq loadOld, loadNew;
Ice::StringSeq pathOld, pathNew;
+ bool force = false;
int idx = 1;
while(idx < argc)
@@ -128,6 +130,15 @@ main(int argc, char* argv[])
}
--argc;
}
+ else if(strcmp(argv[idx], "--force") == 0)
+ {
+ force = true;
+ for(int i = idx ; i + 1 < argc ; ++i)
+ {
+ argv[i] = argv[i + 1];
+ }
+ --argc;
+ }
else if(strcmp(argv[idx], "-h") == 0 || strcmp(argv[idx], "--help") == 0)
{
usage(argv[0]);
@@ -159,9 +170,9 @@ main(int argc, char* argv[])
try
{
dbEnv = Freeze::initializeWithTxn(communicator, argv[1]);
- db = dbEnv->openDB(argv[2], false);
+ db = dbEnv->openDBWithTxn(0, argv[2], false);
- XMLTransform::DBTransformer transformer;
+ XMLTransform::DBTransformer transformer(dbEnv, db, loadOld, loadNew, pathOld, pathNew, force);
if(evictor)
{
@@ -183,11 +194,11 @@ main(int argc, char* argv[])
" <xs:element name=\"Key\" type=\"_internal.Ice.IdentityType\"/>"
" <xs:element name=\"Value\" type=\"ice:_internal.objectType\"/></xs:schema>";
- transformer.transform(dbEnv, db, loadOld, loadNew, pathOld, pathNew, schema);
+ transformer.transform(schema);
}
else
{
- transformer.transform(dbEnv, db, loadOld, loadNew, pathOld, pathNew, argv[3], argv[4]);
+ transformer.transform(argv[3], argv[4]);
}
}
catch(const Freeze::DBNotFoundException&)
diff --git a/cpp/src/XMLTransform/XMLTransform.cpp b/cpp/src/XMLTransform/XMLTransform.cpp
index cacfb377d20..217a0080ef3 100644
--- a/cpp/src/XMLTransform/XMLTransform.cpp
+++ b/cpp/src/XMLTransform/XMLTransform.cpp
@@ -168,6 +168,36 @@ XMLTransform::SchemaViolation::ice_throw() const
throw *this;
}
+XMLTransform::MissingTypeException::MissingTypeException(const char* file, int line) :
+ Exception(file, line)
+{
+}
+
+string
+XMLTransform::MissingTypeException::ice_name() const
+{
+ return "MissingTypeException";
+}
+
+void
+XMLTransform::MissingTypeException::ice_print(ostream& out) const
+{
+ Exception::ice_print(out);
+ out << ":\n" << reason;
+}
+
+::IceUtil::Exception*
+XMLTransform::MissingTypeException::ice_clone() const
+{
+ return new MissingTypeException(*this);
+}
+
+void
+XMLTransform::MissingTypeException::ice_throw() const
+{
+ throw *this;
+}
+
XMLTransform::TransformException::TransformException(const char* file, int line) :
Exception(file, line)
{
@@ -511,7 +541,7 @@ public:
}
virtual void
- transform(::IceUtil::XMLOutput& os, const DocumentInfoPtr&, const string&, DOMNode* node)
+ transform(::IceUtil::XMLOutput& os, const DocumentInfoPtr&, const string&, DOMNode* node, const MissingTypeMap&)
{
if(node == 0)
{
@@ -543,7 +573,7 @@ public:
}
virtual void
- transform(::IceUtil::XMLOutput&, const DocumentInfoPtr&, const string&, DOMNode*)
+ transform(::IceUtil::XMLOutput&, const DocumentInfoPtr&, const string&, DOMNode*, const MissingTypeMap&)
{
throw SchemaViolation(__FILE__, __LINE__);
}
@@ -576,7 +606,7 @@ public:
}
virtual void
- transform(::IceUtil::XMLOutput& os, const DocumentInfoPtr&, const string&, DOMNode*)
+ transform(::IceUtil::XMLOutput& os, const DocumentInfoPtr&, const string&, DOMNode*, const MissingTypeMap&)
{
}
@@ -605,9 +635,16 @@ public:
}
virtual void
- transform(::IceUtil::XMLOutput& os, const DocumentInfoPtr& info, const string&, DOMNode* node)
+ transform(::IceUtil::XMLOutput& os, const DocumentInfoPtr& info, const string&, DOMNode* node,
+ const MissingTypeMap& map)
+ {
+ _transform->transform(os, info, _name, node, map);
+ }
+
+ virtual void
+ checkMissingTypes(const DocumentInfoPtr& info, DOMNode* node, const MissingTypeMap& map)
{
- _transform->transform(os, info, _name, node);
+ _transform->checkMissingTypes(info, node, map);
}
virtual ostream&
@@ -645,7 +682,7 @@ public:
}
virtual void
- transform(::IceUtil::XMLOutput& os, const DocumentInfoPtr&, const string&, DOMNode* node)
+ transform(::IceUtil::XMLOutput& os, const DocumentInfoPtr&, const string&, DOMNode* node, const MissingTypeMap&)
{
if(node == 0)
{
@@ -693,7 +730,7 @@ public:
}
virtual void
- transform(::IceUtil::XMLOutput& os, const DocumentInfoPtr&, const string&, DOMNode* node)
+ transform(::IceUtil::XMLOutput& os, const DocumentInfoPtr&, const string&, DOMNode* node, const MissingTypeMap&)
{
if(node == 0)
{
@@ -769,7 +806,7 @@ public:
}
virtual void
- transform(::IceUtil::XMLOutput& os, const DocumentInfoPtr&, const string&, DOMNode* node)
+ transform(::IceUtil::XMLOutput& os, const DocumentInfoPtr&, const string&, DOMNode* node, const MissingTypeMap&)
{
if(node == 0)
{
@@ -812,22 +849,52 @@ public:
}
virtual void
- transform(::IceUtil::XMLOutput& os, const DocumentInfoPtr& info, const string&, DOMNode* node)
+ transform(::IceUtil::XMLOutput& os, const DocumentInfoPtr& info, const string&, DOMNode* node,
+ const MissingTypeMap& map)
{
if(node == 0)
{
throw SchemaViolation(__FILE__, __LINE__);
}
+
+ string length = getAttributeByName(node, "length");
+ long l = atol(length.c_str());
+
+ //
+ // Before we emit anything, we check for missing types.
+ // If a MissingTypeException is raised for an element,
+ // that element will be skipped. We have to do this in
+ // advance in order to properly compute the sequence length.
+ //
+ DOMNodeList* children = node->getChildNodes();
+ unsigned int i;
+ for(i = 0; i < children->getLength(); ++i)
+ {
+ DOMNode* child = children->item(i);
+ if(child->getNodeType() != DOMNode::ELEMENT_NODE)
+ {
+ continue;
+ }
+
+ try
+ {
+ _transform->checkMissingTypes(info, child, map);
+ }
+ catch(const MissingTypeException& ex)
+ {
+ --l;
+ }
+ }
+
string name = toString(node->getNodeName());
os << ::IceUtil::se(name);
- string length = getAttributeByName(node, "length");
- os << ::IceUtil::attr("length", length);
+ ostringstream lstr;
+ lstr << l;
- long l = atol(length.c_str());
+ os << ::IceUtil::attr("length", lstr.str());
- DOMNodeList* children = node->getChildNodes();
- for(unsigned int i = 0; i < children->getLength(); ++i)
+ for(i = 0; i < children->getLength(); ++i)
{
DOMNode* child = children->item(i);
if(child->getNodeType() != DOMNode::ELEMENT_NODE)
@@ -840,13 +907,40 @@ public:
{
throw SchemaViolation(__FILE__, __LINE__);
}
- _transform->transform(os, info, nodeName, child);
- --l;
+
+ try
+ {
+ _transform->transform(os, info, nodeName, child, map);
+ }
+ catch(const MissingTypeException&)
+ {
+ // Skip this element
+ }
}
os << ::IceUtil::ee;
}
+ virtual void
+ checkMissingTypes(const DocumentInfoPtr& info, DOMNode* node, const MissingTypeMap& map)
+ {
+ if(node == 0)
+ {
+ throw SchemaViolation(__FILE__, __LINE__);
+ }
+ DOMNodeList* children = node->getChildNodes();
+ for(unsigned int i = 0; i < children->getLength(); ++i)
+ {
+ DOMNode* child = children->item(i);
+ if(child->getNodeType() != DOMNode::ELEMENT_NODE)
+ {
+ continue;
+ }
+
+ _transform->checkMissingTypes(info, child, map);
+ }
+ }
+
virtual ostream&
print(ostream& os)
{
@@ -887,7 +981,8 @@ public:
}
virtual void
- transform(::IceUtil::XMLOutput& os, const DocumentInfoPtr& info, const string&, DOMNode* node)
+ transform(::IceUtil::XMLOutput& os, const DocumentInfoPtr& info, const string&, DOMNode* node,
+ const MissingTypeMap& map)
{
if(node == 0)
{
@@ -904,12 +999,43 @@ public:
for(vector<ElementTransformPtr>::const_iterator p = _transforms.begin(); p != _transforms.end(); ++p)
{
DOMNode* child = findChild(node, (*p)->namespaceURI(), (*p)->name());
- (*p)->transform(os, info, (*p)->name(), child);
+ try
+ {
+ (*p)->transform(os, info, (*p)->name(), child, map);
+ }
+ catch(const MissingTypeException& ex)
+ {
+ //
+ // A struct member cannot be removed if it refers to
+ // a missing type, so we translate MissingTypeException
+ // into SchemaViolation.
+ //
+ SchemaViolation e(__FILE__, __LINE__);
+ ostringstream ostr;
+ ostr << "error during transform of struct member `" << (*p)->name() << "':" << endl << ex.reason;
+ e.reason = ostr.str();
+ throw e;
+ }
}
os << ::IceUtil::ee;
}
+ virtual void
+ checkMissingTypes(const DocumentInfoPtr& info, DOMNode* node, const MissingTypeMap& map)
+ {
+ if(node == 0)
+ {
+ throw SchemaViolation(__FILE__, __LINE__);
+ }
+
+ for(vector<ElementTransformPtr>::const_iterator p = _transforms.begin(); p != _transforms.end(); ++p)
+ {
+ DOMNode* child = findChild(node, (*p)->namespaceURI(), (*p)->name());
+ (*p)->checkMissingTypes(info, child, map);
+ }
+ }
+
virtual ostream&
print(ostream& os)
{
@@ -944,28 +1070,61 @@ public:
}
virtual void
- transform(::IceUtil::XMLOutput& os, const DocumentInfoPtr& info, const string& name, DOMNode* node)
+ transform(::IceUtil::XMLOutput& os, const DocumentInfoPtr& info, const string& name, DOMNode* node,
+ const MissingTypeMap& map)
{
- //
- // First check for the "href" attribute, which indicates a
- // reference to another object. We simply emit the node
- // as-is. The referenced object, which is a child of the
- // root node, will be transformed automatically.
- //
- string id = getAttributeByName(node, "href");
- if(!id.empty())
+ //
+ // If the object is null simply emit the node as-is.
+ //
+ string nil = getAttributeByName(node, "xsi:nil");
+ if(!nil.empty() && nil == "true")
{
os << node;
return;
}
+ //
+ // Otherwise, xsi:type must be present.
+ //
+ string type = getAttributeByName(node, "xsi:type");
+ if(type.empty())
+ {
+ throw SchemaViolation(__FILE__, __LINE__);
+ }
+
+ string n = convertQName(type, info);
+
//
- // If the object is null simply emit the node as-is.
+ // 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())
+ {
+ //
+ // No transformation found for this type. This should
+ // have already been discovered by collectMissingTypes.
+ //
+ string id = getAttributeByName(node, "id");
+ assert(!id.empty());
+ MissingTypeMap::const_iterator q = map.find(id);
+ assert(q != map.end());
+ MissingTypeException ex(__FILE__, __LINE__);
+ ex.reason = "unable to find a transformation for type `" + n + "'";
+ throw ex;
+ }
+ p->second->transform(os, info, name, node, map);
+ }
+
+ virtual void
+ collectMissingTypes(const DocumentInfoPtr& info, DOMNode* node, MissingTypeMap& map)
+ {
+ //
+ // Check if the object is null.
//
string nil = getAttributeByName(node, "xsi:nil");
if(!nil.empty() && nil == "true")
{
- os << node;
return;
}
@@ -987,11 +1146,12 @@ public:
TransformMap::const_iterator p = _transforms->find(n);
if(p == _transforms->end())
{
- SchemaViolation ex(__FILE__, __LINE__);
- ex.reason = "unable to find a transformation for type `" + n + "'";
- throw ex;
+ string id = getAttributeByName(node, "id");
+ assert(!id.empty());
+ string sliceType = getAttributeByName(node, "type");
+ assert(!sliceType.empty());
+ map.insert(make_pair(id, sliceType));
}
- p->second->transform(os, info, name, node);
}
virtual ostream&
@@ -1010,6 +1170,92 @@ private:
typedef ::IceUtil::Handle<ClassTransform> ClassTransformPtr;
//
+// Transform for an object reference.
+//
+class ReferenceTransform : public Transform
+{
+public:
+
+ ReferenceTransform()
+ {
+ }
+
+ virtual void
+ transform(::IceUtil::XMLOutput& os, const DocumentInfoPtr& info, const string& name, DOMNode* node,
+ const MissingTypeMap& map)
+ {
+ //
+ // First check for the "href" attribute, which indicates a
+ // reference to another object. The referenced object, which
+ // is a child of the root node, will be transformed automatically.
+ //
+ string id = getAttributeByName(node, "href");
+ if(!id.empty())
+ {
+ id.erase(0, 1); // Remove the '#'.
+ //
+ // If the id is present in the missing type map, then
+ // we must raise an exception.
+ //
+ MissingTypeMap::const_iterator q = map.find(id);
+ if(q != map.end())
+ {
+ MissingTypeException ex(__FILE__, __LINE__);
+ ex.reason = "unable to find a transformation for type `" + q->second + "'";
+ throw ex;
+ }
+
+ os << node;
+ return;
+ }
+
+ //
+ // If there is no "href" attribute, then the object must be nil.
+ //
+ string nil = getAttributeByName(node, "xsi:nil");
+ if(nil.empty())
+ {
+ throw SchemaViolation(__FILE__, __LINE__);
+ }
+ os << node;
+ }
+
+ virtual void
+ checkMissingTypes(const DocumentInfoPtr& info, DOMNode* node, const MissingTypeMap& map)
+ {
+ //
+ // First check for the "href" attribute, which indicates a
+ // reference to another object.
+ //
+ string id = getAttributeByName(node, "href");
+ if(!id.empty())
+ {
+ id.erase(0, 1); // Remove the '#'.
+ //
+ // If the id is present in the missing types map, then
+ // we must raise an exception.
+ //
+ MissingTypeMap::const_iterator q = map.find(id);
+ if(q != map.end())
+ {
+ MissingTypeException ex(__FILE__, __LINE__);
+ ex.reason = "unable to find a transformation for type `" + q->second + "'";
+ throw ex;
+ }
+ }
+ }
+
+ virtual ostream&
+ print(ostream& os)
+ {
+ os << "[reference]\n";
+ return os;
+ }
+};
+
+typedef ::IceUtil::Handle<ReferenceTransform> ReferenceTransformPtr;
+
+//
// This transform produces a new struct. The contents of the struct will contain whatever default value is
// appropriate.
//
@@ -1023,7 +1269,8 @@ public:
}
virtual void
- transform(::IceUtil::XMLOutput& os, const DocumentInfoPtr& info, const string& name, DOMNode* node)
+ transform(::IceUtil::XMLOutput& os, const DocumentInfoPtr& info, const string& name, DOMNode* node,
+ const MissingTypeMap& map)
{
os << ::IceUtil::se(name);
@@ -1031,7 +1278,7 @@ public:
for(vector<ElementTransformPtr>::const_iterator p = _transforms.begin(); p != _transforms.end(); ++p)
{
- (*p)->transform(os, info, (*p)->name(), child);
+ (*p)->transform(os, info, (*p)->name(), child, map);
}
os << ::IceUtil::ee;
@@ -1069,7 +1316,7 @@ public:
}
virtual void
- transform(::IceUtil::XMLOutput& os, const DocumentInfoPtr&, const string& name, DOMNode*)
+ transform(::IceUtil::XMLOutput& os, const DocumentInfoPtr&, const string& name, DOMNode*, const MissingTypeMap&)
{
os << ::IceUtil::se(name);
os << ::IceUtil::startEscapes << _s << ::IceUtil::endEscapes;
@@ -1104,7 +1351,7 @@ public:
}
virtual void
- transform(::IceUtil::XMLOutput& os, const DocumentInfoPtr&, const string& name, DOMNode*)
+ transform(::IceUtil::XMLOutput& os, const DocumentInfoPtr&, const string& name, DOMNode*, const MissingTypeMap&)
{
os << ::IceUtil::se(name);
os << ::IceUtil::attr(_attrName, _attrValue);
@@ -1389,9 +1636,9 @@ XMLTransform::TransformFactory::create(DOMDocument* fromDoc, DOMDocument* toDoc,
//
// Finally process each element from the old schema document.
//
- for(DocumentMap::const_iterator p = _fromDocs.begin(); p != _fromDocs.end(); ++p)
+ for(DocumentMap::const_iterator q = _fromDocs.begin(); q != _fromDocs.end(); ++q)
{
- processElements(p->second);
+ processElements(q->second);
}
}
@@ -1909,12 +2156,17 @@ XMLTransform::TransformFactory::createTransform(const DocumentInfoPtr& fromTypeI
case TypeString:
case TypeProxy: // Same as string
- case TypeReference: // Same as string
{
transform = new NilTransform();
break;
}
+ case TypeReference:
+ {
+ transform = new ReferenceTransform();
+ break;
+ }
+
case TypeEnumeration:
{
//
@@ -1956,48 +2208,10 @@ XMLTransform::TransformFactory::createTransform(const DocumentInfoPtr& fromTypeI
break;
}
+ //
+ // A dictionary is treated as a sequence of struct.
+ //
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)
- {
- IllegalTransform ex(__FILE__, __LINE__);
- ex.reason = "renaming types is not supported (from " + fromTypeName + " to " + toTypeName + ")";
- throw ex;
- }
-
- DOMNode* fromSeq = findChild(from, sequenceElementName);
- DOMNode* toSeq = findChild(to, sequenceElementName);
- if(fromSeq == 0 || toSeq == 0)
- {
- InvalidSchema ex(__FILE__, __LINE__);
- ex.reason = "missing sequence element in " + fromTypeName;
- throw ex;
- }
-
- //
- // Sequences have one element - which contains the type of the sequence.
- //
- DOMNode* fromElement = findChild(fromSeq, elementElementName);
- DOMNode* toElement = findChild(toSeq, elementElementName);
-
- if(fromElement == 0 || toElement == 0)
- {
- InvalidSchema ex(__FILE__, __LINE__);
- ex.reason = "invalid sequence element in " + fromTypeName;
- throw ex;
- }
-
- transform = new SequenceTransform(createTransform(fromInfo, getTypeAttribute(fromElement),
- toInfo, getTypeAttribute(toElement)));
- break;
- }
-
case TypeSequence:
{
//
@@ -2033,7 +2247,7 @@ XMLTransform::TransformFactory::createTransform(const DocumentInfoPtr& fromTypeI
ex.reason = "invalid sequence element in " + fromTypeName;
throw ex;
}
-
+
transform = new SequenceTransform(createTransform(fromInfo, getTypeAttribute(fromElement),
toInfo, getTypeAttribute(toElement)));
break;
@@ -2529,7 +2743,7 @@ XMLTransform::Transformer::~Transformer()
}
void
-XMLTransform::Transformer::transform(::IceUtil::XMLOutput& os, DOMDocument* doc, bool emitRoot)
+XMLTransform::Transformer::transform(::IceUtil::XMLOutput& os, DOMDocument* doc, bool force, bool emitRoot)
{
DOMNode* root = doc->getFirstChild();
@@ -2549,6 +2763,12 @@ XMLTransform::Transformer::transform(::IceUtil::XMLOutput& os, DOMDocument* doc,
DocumentInfoPtr info = new DocumentInfo(doc, false, root);
DOMNodeList* children = root->getChildNodes();
+
+ //
+ // Collect the missing types from all elements before
+ // transforming.
+ //
+ Transform::MissingTypeMap map;
for(i = 0; i < children->getLength(); ++i)
{
DOMNode* child = children->item(i);
@@ -2572,7 +2792,68 @@ XMLTransform::Transformer::transform(::IceUtil::XMLOutput& os, DOMDocument* doc,
throw ex;
}
- p->second->transform(os, info, nodeName, child);
+ p->second->collectMissingTypes(info, child, map);
+ }
+
+ //
+ // If there are missing types, and we are not told to
+ // force removal of objects, then raise an exception.
+ //
+ if(!map.empty() && !force)
+ {
+ set<string> types;
+ for(Transform::MissingTypeMap::const_iterator q = map.begin(); q != map.end(); ++q)
+ {
+ types.insert(q->second);
+ }
+ ostringstream ostr;
+ ostr << "The following types could not be found:";
+ for(set<string>::const_iterator r = types.begin(); r != types.end(); ++r)
+ {
+ ostr << endl << " " << *r;
+ }
+ MissingTypeException ex(__FILE__, __LINE__);
+ ex.reason = ostr.str();
+ throw ex;
+ }
+
+ //
+ // Transform.
+ //
+ for(i = 0; i < children->getLength(); ++i)
+ {
+ DOMNode* child = children->item(i);
+ if(child->getNodeType() != DOMNode::ELEMENT_NODE)
+ {
+ continue;
+ }
+
+ string nodeName = toString(child->getNodeName());
+
+ //
+ // Create local@namespace version of the element name.
+ //
+ string n = convertQName(nodeName, info);
+
+ TransformMap::const_iterator p = _elements.find(n);
+ if(p == _elements.end())
+ {
+ SchemaViolation ex(__FILE__, __LINE__);
+ ex.reason = "cannot find element " + n;
+ throw ex;
+ }
+
+ try
+ {
+ p->second->transform(os, info, nodeName, child, map);
+ }
+ catch(const MissingTypeException&)
+ {
+ if(!force)
+ {
+ throw;
+ }
+ }
}
if(emitRoot)
@@ -2581,7 +2862,12 @@ XMLTransform::Transformer::transform(::IceUtil::XMLOutput& os, DOMDocument* doc,
}
}
-XMLTransform::DBTransformer::DBTransformer()
+XMLTransform::DBTransformer::DBTransformer(const DBEnvironmentPtr& dbEnv, const DBPtr& db,
+ const Ice::StringSeq& loadOld, const Ice::StringSeq& loadNew,
+ const Ice::StringSeq& pathOld, const Ice::StringSeq& pathNew,
+ bool force) :
+ _dbEnv(dbEnv), _db(db), _loadOld(loadOld), _loadNew(loadNew), _pathOld(pathOld), _pathNew(pathNew),
+ _force(force)
{
try
{
@@ -2600,10 +2886,7 @@ XMLTransform::DBTransformer::~DBTransformer()
}
void
-XMLTransform::DBTransformer::transform(const DBEnvironmentPtr& dbEnv, const DBPtr& db,
- const Ice::StringSeq& loadOld, const Ice::StringSeq& loadNew,
- const Ice::StringSeq& pathOld, const Ice::StringSeq& pathNew,
- DOMDocument* oldSchema, DOMDocument* newSchema)
+XMLTransform::DBTransformer::transform(DOMDocument* oldSchema, DOMDocument* newSchema)
{
DOMTreeErrorReporter errReporter;
@@ -2617,7 +2900,7 @@ XMLTransform::DBTransformer::transform(const DBEnvironmentPtr& dbEnv, const DBPt
string reason;
try
{
- Transformer transformer(loadOld, loadNew, pathOld, pathNew, oldSchema, newSchema);
+ Transformer transformer(_loadOld, _loadNew, _pathOld, _pathNew, oldSchema, newSchema);
//
// Header and footer for instance documents.
@@ -2634,7 +2917,7 @@ XMLTransform::DBTransformer::transform(const DBEnvironmentPtr& dbEnv, const DBPt
// keys first, then update the records.
//
vector<Key> keys;
- cursor = db->getCursor();
+ cursor = _db->getCursor();
do
{
Key k;
@@ -2646,7 +2929,7 @@ XMLTransform::DBTransformer::transform(const DBEnvironmentPtr& dbEnv, const DBPt
cursor->close();
cursor = 0;
- txn = dbEnv->startTransaction();
+ txn = _dbEnv->startTransaction();
vector<Key>::const_iterator p;
for(p = keys.begin(); p != keys.end(); ++p)
@@ -2666,7 +2949,7 @@ XMLTransform::DBTransformer::transform(const DBEnvironmentPtr& dbEnv, const DBPt
ostringstream keyStream;
IceUtil::XMLOutput keyOut(keyStream);
- transformer.transform(keyOut, keyDoc, false);
+ transformer.transform(keyOut, keyDoc, _force, false);
Key newKey;
const std::string& keyStr = keyStream.str();
@@ -2676,7 +2959,7 @@ XMLTransform::DBTransformer::transform(const DBEnvironmentPtr& dbEnv, const DBPt
//
// Transform value
//
- Value value = db->getWithTxn(txn, k);
+ Value value = _db->getWithTxn(txn, k);
string fullValue;
fullValue.append(header);
fullValue.append(&value[0], value.size());
@@ -2687,7 +2970,7 @@ XMLTransform::DBTransformer::transform(const DBEnvironmentPtr& dbEnv, const DBPt
ostringstream valueStream;
IceUtil::XMLOutput valueOut(valueStream);
- transformer.transform(valueOut, valueDoc, false);
+ transformer.transform(valueOut, valueDoc, _force, false);
Value newValue;
const std::string& valueStr = valueStream.str();
@@ -2698,15 +2981,15 @@ XMLTransform::DBTransformer::transform(const DBEnvironmentPtr& dbEnv, const DBPt
// Update database - only insert new key,value pair if the transformed
// key doesn't match an existing key.
//
- db->delWithTxn(txn, k);
- if(db->containsWithTxn(txn, newKey))
+ _db->delWithTxn(txn, k);
+ if(_db->containsWithTxn(txn, newKey))
{
reason = "transformed key matches an existing record:\n" + keyStr;
txn->abort();
txn = 0;
break;
}
- db->putWithTxn(txn, newKey, newValue);
+ _db->putWithTxn(txn, newKey, newValue);
}
if(txn)
@@ -2765,10 +3048,7 @@ XMLTransform::DBTransformer::transform(const DBEnvironmentPtr& dbEnv, const DBPt
}
void
-XMLTransform::DBTransformer::transform(const DBEnvironmentPtr& dbEnv, const DBPtr& db,
- const Ice::StringSeq& loadOld, const Ice::StringSeq& loadNew,
- const Ice::StringSeq& pathOld, const Ice::StringSeq& pathNew,
- const string& oldSchemaFile, const string& newSchemaFile)
+XMLTransform::DBTransformer::transform(const string& oldSchemaFile, const string& newSchemaFile)
{
DOMTreeErrorReporter errReporter;
@@ -2807,14 +3087,11 @@ XMLTransform::DBTransformer::transform(const DBEnvironmentPtr& dbEnv, const DBPt
throw e;
}
- transform(dbEnv, db, loadOld, loadNew, pathOld, pathNew, oldSchema, newSchema);
+ transform(oldSchema, newSchema);
}
void
-XMLTransform::DBTransformer::transform(const DBEnvironmentPtr& dbEnv, const DBPtr& db,
- const Ice::StringSeq& loadOld, const Ice::StringSeq& loadNew,
- const Ice::StringSeq& pathOld, const Ice::StringSeq& pathNew,
- const string& schemaStr)
+XMLTransform::DBTransformer::transform(const string& schemaStr)
{
DOMTreeErrorReporter errReporter;
@@ -2850,5 +3127,5 @@ XMLTransform::DBTransformer::transform(const DBEnvironmentPtr& dbEnv, const DBPt
throw e;
}
- transform(dbEnv, db, loadOld, loadNew, pathOld, pathNew, schema, schema);
+ transform(schema, schema);
}
diff --git a/cpp/test/XMLTransform/transform/Populate.cpp b/cpp/test/XMLTransform/transform/Populate.cpp
index c9027568b73..2ebb00d98fe 100644
--- a/cpp/test/XMLTransform/transform/Populate.cpp
+++ b/cpp/test/XMLTransform/transform/Populate.cpp
@@ -83,7 +83,6 @@ transformPrimitive(const DBEnvironmentPtr& dbEnv)
Int i;
DBPtr db;
- XMLTransform::DBTransformer transformer;
StringSeq dummy;
cout << "transforming primitives... " << flush;
@@ -108,7 +107,10 @@ transformPrimitive(const DBEnvironmentPtr& dbEnv)
db = dbEnv->openDBWithTxn(0, "byteToShort", false);
emitSchemas("xs:byte", "xs:short");
- transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
+ {
+ XMLTransform::DBTransformer transformer(dbEnv, db, dummy, dummy, paths, paths, false);
+ transformer.transform(oldSchema, newSchema);
+ }
db->close();
db = 0;
@@ -130,7 +132,10 @@ transformPrimitive(const DBEnvironmentPtr& dbEnv)
db = dbEnv->openDBWithTxn(0, "shortToInt", false);
emitSchemas("xs:short", "xs:int");
- transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
+ {
+ XMLTransform::DBTransformer transformer(dbEnv, db, dummy, dummy, paths, paths, false);
+ transformer.transform(oldSchema, newSchema);
+ }
db->close();
db = 0;
@@ -152,7 +157,10 @@ transformPrimitive(const DBEnvironmentPtr& dbEnv)
db = dbEnv->openDBWithTxn(0, "intToLong", false);
emitSchemas("xs:int", "xs:long");
- transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
+ {
+ XMLTransform::DBTransformer transformer(dbEnv, db, dummy, dummy, paths, paths, false);
+ transformer.transform(oldSchema, newSchema);
+ }
db->close();
db = 0;
@@ -174,7 +182,10 @@ transformPrimitive(const DBEnvironmentPtr& dbEnv)
db = dbEnv->openDBWithTxn(0, "longToByte", false);
emitSchemas("xs:long", "xs:byte");
- transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
+ {
+ XMLTransform::DBTransformer transformer(dbEnv, db, dummy, dummy, paths, paths, false);
+ transformer.transform(oldSchema, newSchema);
+ }
db->close();
db = 0;
@@ -196,7 +207,10 @@ transformPrimitive(const DBEnvironmentPtr& dbEnv)
db = dbEnv->openDBWithTxn(0, "floatToDouble", false);
emitSchemas("xs:float", "xs:double");
- transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
+ {
+ XMLTransform::DBTransformer transformer(dbEnv, db, dummy, dummy, paths, paths, false);
+ transformer.transform(oldSchema, newSchema);
+ }
db->close();
db = 0;
@@ -223,7 +237,8 @@ transformPrimitive(const DBEnvironmentPtr& dbEnv)
emitSchemas("xs:long", "xs:byte");
try
{
- transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
+ XMLTransform::DBTransformer transformer(dbEnv, db, dummy, dummy, paths, paths, false);
+ transformer.transform(oldSchema, newSchema);
test(false);
}
catch(const XMLTransform::IllegalTransform&)
@@ -256,7 +271,8 @@ transformPrimitive(const DBEnvironmentPtr& dbEnv)
emitSchemas("xs:long", "xs:short");
try
{
- transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
+ XMLTransform::DBTransformer transformer(dbEnv, db, dummy, dummy, paths, paths, false);
+ transformer.transform(oldSchema, newSchema);
test(false);
}
catch(const XMLTransform::IllegalTransform&)
@@ -289,7 +305,8 @@ transformPrimitive(const DBEnvironmentPtr& dbEnv)
emitSchemas("xs:long", "xs:int");
try
{
- transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
+ XMLTransform::DBTransformer transformer(dbEnv, db, dummy, dummy, paths, paths, false);
+ transformer.transform(oldSchema, newSchema);
test(false);
}
catch(const XMLTransform::IllegalTransform&)
@@ -323,7 +340,6 @@ transformPrimitiveSequence(const DBEnvironmentPtr& dbEnv)
Int i;
DBPtr db;
- XMLTransform::DBTransformer transformer;
StringSeq dummy;
cout << "transforming primitive sequences... " << flush;
@@ -350,7 +366,10 @@ transformPrimitiveSequence(const DBEnvironmentPtr& dbEnv)
db = dbEnv->openDBWithTxn(0, "byteToShortSeq", false);
emitSchemas("tns:_internal.Test.Seq1Type", "tns:_internal.Test.Seq1Type");
- transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
+ {
+ XMLTransform::DBTransformer transformer(dbEnv, db, dummy, dummy, paths, paths, false);
+ transformer.transform(oldSchema, newSchema);
+ }
db->close();
db = 0;
@@ -374,7 +393,10 @@ transformPrimitiveSequence(const DBEnvironmentPtr& dbEnv)
db = dbEnv->openDBWithTxn(0, "shortToIntSeq", false);
emitSchemas("tns:_internal.Test.Seq2Type", "tns:_internal.Test.Seq2Type");
- transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
+ {
+ XMLTransform::DBTransformer transformer(dbEnv, db, dummy, dummy, paths, paths, false);
+ transformer.transform(oldSchema, newSchema);
+ }
db->close();
db = 0;
@@ -398,7 +420,10 @@ transformPrimitiveSequence(const DBEnvironmentPtr& dbEnv)
db = dbEnv->openDBWithTxn(0, "intToLongSeq", false);
emitSchemas("tns:_internal.Test.Seq3Type", "tns:_internal.Test.Seq3Type");
- transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
+ {
+ XMLTransform::DBTransformer transformer(dbEnv, db, dummy, dummy, paths, paths, false);
+ transformer.transform(oldSchema, newSchema);
+ }
db->close();
db = 0;
@@ -422,7 +447,10 @@ transformPrimitiveSequence(const DBEnvironmentPtr& dbEnv)
db = dbEnv->openDBWithTxn(0, "longToByteSeq", false);
emitSchemas("tns:_internal.Test.Seq4Type", "tns:_internal.Test.Seq4Type");
- transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
+ {
+ XMLTransform::DBTransformer transformer(dbEnv, db, dummy, dummy, paths, paths, false);
+ transformer.transform(oldSchema, newSchema);
+ }
db->close();
db = 0;
@@ -451,7 +479,8 @@ transformPrimitiveSequence(const DBEnvironmentPtr& dbEnv)
emitSchemas("tns:_internal.Test.Seq4Type", "tns:_internal.Test.Seq4Type");
try
{
- transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
+ XMLTransform::DBTransformer transformer(dbEnv, db, dummy, dummy, paths, paths, false);
+ transformer.transform(oldSchema, newSchema);
test(false);
}
catch(const XMLTransform::IllegalTransform&)
@@ -483,7 +512,6 @@ static void
transformEnum(const DBEnvironmentPtr& dbEnv)
{
DBPtr db;
- XMLTransform::DBTransformer transformer;
StringSeq dummy;
cout << "transforming enumerations... " << flush;
@@ -506,7 +534,10 @@ transformEnum(const DBEnvironmentPtr& dbEnv)
db = dbEnv->openDBWithTxn(0, "enum", false);
emitSchemas("tns:_internal.Test.E1Type", "tns:_internal.Test.E1Type");
- transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
+ {
+ XMLTransform::DBTransformer transformer(dbEnv, db, dummy, dummy, paths, paths, false);
+ transformer.transform(oldSchema, newSchema);
+ }
db->close();
db = 0;
@@ -529,7 +560,8 @@ transformEnum(const DBEnvironmentPtr& dbEnv)
emitSchemas("tns:_internal.Test.E1Type", "tns:_internal.Test.E1Type");
try
{
- transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
+ XMLTransform::DBTransformer transformer(dbEnv, db, dummy, dummy, paths, paths, false);
+ transformer.transform(oldSchema, newSchema);
test(false);
}
catch(const XMLTransform::IllegalTransform&)
@@ -561,7 +593,6 @@ static void
transformDictionary(const DBEnvironmentPtr& dbEnv)
{
DBPtr db;
- XMLTransform::DBTransformer transformer;
StringSeq dummy;
cout << "transforming dictionaries... " << flush;
@@ -586,7 +617,10 @@ transformDictionary(const DBEnvironmentPtr& dbEnv)
db = dbEnv->openDBWithTxn(0, "dict", false);
emitSchemas("tns:_internal.Test.D1Type", "tns:_internal.Test.D1Type");
- transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
+ {
+ XMLTransform::DBTransformer transformer(dbEnv, db, dummy, dummy, paths, paths, false);
+ transformer.transform(oldSchema, newSchema);
+ }
db->close();
db = 0;
@@ -611,7 +645,8 @@ transformDictionary(const DBEnvironmentPtr& dbEnv)
emitSchemas("tns:_internal.Test.D1Type", "tns:_internal.Test.D1Type");
try
{
- transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
+ XMLTransform::DBTransformer transformer(dbEnv, db, dummy, dummy, paths, paths, false);
+ transformer.transform(oldSchema, newSchema);
test(false);
}
catch(const XMLTransform::IllegalTransform&)
@@ -643,7 +678,6 @@ static void
transformStruct(const DBEnvironmentPtr& dbEnv)
{
DBPtr db;
- XMLTransform::DBTransformer transformer;
StringSeq dummy;
cout << "transforming structs... " << flush;
@@ -674,7 +708,10 @@ transformStruct(const DBEnvironmentPtr& dbEnv)
db = dbEnv->openDBWithTxn(0, "struct", false);
emitSchemas("tns:_internal.Test.S1Type", "tns:_internal.Test.S1Type");
- transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
+ {
+ XMLTransform::DBTransformer transformer(dbEnv, db, dummy, dummy, paths, paths, false);
+ transformer.transform(oldSchema, newSchema);
+ }
db->close();
db = 0;
@@ -704,7 +741,8 @@ transformStruct(const DBEnvironmentPtr& dbEnv)
emitSchemas("tns:_internal.Test.S1Type", "tns:_internal.Test.S1Type");
try
{
- transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
+ XMLTransform::DBTransformer transformer(dbEnv, db, dummy, dummy, paths, paths, false);
+ transformer.transform(oldSchema, newSchema);
test(false);
}
catch(const XMLTransform::IllegalTransform&)
@@ -751,7 +789,6 @@ static void
transformClass(const DBEnvironmentPtr& dbEnv)
{
DBPtr db;
- XMLTransform::DBTransformer transformer;
StringSeq dummy;
cout << "transforming classes... " << flush;
@@ -834,7 +871,10 @@ transformClass(const DBEnvironmentPtr& dbEnv)
db = dbEnv->openDBWithTxn(0, "class", false);
emitSchemas("tns:_internal.Test.C1Type", "tns:_internal.Test.C1Type");
- transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
+ {
+ XMLTransform::DBTransformer transformer(dbEnv, db, dummy, dummy, paths, paths, false);
+ transformer.transform(oldSchema, newSchema);
+ }
db->close();
db = 0;
@@ -880,7 +920,8 @@ transformClass(const DBEnvironmentPtr& dbEnv)
emitSchemas("tns:_internal.Test.C1Type", "tns:_internal.Test.C1Type");
try
{
- transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
+ XMLTransform::DBTransformer transformer(dbEnv, db, dummy, dummy, paths, paths, false);
+ transformer.transform(oldSchema, newSchema);
test(false);
}
catch(const XMLTransform::IllegalTransform&)
@@ -927,7 +968,6 @@ static void
transformEvictor(const DBEnvironmentPtr& dbEnv)
{
DBPtr db;
- XMLTransform::DBTransformer transformer;
StringSeq loadOld, loadNew;
Identity ident;
EvictorPtr evictor;
@@ -1032,7 +1072,10 @@ transformEvictor(const DBEnvironmentPtr& dbEnv)
db = 0;
db = dbEnv->openDBWithTxn(0, "evictor", false);
- transformer.transform(dbEnv, db, loadOld, loadNew, paths, paths, evictorSchema);
+ {
+ XMLTransform::DBTransformer transformer(dbEnv, db, loadOld, loadNew, paths, paths, false);
+ transformer.transform(evictorSchema);
+ }
db->close();
db = 0;
@@ -1081,7 +1124,8 @@ transformEvictor(const DBEnvironmentPtr& dbEnv)
db = dbEnv->openDBWithTxn(0, "failure", false);
try
{
- transformer.transform(dbEnv, db, loadOld, loadNew, paths, paths, evictorSchema);
+ XMLTransform::DBTransformer transformer(dbEnv, db, loadOld, loadNew, paths, paths, false);
+ transformer.transform(evictorSchema);
test(false);
}
catch(const XMLTransform::IllegalTransform&)