summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Spruiell <mes@zeroc.com>2002-10-03 19:33:07 +0000
committerMark Spruiell <mes@zeroc.com>2002-10-03 19:33:07 +0000
commit1ef9bd7de436369bec96f33af991dfade2c05428 (patch)
tree3d64b3f24efe15a0043edb41e0019be1bd0d34cc
parentalign output with XML transformer (diff)
downloadice-1ef9bd7de436369bec96f33af991dfade2c05428.tar.bz2
ice-1ef9bd7de436369bec96f33af991dfade2c05428.tar.xz
ice-1ef9bd7de436369bec96f33af991dfade2c05428.zip
add evictor support
-rw-r--r--cpp/include/XMLTransform/XMLTransform.h22
-rw-r--r--cpp/src/XMLTransform/TransformDB.cpp111
-rw-r--r--cpp/src/XMLTransform/XMLTransform.cpp333
-rw-r--r--cpp/test/XMLTransform/transform/Makefile6
-rw-r--r--cpp/test/XMLTransform/transform/Populate.cpp230
-rw-r--r--cpp/test/XMLTransform/transform/Validate.cpp112
6 files changed, 722 insertions, 92 deletions
diff --git a/cpp/include/XMLTransform/XMLTransform.h b/cpp/include/XMLTransform/XMLTransform.h
index 17ea6c75b09..2685fca04bb 100644
--- a/cpp/include/XMLTransform/XMLTransform.h
+++ b/cpp/include/XMLTransform/XMLTransform.h
@@ -173,7 +173,8 @@ class XML_TRANSFORM_API Transformer
{
public:
- Transformer(const Ice::StringSeq&, DOMDocument*, DOMDocument*);
+ Transformer(const Ice::StringSeq&, const Ice::StringSeq&, const Ice::StringSeq&, const Ice::StringSeq&,
+ DOMDocument*, DOMDocument*);
~Transformer();
void transform(::IceUtil::XMLOutput&, DOMDocument*, bool = true);
@@ -195,13 +196,28 @@ 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();
- void transform(const Freeze::DBEnvironmentPtr&, const Freeze::DBPtr&, const Ice::StringSeq&, const std::string&,
- const std::string&);
+ //
+ // 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&);
+
+ //
+ // 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&);
};
} // End namespace XMLTransform
diff --git a/cpp/src/XMLTransform/TransformDB.cpp b/cpp/src/XMLTransform/TransformDB.cpp
index 7dc6be200e1..3d16675f2a3 100644
--- a/cpp/src/XMLTransform/TransformDB.cpp
+++ b/cpp/src/XMLTransform/TransformDB.cpp
@@ -18,9 +18,15 @@ static void
usage(const string& appName)
{
cerr << "Usage: " << appName << " [options] db-env db old-schema new-schema\n";
+ cerr << " " << appName << " [options] --evictor db-env db\n";
+ cerr << "\n";
cerr <<
"Options:\n"
- "-IDIR Add directory DIR to the schema include path.\n"
+ "-e,--evictor Use the Freeze Evictor schema.\n"
+ "--load-old DIR Load all old schema files in directory DIR.\n"
+ "--load-new DIR Load all new schema files in directory DIR.\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"
"-h, --help Show this message.\n"
"-v, --version Display the Ice version.\n"
;
@@ -38,22 +44,83 @@ main(int argc, char* argv[])
{
communicator = Ice::initialize(argc, argv);
- Ice::StringSeq paths;
+ bool evictor = false;
+ Ice::StringSeq loadOld, loadNew;
+ Ice::StringSeq pathOld, pathNew;
int idx = 1;
while(idx < argc)
{
- if(strncmp(argv[idx], "-I", 2) == 0)
+ if(strcmp(argv[idx], "--load-old") == 0)
{
- if(strlen(argv[idx]) == 2)
+ if(idx + 1 >= argc)
{
+ cerr << argv[0] << ": argument expected for `" << argv[idx] << "'" << endl;
usage(argv[0]);
return EXIT_FAILURE;
}
- paths.push_back(argv[idx] + 2);
- for(int j = idx; j + 1 < argc; ++j)
+
+ loadOld.push_back(argv[idx + 1]);
+ for(int i = idx ; i + 2 < argc ; ++i)
+ {
+ argv[i] = argv[i + 2];
+ }
+ argc -= 2;
+ }
+ else if(strcmp(argv[idx], "--load-new") == 0)
+ {
+ if(idx + 1 >= argc)
+ {
+ cerr << argv[0] << ": argument expected for `" << argv[idx] << "'" << endl;
+ usage(argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ loadNew.push_back(argv[idx + 1]);
+ for(int i = idx ; i + 2 < argc ; ++i)
+ {
+ argv[i] = argv[i + 2];
+ }
+ argc -= 2;
+ }
+ else if(strcmp(argv[idx], "--path-old") == 0)
+ {
+ if(idx + 1 >= argc)
+ {
+ cerr << argv[0] << ": argument expected for `" << argv[idx] << "'" << endl;
+ usage(argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ pathOld.push_back(argv[idx + 1]);
+ for(int i = idx ; i + 2 < argc ; ++i)
{
- argv[j] = argv[j + 1];
+ argv[i] = argv[i + 2];
+ }
+ argc -= 2;
+ }
+ else if(strcmp(argv[idx], "--path-new") == 0)
+ {
+ if(idx + 1 >= argc)
+ {
+ cerr << argv[0] << ": argument expected for `" << argv[idx] << "'" << endl;
+ usage(argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ pathNew.push_back(argv[idx + 1]);
+ for(int i = idx ; i + 2 < argc ; ++i)
+ {
+ argv[i] = argv[i + 2];
+ }
+ argc -= 2;
+ }
+ else if(strcmp(argv[idx], "-e") == 0 || strcmp(argv[idx], "--evictor") == 0)
+ {
+ evictor = true;
+ for(int i = idx ; i + 1 < argc ; ++i)
+ {
+ argv[i] = argv[i + 1];
}
--argc;
}
@@ -76,7 +143,7 @@ main(int argc, char* argv[])
idx++;
}
- if(argc < 5)
+ if((evictor && argc != 3) || (!evictor && argc != 5))
{
usage(argv[0]);
return EXIT_FAILURE;
@@ -88,7 +155,33 @@ main(int argc, char* argv[])
db = dbEnv->openDB(argv[2], false);
XMLTransform::DBTransformer transformer;
- transformer.transform(dbEnv, db, paths, argv[3], argv[4]);
+
+ if(evictor)
+ {
+ //
+ // This is the schema definition for the database used by the
+ // Freeze Evictor (a map of Ice::Identity to Ice::Object).
+ // Note that this requires that a schema file be created for
+ // Identity.ice, and that it be loaded using --load-old and
+ // --load-new.
+ //
+ static string schema =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\""
+ " elementFormDefault=\"qualified\""
+ " xmlns:tns=\"http://www.noorg.org/schemas\""
+ " xmlns:ice=\"http://www.mutablerealms.com/schemas\""
+ " targetNamespace=\"http://www.noorg.org/schemas\">"
+ " <xs:import namespace=\"http://www.mutablerealms.com/schemas\" schemaLocation=\"ice.xsd\"/>"
+ " <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);
+ }
+ else
+ {
+ transformer.transform(dbEnv, db, loadOld, loadNew, pathOld, pathNew, argv[3], argv[4]);
+ }
}
catch(const Freeze::DBNotFoundException&)
{
diff --git a/cpp/src/XMLTransform/XMLTransform.cpp b/cpp/src/XMLTransform/XMLTransform.cpp
index 9120d455771..020224c6014 100644
--- a/cpp/src/XMLTransform/XMLTransform.cpp
+++ b/cpp/src/XMLTransform/XMLTransform.cpp
@@ -23,6 +23,16 @@
#include <sys/stat.h>
+#ifdef _WIN32
+# include <direct.h>
+# include <io.h>
+# define S_ISDIR(mode) ((mode) & _S_IFDIR)
+# define S_ISREG(mode) ((mode) & _S_IFREG)
+#else
+# include <unistd.h>
+# include <dirent.h>
+#endif
+
using namespace std;
using namespace Freeze;
using namespace XMLTransform;
@@ -1071,10 +1081,11 @@ class TransformFactory
{
public:
- TransformFactory(const Ice::StringSeq&);
+ TransformFactory();
~TransformFactory();
- void create(DOMDocument*, DOMDocument*, TransformMap*, TransformMap*);
+ void create(DOMDocument*, DOMDocument*, const Ice::StringSeq&, const Ice::StringSeq&,
+ const Ice::StringSeq&, const Ice::StringSeq&, TransformMap*, TransformMap*);
private:
@@ -1095,10 +1106,15 @@ private:
};
//
+ // Load all schemas in a list of directories.
+ //
+ void load(DocumentMap&, const string&, const Ice::StringSeq&);
+
+ //
// Schema import handling.
//
- void import(DocumentMap&, const string&, const string&);
- void processImport(DOMDocument*, DocumentMap&);
+ void import(DocumentMap&, const string&, const string&, const Ice::StringSeq&);
+ void processImport(DOMDocument*, DocumentMap&, const Ice::StringSeq&);
//
// Element processing.
@@ -1155,11 +1171,6 @@ private:
DOMNode* findSchemaRoot(DOMDocument*);
//
- // Search paths for importing schemas.
- //
- Ice::StringSeq _paths;
-
- //
// Map of local@uri class transforms (based on static type). This information cached for creation of the
// transform.
//
@@ -1247,8 +1258,7 @@ const TransformFactory::StringTypeTable* TransformFactory::itemsByNameEnd = &ite
//
// Constructor & destructor.
//
-XMLTransform::TransformFactory::TransformFactory(const Ice::StringSeq& paths) :
- _paths(paths)
+XMLTransform::TransformFactory::TransformFactory()
{
}
@@ -1265,8 +1275,10 @@ XMLTransform::TransformFactory::~TransformFactory()
// maps: A map of local@uri -> element transform and a map of transforms for specific class types.
//
void
-XMLTransform::TransformFactory::create(DOMDocument* fromDoc, DOMDocument* toDoc, TransformMap* elements,
- TransformMap* staticClassTransforms)
+XMLTransform::TransformFactory::create(DOMDocument* fromDoc, DOMDocument* toDoc,
+ const Ice::StringSeq& loadFrom, const Ice::StringSeq& loadTo,
+ const Ice::StringSeq& pathFrom, const Ice::StringSeq& pathTo,
+ TransformMap* elements, TransformMap* staticClassTransforms)
{
//
// Setup member state.
@@ -1279,6 +1291,19 @@ XMLTransform::TransformFactory::create(DOMDocument* fromDoc, DOMDocument* toDoc,
_defaultInitializedTransforms.clear();
//
+ // Load schemas.
+ //
+ Ice::StringSeq::size_type i;
+ for(i = 0; i < loadFrom.size(); i++)
+ {
+ load(_fromDocs, loadFrom[i], pathFrom);
+ }
+ for(i = 0; i < loadTo.size(); i++)
+ {
+ load(_toDocs, loadTo[i], pathTo);
+ }
+
+ //
// Create both of the document infos for the old & new schemas.
// Add the root documents to the document map.
//
@@ -1296,8 +1321,8 @@ XMLTransform::TransformFactory::create(DOMDocument* fromDoc, DOMDocument* toDoc,
//
// Process the import declarations for the source schema documents.
//
- processImport(fromDoc, _fromDocs);
- processImport(toDoc, _toDocs);
+ processImport(fromDoc, _fromDocs, pathFrom);
+ processImport(toDoc, _toDocs, pathTo);
//
// Finally process each element from the old schema document.
@@ -1309,7 +1334,128 @@ XMLTransform::TransformFactory::create(DOMDocument* fromDoc, DOMDocument* toDoc,
}
void
-XMLTransform::TransformFactory::import(DocumentMap& documents, const string& ns, const string& loc)
+XMLTransform::TransformFactory::load(DocumentMap& documents, const string& path, const Ice::StringSeq& paths)
+{
+ struct stat buf;
+ if(::stat(path.c_str(), &buf) == -1)
+ {
+ InvalidSchema ex(__FILE__, __LINE__);
+ ex.reason = "cannot stat `" + path + "': " + strerror(errno);
+ throw ex;
+ }
+
+ if(S_ISREG(buf.st_mode) && path.rfind(".xsd") != string::npos)
+ {
+ import(documents, "", path, paths);
+ }
+ else if(S_ISDIR(buf.st_mode))
+ {
+#ifdef _WIN32
+
+ struct _finddata_t data;
+ long h = _findfirst((path + "/*").c_str(), &data);
+ if(h == -1)
+ {
+ InvalidSchema ex(__FILE__, __LINE__);
+ ex.reason = "cannot read directory `" + path + "': " + strerror(errno);
+ throw ex;
+ }
+
+ while(true)
+ {
+ string name = data.name;
+ assert(!name.empty());
+
+ string fullPath = path + '/' + name;
+ if(::stat(fullPath.c_str(), &buf) == -1)
+ {
+ InvalidSchema ex(__FILE__, __LINE__);
+ ex.reason = "cannot stat `" + fullPath + "': " + strerror(errno);
+ throw ex;
+ }
+
+ if(S_ISDIR(buf.st_mode))
+ {
+ if(name != ".." && name != ".")
+ {
+ load(documents, fullPath, paths); // Recurse through subdirectories
+ }
+ }
+ else if(S_ISREG(buf.st_mode) && name.rfind(".xsd") != string::npos)
+ {
+ import(documents, "", fullPath, paths);
+ }
+
+ if(_findnext(h, &data) == -1)
+ {
+ if(errno == ENOENT)
+ {
+ break;
+ }
+
+ InvalidSchema ex(__FILE__, __LINE__);
+ ex.reason = "cannot read directory `" + path + "': " + strerror(errno);
+ _findclose(h);
+ throw ex;
+ }
+ }
+
+ _findclose(h);
+
+#else
+
+ struct dirent **namelist;
+ int n = ::scandir(path.c_str(), &namelist, 0, alphasort);
+ if(n < 0)
+ {
+ InvalidSchema ex(__FILE__, __LINE__);
+ ex.reason = "cannot read directory `" + path + "': " + strerror(errno);
+ throw ex;
+ }
+
+ for(int i = 0; i < n; ++i)
+ {
+ string name = namelist[i]->d_name;
+ assert(!name.empty());
+
+ free(namelist[i]);
+
+ string fullPath = path + '/' + name;
+ if(::stat(fullPath.c_str(), &buf) == -1)
+ {
+ InvalidSchema ex(__FILE__, __LINE__);
+ ex.reason = "cannot stat `" + fullPath + "': " + strerror(errno);
+ throw ex;
+ }
+
+ if(S_ISDIR(buf.st_mode))
+ {
+ if(name != ".." && name != ".")
+ {
+ load(documents, fullPath, paths); // Recurse through subdirectories
+ }
+ }
+ else if(S_ISREG(buf.st_mode) && name.rfind(".xsd") != string::npos)
+ {
+ import(documents, "", fullPath, paths);
+ }
+ }
+
+ free(namelist);
+
+#endif
+ }
+ else
+ {
+ InvalidSchema ex(__FILE__, __LINE__);
+ ex.reason = "cannot load schema from `" + path + "'";
+ throw ex;
+ }
+}
+
+void
+XMLTransform::TransformFactory::import(DocumentMap& documents, const string& ns, const string& loc,
+ const Ice::StringSeq& paths)
{
DOMTreeErrorReporter errorReporter;
XercesDOMParser parser;
@@ -1319,7 +1465,7 @@ XMLTransform::TransformFactory::import(DocumentMap& documents, const string& ns,
try
{
- string file = findFile(loc, _paths);
+ string file = findFile(loc, paths);
parser.parse(file.c_str());
if(errorReporter.getSawErrors())
{
@@ -1363,11 +1509,11 @@ XMLTransform::TransformFactory::import(DocumentMap& documents, const string& ns,
//
// Process any imports in the imported document.
//
- processImport(document, documents);
+ processImport(document, documents, paths);
}
void
-XMLTransform::TransformFactory::processImport(DOMDocument* parent, DocumentMap& documents)
+XMLTransform::TransformFactory::processImport(DOMDocument* parent, DocumentMap& documents, const Ice::StringSeq& paths)
{
DOMNode* schema = findSchemaRoot(parent);
assert(schema);
@@ -1381,7 +1527,7 @@ XMLTransform::TransformFactory::processImport(DOMDocument* parent, DocumentMap&
string ns = getAttributeByName(child, "namespace");
string loc = getAttributeByName(child, "schemaLocation");
- import(documents, ns, loc);
+ import(documents, ns, loc, paths);
}
child = child->getNextSibling();
}
@@ -1435,6 +1581,11 @@ XMLTransform::TransformFactory::processElements(const DocumentInfoPtr& info)
fullElementName += '@';
fullElementName += info->getTargetNamespace();
+/*
+ * We need to allow redefinitions, otherwise importing
+ * will fail. For example, this occurs if we import two
+ * schemas which both internally import the same schema.
+ *
//
// Redefinitions of elements is not permitted.
//
@@ -1444,6 +1595,7 @@ XMLTransform::TransformFactory::processElements(const DocumentInfoPtr& info)
ex.reason = "redefinition of element " + nameAttr;
throw ex;
}
+ */
string fromTypeName = getTypeAttribute(child);
string toTypeName = getTypeAttribute(to);
@@ -2254,11 +2406,12 @@ XMLTransform::TransformFactory::findSchemaRoot(DOMDocument* root)
}
-XMLTransform::Transformer::Transformer(const Ice::StringSeq& paths, DOMDocument* fromDoc,
- DOMDocument* toDoc)
+XMLTransform::Transformer::Transformer(const Ice::StringSeq& loadFrom, const Ice::StringSeq& loadTo,
+ const Ice::StringSeq& pathFrom, const Ice::StringSeq& pathTo,
+ DOMDocument* fromDoc, DOMDocument* toDoc)
{
- TransformFactory factory(paths);
- factory.create(fromDoc, toDoc, &_elements, &_staticClassTransforms);
+ TransformFactory factory;
+ factory.create(fromDoc, toDoc, loadFrom, loadTo, pathFrom, pathTo, &_elements, &_staticClassTransforms);
}
XMLTransform::Transformer::~Transformer()
@@ -2337,8 +2490,10 @@ XMLTransform::DBTransformer::~DBTransformer()
}
void
-XMLTransform::DBTransformer::transform(const DBEnvironmentPtr& dbEnv, const DBPtr& db, const Ice::StringSeq& paths,
- const string& oldSchemaFile, const string& newSchemaFile)
+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)
{
DOMTreeErrorReporter errReporter;
@@ -2347,47 +2502,20 @@ XMLTransform::DBTransformer::transform(const DBEnvironmentPtr& dbEnv, const DBPt
parser.setDoNamespaces(true);
parser.setErrorHandler(&errReporter);
- DOMDocument* oldSchema;
- DOMDocument* newSchema;
-
- try
- {
- parser.parse(oldSchemaFile.c_str());
- oldSchema = parser.getDocument();
-
- parser.parse(newSchemaFile.c_str());
- newSchema = parser.getDocument();
- }
- catch(const XMLException& ex)
- {
- InvalidSchema e(__FILE__, __LINE__);
- e.reason = "XML exception: " + toString(ex.getMessage());
- throw e;
- }
- catch(const SAXException& ex)
- {
- InvalidSchema e(__FILE__, __LINE__);
- e.reason = "SAX exception: " + toString(ex.getMessage());
- throw e;
- }
- catch(...)
- {
- InvalidSchema e(__FILE__, __LINE__);
- e.reason = "Unexpected exception";
- throw e;
- }
-
DBCursorPtr cursor;
DBTransactionPtr txn;
string reason;
try
{
- Transformer transformer(paths, oldSchema, newSchema);
+ Transformer transformer(loadOld, loadNew, pathOld, pathNew, oldSchema, newSchema);
+ //
+ // Header and footer for instance documents.
+ //
const string header = "<ice:data xmlns=\"http://www.noorg.org/schemas\""
" xmlns:ice=\"http://www.mutablerealms.com/schemas\""
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
- " xsi:schemaLocation=\"http://www.noorg.org/schemas " + oldSchemaFile + "\">";
+ " xsi:schemaLocation=\"http://www.noorg.org/schemas Dummy.xsd\">";
const string footer = "</ice:data>";
//
@@ -2525,3 +2653,92 @@ XMLTransform::DBTransformer::transform(const DBEnvironmentPtr& dbEnv, const DBPt
throw ex;
}
}
+
+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)
+{
+ DOMTreeErrorReporter errReporter;
+
+ XercesDOMParser parser;
+ parser.setValidationScheme(AbstractDOMParser::Val_Auto);
+ parser.setDoNamespaces(true);
+ parser.setErrorHandler(&errReporter);
+
+ DOMDocument* oldSchema;
+ DOMDocument* newSchema;
+
+ try
+ {
+ parser.parse(oldSchemaFile.c_str());
+ oldSchema = parser.getDocument();
+
+ parser.parse(newSchemaFile.c_str());
+ newSchema = parser.getDocument();
+ }
+ catch(const XMLException& ex)
+ {
+ InvalidSchema e(__FILE__, __LINE__);
+ e.reason = "XML exception: " + toString(ex.getMessage());
+ throw e;
+ }
+ catch(const SAXException& ex)
+ {
+ InvalidSchema e(__FILE__, __LINE__);
+ e.reason = "SAX exception: " + toString(ex.getMessage());
+ throw e;
+ }
+ catch(...)
+ {
+ InvalidSchema e(__FILE__, __LINE__);
+ e.reason = "Unexpected exception";
+ throw e;
+ }
+
+ transform(dbEnv, db, loadOld, loadNew, pathOld, pathNew, 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)
+{
+ DOMTreeErrorReporter errReporter;
+
+ XercesDOMParser parser;
+ parser.setValidationScheme(AbstractDOMParser::Val_Auto);
+ parser.setDoNamespaces(true);
+ parser.setErrorHandler(&errReporter);
+
+ DOMDocument* schema;
+
+ try
+ {
+ MemBufInputSource source((const XMLByte*)schemaStr.data(), schemaStr.size(), "schema");
+ parser.parse(source);
+ schema = parser.getDocument();
+ }
+ catch(const XMLException& ex)
+ {
+ InvalidSchema e(__FILE__, __LINE__);
+ e.reason = "XML exception: " + toString(ex.getMessage());
+ throw e;
+ }
+ catch(const SAXException& ex)
+ {
+ InvalidSchema e(__FILE__, __LINE__);
+ e.reason = "SAX exception: " + toString(ex.getMessage());
+ throw e;
+ }
+ catch(...)
+ {
+ InvalidSchema e(__FILE__, __LINE__);
+ e.reason = "Unexpected exception";
+ throw e;
+ }
+
+ transform(dbEnv, db, loadOld, loadNew, pathOld, pathNew, schema, schema);
+}
diff --git a/cpp/test/XMLTransform/transform/Makefile b/cpp/test/XMLTransform/transform/Makefile
index ded12fd58d9..e4dbf1a5750 100644
--- a/cpp/test/XMLTransform/transform/Makefile
+++ b/cpp/test/XMLTransform/transform/Makefile
@@ -54,7 +54,8 @@ SRCS = $(POPULATE_OBJS:.o=.cpp) \
$(VALIDATE_OBJS:.o=.cpp)
SCHEMAS = TestOld.xsd \
- TestNew.xsd
+ TestNew.xsd \
+ Identity.xsd
include $(top_srcdir)/config/Make.rules
@@ -163,6 +164,9 @@ TestOld.xsd: TestOld.ice $(SLICE2XSD)
TestNew.xsd: TestNew.ice $(SLICE2XSD)
$(SLICE2XSD) TestNew.ice
+Identity.xsd: $(top_srcdir)/slice/Ice/Identity.ice $(SLICE2XSD)
+ $(SLICE2XSD) --ice -I$(top_srcdir)/slice $(top_srcdir)/slice/Ice/Identity.ice
+
TestOld.h TestOld.cpp: TestOld.ice
rm -f TestOld.h TestOld.cpp
$(SLICE2CPP) TestOld.ice
diff --git a/cpp/test/XMLTransform/transform/Populate.cpp b/cpp/test/XMLTransform/transform/Populate.cpp
index 66dcc41bb8c..c629696a949 100644
--- a/cpp/test/XMLTransform/transform/Populate.cpp
+++ b/cpp/test/XMLTransform/transform/Populate.cpp
@@ -80,6 +80,7 @@ transformPrimitive(const DBEnvironmentPtr& dbEnv)
DBPtr db;
XMLTransform::DBTransformer transformer;
+ StringSeq dummy;
cout << "transforming primitives... " << flush;
@@ -100,7 +101,7 @@ transformPrimitive(const DBEnvironmentPtr& dbEnv)
}
emitSchemas("xs:byte", "xs:short");
- transformer.transform(dbEnv, db, paths, oldSchema, newSchema);
+ transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
db->close();
db = 0;
@@ -119,7 +120,7 @@ transformPrimitive(const DBEnvironmentPtr& dbEnv)
}
emitSchemas("xs:short", "xs:int");
- transformer.transform(dbEnv, db, paths, oldSchema, newSchema);
+ transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
db->close();
db = 0;
@@ -138,7 +139,7 @@ transformPrimitive(const DBEnvironmentPtr& dbEnv)
}
emitSchemas("xs:int", "xs:long");
- transformer.transform(dbEnv, db, paths, oldSchema, newSchema);
+ transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
db->close();
db = 0;
@@ -157,7 +158,7 @@ transformPrimitive(const DBEnvironmentPtr& dbEnv)
}
emitSchemas("xs:long", "xs:byte");
- transformer.transform(dbEnv, db, paths, oldSchema, newSchema);
+ transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
db->close();
db = 0;
@@ -176,7 +177,7 @@ transformPrimitive(const DBEnvironmentPtr& dbEnv)
}
emitSchemas("xs:float", "xs:double");
- transformer.transform(dbEnv, db, paths, oldSchema, newSchema);
+ transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
db->close();
db = 0;
@@ -201,7 +202,7 @@ transformPrimitive(const DBEnvironmentPtr& dbEnv)
try
{
- transformer.transform(dbEnv, db, paths, oldSchema, newSchema);
+ transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
test(false);
}
catch(const XMLTransform::IllegalTransform&)
@@ -232,7 +233,7 @@ transformPrimitive(const DBEnvironmentPtr& dbEnv)
try
{
- transformer.transform(dbEnv, db, paths, oldSchema, newSchema);
+ transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
test(false);
}
catch(const XMLTransform::IllegalTransform&)
@@ -263,7 +264,7 @@ transformPrimitive(const DBEnvironmentPtr& dbEnv)
try
{
- transformer.transform(dbEnv, db, paths, oldSchema, newSchema);
+ transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
test(false);
}
catch(const XMLTransform::IllegalTransform&)
@@ -298,6 +299,7 @@ transformPrimitiveSequence(const DBEnvironmentPtr& dbEnv)
DBPtr db;
XMLTransform::DBTransformer transformer;
+ StringSeq dummy;
cout << "transforming primitive sequences... " << flush;
@@ -320,7 +322,7 @@ transformPrimitiveSequence(const DBEnvironmentPtr& dbEnv)
}
emitSchemas("tns:_internal.Test.Seq1Type", "tns:_internal.Test.Seq1Type");
- transformer.transform(dbEnv, db, paths, oldSchema, newSchema);
+ transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
db->close();
db = 0;
@@ -341,7 +343,7 @@ transformPrimitiveSequence(const DBEnvironmentPtr& dbEnv)
}
emitSchemas("tns:_internal.Test.Seq2Type", "tns:_internal.Test.Seq2Type");
- transformer.transform(dbEnv, db, paths, oldSchema, newSchema);
+ transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
db->close();
db = 0;
@@ -362,7 +364,7 @@ transformPrimitiveSequence(const DBEnvironmentPtr& dbEnv)
}
emitSchemas("tns:_internal.Test.Seq3Type", "tns:_internal.Test.Seq3Type");
- transformer.transform(dbEnv, db, paths, oldSchema, newSchema);
+ transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
db->close();
db = 0;
@@ -383,7 +385,7 @@ transformPrimitiveSequence(const DBEnvironmentPtr& dbEnv)
}
emitSchemas("tns:_internal.Test.Seq4Type", "tns:_internal.Test.Seq4Type");
- transformer.transform(dbEnv, db, paths, oldSchema, newSchema);
+ transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
db->close();
db = 0;
@@ -410,7 +412,7 @@ transformPrimitiveSequence(const DBEnvironmentPtr& dbEnv)
try
{
- transformer.transform(dbEnv, db, paths, oldSchema, newSchema);
+ transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
test(false);
}
catch(const XMLTransform::IllegalTransform&)
@@ -443,6 +445,7 @@ transformEnum(const DBEnvironmentPtr& dbEnv)
{
DBPtr db;
XMLTransform::DBTransformer transformer;
+ StringSeq dummy;
cout << "transforming enumerations... " << flush;
@@ -461,7 +464,7 @@ transformEnum(const DBEnvironmentPtr& dbEnv)
}
emitSchemas("tns:_internal.Test.E1Type", "tns:_internal.Test.E1Type");
- transformer.transform(dbEnv, db, paths, oldSchema, newSchema);
+ transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
db->close();
db = 0;
@@ -482,7 +485,7 @@ transformEnum(const DBEnvironmentPtr& dbEnv)
try
{
- transformer.transform(dbEnv, db, paths, oldSchema, newSchema);
+ transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
test(false);
}
catch(const XMLTransform::IllegalTransform&)
@@ -515,6 +518,7 @@ transformDictionary(const DBEnvironmentPtr& dbEnv)
{
DBPtr db;
XMLTransform::DBTransformer transformer;
+ StringSeq dummy;
cout << "transforming dictionaries... " << flush;
@@ -535,7 +539,7 @@ transformDictionary(const DBEnvironmentPtr& dbEnv)
}
emitSchemas("tns:_internal.Test.D1Type", "tns:_internal.Test.D1Type");
- transformer.transform(dbEnv, db, paths, oldSchema, newSchema);
+ transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
db->close();
db = 0;
@@ -558,7 +562,7 @@ transformDictionary(const DBEnvironmentPtr& dbEnv)
try
{
- transformer.transform(dbEnv, db, paths, oldSchema, newSchema);
+ transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
test(false);
}
catch(const XMLTransform::IllegalTransform&)
@@ -591,6 +595,7 @@ transformStruct(const DBEnvironmentPtr& dbEnv)
{
DBPtr db;
XMLTransform::DBTransformer transformer;
+ StringSeq dummy;
cout << "transforming structs... " << flush;
@@ -617,7 +622,7 @@ transformStruct(const DBEnvironmentPtr& dbEnv)
}
emitSchemas("tns:_internal.Test.S1Type", "tns:_internal.Test.S1Type");
- transformer.transform(dbEnv, db, paths, oldSchema, newSchema);
+ transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
db->close();
db = 0;
@@ -645,7 +650,7 @@ transformStruct(const DBEnvironmentPtr& dbEnv)
try
{
- transformer.transform(dbEnv, db, paths, oldSchema, newSchema);
+ transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
test(false);
}
catch(const XMLTransform::IllegalTransform&)
@@ -678,6 +683,7 @@ transformClass(const DBEnvironmentPtr& dbEnv)
{
DBPtr db;
XMLTransform::DBTransformer transformer;
+ StringSeq dummy;
cout << "transforming classes... " << flush;
@@ -756,7 +762,7 @@ transformClass(const DBEnvironmentPtr& dbEnv)
}
emitSchemas("tns:_internal.Test.C1Type", "tns:_internal.Test.C1Type");
- transformer.transform(dbEnv, db, paths, oldSchema, newSchema);
+ transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
db->close();
db = 0;
@@ -800,7 +806,188 @@ transformClass(const DBEnvironmentPtr& dbEnv)
try
{
- transformer.transform(dbEnv, db, paths, oldSchema, newSchema);
+ transformer.transform(dbEnv, db, dummy, dummy, paths, paths, oldSchema, newSchema);
+ test(false);
+ }
+ catch(const XMLTransform::IllegalTransform&)
+ {
+ // Expected.
+ }
+ db->close();
+ db = 0;
+
+ cout << "ok" << endl;
+ }
+ catch(...)
+ {
+ cout << "failed" << endl;
+ if(db)
+ {
+ db->close();
+ }
+ throw;
+ }
+
+ if(db)
+ {
+ db->close();
+ }
+}
+
+static void
+transformEvictor(const DBEnvironmentPtr& dbEnv)
+{
+ DBPtr db;
+ XMLTransform::DBTransformer transformer;
+ StringSeq loadOld, loadNew;
+ Identity ident;
+ EvictorPtr evictor;
+
+ loadOld.push_back("TestOld.xsd");
+ loadOld.push_back("Identity.xsd");
+ loadNew.push_back("TestNew.xsd");
+ loadNew.push_back("Identity.xsd");
+
+ static string evictorSchema =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\""
+ " elementFormDefault=\"qualified\""
+ " xmlns:tns=\"http://www.noorg.org/schemas\""
+ " xmlns:ice=\"http://www.mutablerealms.com/schemas\""
+ " targetNamespace=\"http://www.noorg.org/schemas\">"
+ " <xs:import namespace=\"http://www.mutablerealms.com/schemas\" schemaLocation=\"ice.xsd\"/>"
+ " <xs:element name=\"Key\" type=\"_internal.Ice.IdentityType\"/>"
+ " <xs:element name=\"Value\" type=\"ice:_internal.objectType\"/></xs:schema>";
+
+ cout << "transforming evictor map... " << flush;
+
+ try
+ {
+ //
+ // Transform C2
+ //
+ db = dbEnv->openDB("evictor", true);
+ db->clear();
+ evictor = db->createEvictor(SaveUponEviction);
+
+ {
+ Test::C2Ptr c2;
+ c2 = new Test::C2;
+ c2->s = "0";
+ c2->f = 0;
+ c2->b = 0;
+ c2->i = 0;
+ c2->l = 0;
+ c2->d = 0;
+ ident.name = "0";
+ evictor->createObject(ident, c2);
+ c2 = new Test::C2;
+ c2->s = "1";
+ c2->f = 1;
+ c2->b = 1;
+ c2->i = 1;
+ c2->l = 1;
+ c2->d = 1;
+ ident.name = "1";
+ evictor->createObject(ident, c2);
+ c2 = new Test::C2;
+ c2->s = "2";
+ c2->f = 2;
+ c2->b = 2;
+ c2->i = 2;
+ c2->l = 2;
+ c2->d = 2;
+ ident.name = "2";
+ evictor->createObject(ident, c2);
+
+ //
+ // Add an object with facets.
+ //
+ Test::C1Ptr c1Facet;
+ Test::C2Ptr c2Facet;
+ c2 = new Test::C2;
+ c2->s = "3";
+ c2->f = 3;
+ c2->b = 3;
+ c2->i = 3;
+ c2->l = 3;
+ c2->d = 3;
+ c1Facet = new Test::C1;
+ c1Facet->s = "c1-0";
+ c1Facet->f = 0;
+ c1Facet->b = 0;
+ c2->ice_addFacet(c1Facet, "c1-0");
+ c1Facet = new Test::C1;
+ c1Facet->s = "c1-1";
+ c1Facet->f = 1;
+ c1Facet->b = 1;
+ c2->ice_addFacet(c1Facet, "c1-1");
+ c2Facet = new Test::C2;
+ c2Facet->s = "c1-2";
+ c2Facet->f = 2;
+ c2Facet->b = 2;
+ c2Facet->i = 2;
+ c2Facet->l = 2;
+ c2Facet->d = 2;
+ c1Facet = new Test::C1;
+ c1Facet->s = "c2-0";
+ c1Facet->f = 0;
+ c1Facet->b = 0;
+ c2Facet->ice_addFacet(c1Facet, "c2-0"); // Nested facet
+ c2->ice_addFacet(c2Facet, "c1-2");
+ ident.name = "3";
+ evictor->createObject(ident, c2);
+ }
+
+ evictor->deactivate();
+ transformer.transform(dbEnv, db, loadOld, loadNew, paths, paths, evictorSchema);
+ db->close();
+ db = 0;
+
+ //
+ // Transform C2 (should fail)
+ //
+ db = dbEnv->openDB("failure", true);
+ db->clear();
+ evictor = db->createEvictor(SaveUponEviction);
+
+ {
+ Test::C2Ptr c2;
+ c2 = new Test::C2;
+ c2->s = "0";
+ c2->f = 0;
+ c2->b = 0;
+ c2->i = 0;
+ c2->l = INT_MIN;
+ c2->d = 0;
+ ident.name = "0";
+ evictor->createObject(ident, c2);
+ c2 = new Test::C2;
+ c2->s = "1";
+ c2->f = 1;
+ c2->b = 1;
+ c2->i = 1;
+ c2->l = INT_MAX;
+ c2->d = 1;
+ ident.name = "1";
+ evictor->createObject(ident, c2);
+ c2 = new Test::C2;
+ c2->s = "2";
+ c2->f = 2;
+ c2->b = 2;
+ c2->i = 2;
+ c2->l = INT_MAX;
+ c2->l++; // Out of range for int
+ c2->d = 2;
+ ident.name = "2";
+ evictor->createObject(ident, c2);
+ }
+
+ evictor->deactivate();
+
+ try
+ {
+ transformer.transform(dbEnv, db, loadOld, loadNew, paths, paths, evictorSchema);
test(false);
}
catch(const XMLTransform::IllegalTransform&)
@@ -889,6 +1076,7 @@ run(int argc, char* argv[], const CommunicatorPtr& communicator)
transformDictionary(dbEnv);
transformStruct(dbEnv);
transformClass(dbEnv);
+ transformEvictor(dbEnv);
}
catch(...)
{
diff --git a/cpp/test/XMLTransform/transform/Validate.cpp b/cpp/test/XMLTransform/transform/Validate.cpp
index e5e4f034244..ea8c1a0a595 100644
--- a/cpp/test/XMLTransform/transform/Validate.cpp
+++ b/cpp/test/XMLTransform/transform/Validate.cpp
@@ -490,6 +490,117 @@ validateClass(const DBEnvironmentPtr& dbEnv)
throw;
}
+ communicator->removeObjectFactory(Test::C1::ice_staticId());
+ communicator->removeObjectFactory(Test::C2::ice_staticId());
+
+ if(db)
+ {
+ db->close();
+ }
+}
+
+static void
+validateEvictor(const DBEnvironmentPtr& dbEnv)
+{
+ DBPtr db;
+ EvictorPtr evictor;
+
+ CommunicatorPtr communicator = dbEnv->getCommunicator();
+ communicator->addObjectFactory(Test::C1::ice_factory(), Test::C1::ice_staticId());
+ communicator->addObjectFactory(Test::C2::ice_factory(), Test::C2::ice_staticId());
+
+ cout << "validating evictor transformations... " << flush;
+
+ try
+ {
+ //
+ // Validate C2
+ //
+ db = dbEnv->openDB("evictor", false);
+ evictor = db->createEvictor(SaveUponEviction);
+
+ {
+ EvictorIteratorPtr iter = evictor->getIterator();
+ while(iter->hasNext())
+ {
+ Current current;
+ LocalObjectPtr cookie;
+
+ current.id = iter->next();
+
+ ObjectPtr obj = evictor->locate(current, cookie);
+ test(obj);
+
+ Test::C2Ptr c2 = Test::C2Ptr::dynamicCast(obj);
+ test(c2);
+ test(c2->s.size() == 1 && c2->s == current.id.name);
+ int i = current.id.name[0] - '0';
+ test(c2->b == i);
+ test(c2->l == i);
+ test(c2->i == i);
+ if(c2->s == "3")
+ {
+ //
+ // Test facets
+ //
+ Ice::ObjectPtr obj;
+ Test::C1Ptr c1;
+
+ obj = c2->ice_findFacet("c1-0");
+ test(obj);
+ c1 = Test::C1Ptr::dynamicCast(obj);
+ test(c1);
+ test(c1->s == "c1-0");
+ test(c1->b == 0);
+
+ obj = c2->ice_findFacet("c1-1");
+ test(obj);
+ c1 = Test::C1Ptr::dynamicCast(obj);
+ test(c1);
+ test(c1->s == "c1-1");
+ test(c1->b == 1);
+
+ obj = c2->ice_findFacet("c1-2");
+ test(obj);
+ Test::C2Ptr c2Facet = Test::C2Ptr::dynamicCast(obj);
+ test(c2Facet);
+ test(c2Facet->s == "c1-2");
+ test(c2Facet->b == 2);
+ test(c2Facet->i == 2);
+ test(c2Facet->l == 2);
+
+ obj = c2Facet->ice_findFacet("c2-0");
+ test(obj);
+ c1 = Test::C1Ptr::dynamicCast(obj);
+ test(c1);
+ test(c1->s == "c2-0");
+ test(c1->b == 0);
+ }
+
+ evictor->finished(current, obj, cookie);
+ }
+ iter->destroy();
+ }
+
+ evictor->deactivate();
+ db->close();
+ db = 0;
+
+ cout << "ok" << endl;
+ }
+ catch(...)
+ {
+ cout << "failed" << endl;
+ if(db)
+ {
+ db->close();
+ }
+ throw;
+ }
+
+ communicator->removeObjectFactory(Test::C1::ice_staticId());
+ communicator->removeObjectFactory(Test::C2::ice_staticId());
+
if(db)
{
db->close();
@@ -543,6 +654,7 @@ run(int argc, char* argv[], const CommunicatorPtr& communicator)
validateDictionary(dbEnv);
validateStruct(dbEnv);
validateClass(dbEnv);
+ validateEvictor(dbEnv);
}
catch(...)
{