summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2016-09-25 00:21:09 +0100
committerDan Goodliffe <dan@randomdan.homeip.net>2016-09-25 00:21:09 +0100
commitbfc6d0c01b66aa22011197d7eb7d71dddda2594b (patch)
tree23f0275f7ef84bb4d15c30b60c95922fdd5893c9
parentSlicer 1.4 compatibility fix (diff)
downloadicespider-bfc6d0c01b66aa22011197d7eb7d71dddda2594b.tar.bz2
icespider-bfc6d0c01b66aa22011197d7eb7d71dddda2594b.tar.xz
icespider-bfc6d0c01b66aa22011197d7eb7d71dddda2594b.zip
Routes and output serializers as compact json object maps
-rw-r--r--icespider/common/routes.ice8
-rw-r--r--icespider/compile/routeCompiler.cpp68
-rw-r--r--icespider/unittests/testCompile.cpp44
-rw-r--r--icespider/unittests/testRoutes.json218
4 files changed, 160 insertions, 178 deletions
diff --git a/icespider/common/routes.ice b/icespider/common/routes.ice
index e238664..e77fed4 100644
--- a/icespider/common/routes.ice
+++ b/icespider/common/routes.ice
@@ -23,12 +23,12 @@ module IceSpider {
dictionary<string, Parameter> Parameters;
class OutputSerializer {
- string contentType;
string serializer;
StringSeq params;
};
- sequence<OutputSerializer> OutputSerializers;
+ ["slicer:json:object"]
+ dictionary<string, OutputSerializer> OutputSerializers;
class Operation {
string operation;
@@ -39,7 +39,6 @@ module IceSpider {
dictionary<string, Operation> Operations;
class Route {
- string name;
string path;
HttpMethod method = GET;
optional(0) string operation;
@@ -49,7 +48,8 @@ module IceSpider {
OutputSerializers outputSerializers;
};
- sequence<Route> Routes;
+ ["slicer:json:object"]
+ dictionary<string, Route> Routes;
class RouteConfiguration {
string name;
diff --git a/icespider/compile/routeCompiler.cpp b/icespider/compile/routeCompiler.cpp
index 0f603f5..b8b89db 100644
--- a/icespider/compile/routeCompiler.cpp
+++ b/icespider/compile/routeCompiler.cpp
@@ -97,7 +97,7 @@ namespace IceSpider {
for (const auto & o : r->operations) {
auto op = findOperation(o.second->operation, us);
if (!op) {
- throw std::runtime_error("Find operator failed for " + r->name);
+ throw std::runtime_error("Find operator failed for " + r->path);
}
for (const auto & p : op->parameters()) {
auto po = o.second->paramOverrides.find(p->name());
@@ -116,21 +116,21 @@ namespace IceSpider {
RouteCompiler::applyDefaults(RouteConfigurationPtr c, const Units & u) const
{
for (const auto & r : c->routes) {
- if (r->operation) {
- r->operations[std::string()] = new Operation(*r->operation, {});
+ if (r.second->operation) {
+ r.second->operations[std::string()] = new Operation(*r.second->operation, {});
}
- auto ps = findParameters(r, u);
+ auto ps = findParameters(r.second, u);
for (const auto & p : ps) {
- auto defined = r->params.find(p.first);
- if (defined != r->params.end()) {
+ auto defined = r.second->params.find(p.first);
+ if (defined != r.second->params.end()) {
if (!defined->second->key) defined->second->key = defined->first;
}
else {
- defined = r->params.insert({ p.first, new Parameter(ParameterSource::URL, p.first, false, IceUtil::Optional<std::string>(), false) }).first;
+ defined = r.second->params.insert({ p.first, new Parameter(ParameterSource::URL, p.first, false, IceUtil::Optional<std::string>(), false) }).first;
}
auto d = defined->second;
if (d->source == ParameterSource::URL) {
- Path path(r->path);
+ Path path(r.second->path);
d->hasUserSource = std::find_if(path.parts.begin(), path.parts.end(), [d](const auto & pp) {
if (auto par = dynamic_cast<PathParameter *>(pp.get())) {
return par->name == d->key;
@@ -232,12 +232,12 @@ namespace IceSpider {
RouteCompiler::registerOutputSerializers(FILE * output, RoutePtr r) const
{
for (const auto & os : r->outputSerializers) {
- auto bs = boost::algorithm::replace_all_copy(os->serializer, ".", "::");
- auto slash = os->contentType.find('/');
+ auto bs = boost::algorithm::replace_all_copy(os.second->serializer, ".", "::");
+ auto slash = os.first.find('/');
fprintbf(4, output, "addRouteSerializer({ \"%s\", \"%s\" }, new %s::IceSpiderFactory(",
- os->contentType.substr(0, slash), os->contentType.substr(slash + 1), bs);
- for (auto p = os->params.begin(); p != os->params.end(); ++p) {
- if (p != os->params.begin()) {
+ os.first.substr(0, slash), os.first.substr(slash + 1), bs);
+ for (auto p = os.second->params.begin(); p != os.second->params.end(); ++p) {
+ if (p != os.second->params.begin()) {
fprintf(output, ", ");
}
fputs(p->c_str(), output);
@@ -250,9 +250,9 @@ namespace IceSpider {
RouteCompiler::releaseOutputSerializers(FILE * output, RoutePtr r) const
{
for (const auto & os : r->outputSerializers) {
- auto slash = os->contentType.find('/');
+ auto slash = os.first.find('/');
fprintbf(4, output, "removeRouteSerializer({ \"%s\", \"%s\" });\n",
- os->contentType.substr(0, slash), os->contentType.substr(slash + 1));
+ os.first.substr(0, slash), os.first.substr(slash + 1));
}
}
@@ -285,20 +285,20 @@ namespace IceSpider {
fprintbf(output, "namespace %s {\n", c->name);
fprintbf(1, output, "// Implementation classes.\n\n");
for (const auto & r : c->routes) {
- std::string methodName = getEnumString(r->method);
+ std::string methodName = getEnumString(r.second->method);
- fprintbf(1, output, "// Route name: %s\n", r->name);
- fprintbf(1, output, "// path: %s\n", r->path);
- fprintbf(1, output, "class %s : public IceSpider::IRouteHandler {\n", r->name);
+ fprintbf(1, output, "// Route name: %s\n", r.first);
+ fprintbf(1, output, "// path: %s\n", r.second->path);
+ fprintbf(1, output, "class %s : public IceSpider::IRouteHandler {\n", r.first);
fprintbf(2, output, "public:\n");
- fprintbf(3, output, "%s(const IceSpider::Core * core) :\n", r->name);
- fprintbf(4, output, "IceSpider::IRouteHandler(IceSpider::HttpMethod::%s, \"%s\")", methodName, r->path);
- auto proxies = initializeProxies(output, r);
- for (const auto & p : r->params) {
+ fprintbf(3, output, "%s(const IceSpider::Core * core) :\n", r.first);
+ fprintbf(4, output, "IceSpider::IRouteHandler(IceSpider::HttpMethod::%s, \"%s\")", methodName, r.second->path);
+ auto proxies = initializeProxies(output, r.second);
+ for (const auto & p : r.second->params) {
if (p.second->hasUserSource) {
fprintf(output, ",\n");
if (p.second->source == ParameterSource::URL) {
- Path path(r->path);
+ Path path(r.second->path);
unsigned int idx = -1;
for (const auto & pp : path.parts) {
if (auto par = dynamic_cast<PathParameter *>(pp.get())) {
@@ -321,16 +321,16 @@ namespace IceSpider {
}
fprintf(output, "\n");
fprintbf(3, output, "{\n");
- registerOutputSerializers(output, r);
+ registerOutputSerializers(output, r.second);
fprintbf(3, output, "}\n\n");
- fprintbf(3, output, "~%s()\n", r->name);
+ fprintbf(3, output, "~%s()\n", r.first);
fprintbf(3, output, "{\n");
- releaseOutputSerializers(output, r);
+ releaseOutputSerializers(output, r.second);
fprintbf(3, output, "}\n\n");
fprintbf(3, output, "void execute(IceSpider::IHttpRequest * request) const\n");
fprintbf(3, output, "{\n");
- auto ps = findParameters(r, units);
- for (const auto & p : r->params) {
+ auto ps = findParameters(r.second, units);
+ for (const auto & p : r.second->params) {
if (p.second->hasUserSource) {
auto ip = ps.find(p.first)->second;
fprintbf(4, output, "auto _p_%s(request->get%sParam<%s>(_p%c_%s)",
@@ -351,16 +351,16 @@ namespace IceSpider {
fprintbf(0, output, ");\n");
}
}
- if (r->operation) {
- addSingleOperation(output, r, findOperation(*r->operation, units));
+ if (r.second->operation) {
+ addSingleOperation(output, r.second, findOperation(*r.second->operation, units));
}
else {
- addMashupOperations(output, r, proxies, units);
+ addMashupOperations(output, r.second, proxies, units);
}
fprintbf(3, output, "}\n\n");
fprintbf(2, output, "private:\n");
declareProxies(output, proxies);
- for (const auto & p : r->params) {
+ for (const auto & p : r.second->params) {
if (p.second->hasUserSource) {
if (p.second->source == ParameterSource::URL) {
fprintbf(3, output, "const unsigned int _pi_%s;\n", p.first);
@@ -381,7 +381,7 @@ namespace IceSpider {
fprintbf(output, "} // namespace %s\n\n", c->name);
fprintf(output, "// Register route handlers.\n");
for (const auto & r : c->routes) {
- fprintbf(output, "FACTORY(%s::%s, IceSpider::RouteHandlerFactory);\n", c->name, r->name);
+ fprintbf(output, "FACTORY(%s::%s, IceSpider::RouteHandlerFactory);\n", c->name, r.first);
}
fprintf(output, "\n// End generated code.\n");
}
diff --git a/icespider/unittests/testCompile.cpp b/icespider/unittests/testCompile.cpp
index 063d691..4fb7827 100644
--- a/icespider/unittests/testCompile.cpp
+++ b/icespider/unittests/testCompile.cpp
@@ -38,31 +38,25 @@ BOOST_AUTO_TEST_CASE( testLoadConfiguration )
BOOST_REQUIRE_EQUAL("common", cfg->name);
BOOST_REQUIRE_EQUAL(10, cfg->routes.size());
- BOOST_REQUIRE_EQUAL("index", cfg->routes[0]->name);
- BOOST_REQUIRE_EQUAL("/", cfg->routes[0]->path);
- BOOST_REQUIRE_EQUAL(HttpMethod::GET, cfg->routes[0]->method);
- BOOST_REQUIRE_EQUAL("TestIceSpider.TestApi.index", cfg->routes[0]->operation);
- BOOST_REQUIRE_EQUAL(0, cfg->routes[0]->params.size());
-
- BOOST_REQUIRE_EQUAL("item", cfg->routes[1]->name);
- BOOST_REQUIRE_EQUAL("/view/{s}/{i}", cfg->routes[1]->path);
- BOOST_REQUIRE_EQUAL(2, cfg->routes[1]->params.size());
-
- BOOST_REQUIRE_EQUAL("del", cfg->routes[2]->name);
- BOOST_REQUIRE_EQUAL(HttpMethod::DELETE, cfg->routes[2]->method);
- BOOST_REQUIRE_EQUAL(1, cfg->routes[2]->params.size());
-
- BOOST_REQUIRE_EQUAL("update", cfg->routes[3]->name);
- BOOST_REQUIRE_EQUAL(HttpMethod::POST, cfg->routes[3]->method);
- BOOST_REQUIRE_EQUAL(2, cfg->routes[3]->params.size());
-
- BOOST_REQUIRE_EQUAL("mashStruct", cfg->routes[6]->name);
- BOOST_REQUIRE_EQUAL(HttpMethod::GET, cfg->routes[6]->method);
- BOOST_REQUIRE_EQUAL(3, cfg->routes[6]->params.size());
-
- BOOST_REQUIRE_EQUAL("mashClass", cfg->routes[7]->name);
- BOOST_REQUIRE_EQUAL(HttpMethod::GET, cfg->routes[7]->method);
- BOOST_REQUIRE_EQUAL(3, cfg->routes[7]->params.size());
+ BOOST_REQUIRE_EQUAL("/", cfg->routes["index"]->path);
+ BOOST_REQUIRE_EQUAL(HttpMethod::GET, cfg->routes["index"]->method);
+ BOOST_REQUIRE_EQUAL("TestIceSpider.TestApi.index", cfg->routes["index"]->operation);
+ BOOST_REQUIRE_EQUAL(0, cfg->routes["index"]->params.size());
+
+ BOOST_REQUIRE_EQUAL("/view/{s}/{i}", cfg->routes["item"]->path);
+ BOOST_REQUIRE_EQUAL(2, cfg->routes["item"]->params.size());
+
+ BOOST_REQUIRE_EQUAL(HttpMethod::DELETE, cfg->routes["del"]->method);
+ BOOST_REQUIRE_EQUAL(1, cfg->routes["del"]->params.size());
+
+ BOOST_REQUIRE_EQUAL(HttpMethod::POST, cfg->routes["update"]->method);
+ BOOST_REQUIRE_EQUAL(2, cfg->routes["update"]->params.size());
+
+ BOOST_REQUIRE_EQUAL(HttpMethod::GET, cfg->routes["mashStruct"]->method);
+ BOOST_REQUIRE_EQUAL(3, cfg->routes["mashStruct"]->params.size());
+
+ BOOST_REQUIRE_EQUAL(HttpMethod::GET, cfg->routes["mashClass"]->method);
+ BOOST_REQUIRE_EQUAL(3, cfg->routes["mashClass"]->params.size());
BOOST_REQUIRE_EQUAL(1, cfg->slices.size());
BOOST_REQUIRE_EQUAL("test-api.ice", cfg->slices[0]);
diff --git a/icespider/unittests/testRoutes.json b/icespider/unittests/testRoutes.json
index 52add90..13a6806 100644
--- a/icespider/unittests/testRoutes.json
+++ b/icespider/unittests/testRoutes.json
@@ -1,132 +1,120 @@
{
"name": "common",
"headers": [ "xsltStreamSerializer.h" ],
- "routes": [
- {
- "name": "index",
- "path": "/",
- "method": "GET",
- "outputSerializers": [
- {
- "contentType": "text/html",
- "serializer": "IceSpider.XsltStreamSerializer",
- "params": [ "\"xslt/transform.xslt\"" ]
- }
- ],
- "operation": "TestIceSpider.TestApi.index"
- },
- {
- "name": "item",
- "path": "/view/{s}/{i}",
- "method": "GET",
- "operation": "TestIceSpider.TestApi.withParams"
- },
- {
- "name": "del",
- "path": "/{s}",
- "method": "DELETE",
- "operation": "TestIceSpider.TestApi.returnNothing"
- },
- {
- "name": "update",
- "path": "/{id}",
- "method": "POST",
- "operation": "TestIceSpider.TestApi.complexParam",
- "params": {
- "s": {
- "source": "URL",
- "key": "id",
- "isOptional": true
+ "routes": {
+ "index": {
+ "path": "/",
+ "method": "GET",
+ "outputSerializers": {
+ "text/html": {
+ "serializer": "IceSpider.XsltStreamSerializer",
+ "params": [ "\"xslt/transform.xslt\"" ]
+ }
},
- "m": {
- "source": "Body"
+ "operation": "TestIceSpider.TestApi.index"
+ },
+ "item": {
+ "path": "/view/{s}/{i}",
+ "method": "GET",
+ "operation": "TestIceSpider.TestApi.withParams"
+ },
+ "del": {
+ "path": "/{s}",
+ "method": "DELETE",
+ "operation": "TestIceSpider.TestApi.returnNothing"
+ },
+ "update": {
+ "path": "/{id}",
+ "method": "POST",
+ "operation": "TestIceSpider.TestApi.complexParam",
+ "params": {
+ "s": {
+ "source": "URL",
+ "key": "id",
+ "isOptional": true
+ },
+ "m": {
+ "source": "Body"
+ }
}
- }
- },
- {
- "name": "defaultItem",
- "path": "/item/{s}",
- "method": "GET",
- "operation": "TestIceSpider.TestApi.withParams",
- "params": {
- "i": {
- "default": "1234"
+ },
+ "defaultItem": {
+ "path": "/item/{s}",
+ "method": "GET",
+ "operation": "TestIceSpider.TestApi.withParams",
+ "params": {
+ "i": {
+ "default": "1234"
+ }
}
- }
- },
- {
- "name": "itemWithDefault",
- "path": "/item/{s}/{i}",
- "method": "GET",
- "operation": "TestIceSpider.TestApi.withParams",
- "params": {
- "i": {
- "default": "1234"
+ },
+ "itemWithDefault":{
+ "path": "/item/{s}/{i}",
+ "method": "GET",
+ "operation": "TestIceSpider.TestApi.withParams",
+ "params": {
+ "i": {
+ "default": "1234"
+ }
}
- }
- },
- {
- "name": "mashStruct",
- "path": "/mashS/{s}/{t}/{i}",
- "method": "GET",
- "type": "TestIceSpider.Mash1",
- "operations": {
- "a": {
- "operation": "TestIceSpider.TestApi.withParams"
- },
- "b": {
- "operation": "TestIceSpider.TestApi.withParams",
- "paramOverrides": {
- "s": "t"
+ },
+ "mashStruct": {
+ "path": "/mashS/{s}/{t}/{i}",
+ "method": "GET",
+ "type": "TestIceSpider.Mash1",
+ "operations": {
+ "a": {
+ "operation": "TestIceSpider.TestApi.withParams"
+ },
+ "b": {
+ "operation": "TestIceSpider.TestApi.withParams",
+ "paramOverrides": {
+ "s": "t"
+ }
}
}
- }
- },
- {
- "name": "mashClass",
- "path": "/mashC/{s}/{t}/{i}",
- "method": "GET",
- "type": "TestIceSpider.Mash2",
- "operations": {
- "a": {
- "operation": "TestIceSpider.TestApi.withParams"
- },
- "b": {
- "operation": "TestIceSpider.TestApi.withParams",
- "paramOverrides": {
- "s": "t"
+ },
+ "mashClass": {
+ "path": "/mashC/{s}/{t}/{i}",
+ "method": "GET",
+ "type": "TestIceSpider.Mash2",
+ "operations": {
+ "a": {
+ "operation": "TestIceSpider.TestApi.withParams"
+ },
+ "b": {
+ "operation": "TestIceSpider.TestApi.withParams",
+ "paramOverrides": {
+ "s": "t"
+ }
}
}
- }
- },
- {
- "name": "override",
- "path": "/override",
- "method": "GET",
- "outputSerializers": [
- {
- "contentType": "application/xml",
- "serializer": "IceSpider.XsltStreamSerializer",
- "params": [ "\"xslt/transform.xslt\"" ]
- }
- ],
- "operation": "TestIceSpider.TestApi.index"
- },
- {
- "name": "search",
- "path": "/search",
- "method": "GET",
- "operation": "TestIceSpider.TestApi.withParams",
- "params": {
- "s": {
- "source": "QueryString"
+ },
+ "override": {
+ "path": "/override",
+ "method": "GET",
+ "outputSerializers": {
+ "application/xml": {
+ "serializer": "IceSpider.XsltStreamSerializer",
+ "params": [ "\"xslt/transform.xslt\"" ]
+ }
},
- "i": {
- "source": "QueryString"
+ "operation": "TestIceSpider.TestApi.index"
+ },
+ "search": {
+ "path": "/search",
+ "method": "GET",
+ "operation": "TestIceSpider.TestApi.withParams",
+ "params": {
+ "s": {
+ "source": "QueryString"
+ },
+ "i": {
+ "source": "QueryString"
+ }
}
}
- }
- ],
+ },
"slices": [
"test-api.ice"
]