diff --git a/js/client/modules/org/arangodb/actions.js b/js/client/modules/org/arangodb/actions.js index 7d3a156dd5..d8174f3c67 100644 --- a/js/client/modules/org/arangodb/actions.js +++ b/js/client/modules/org/arangodb/actions.js @@ -1,8 +1,8 @@ /*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, regexp: true plusplus: true */ -/*global require, exports */ +/*global require, exports, module */ //////////////////////////////////////////////////////////////////////////////// -/// @brief JavaScript fake actions module +/// @brief JavaScript actions module /// /// @file /// @@ -28,11 +28,143 @@ /// @author Copyright 2013, triAGENS GmbH, Cologne, Germany //////////////////////////////////////////////////////////////////////////////// +var internal = require("internal"); + +var arangodb = require("org/arangodb"); + +// ----------------------------------------------------------------------------- +// --SECTION-- private variables +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @brief prints the flatten routing cache for a method +//////////////////////////////////////////////////////////////////////////////// + +function printFlatRoutingMethod (indent, flat) { + var i; + + for (i = 0; i < flat.length; ++i) { + var f = flat[i]; + var c = ""; + + if (f.prefix) { + c += "prefix "; + } + + if (c !== "") { + c = "[" + c.substr(0, c.length - 1) + "]"; + } + + arangodb.printf("%s%d: %s %s\n", indent, i, f.path, c); + } +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief prints the routing cache for a method +//////////////////////////////////////////////////////////////////////////////// + +function printRoutingMethod (indent, routes) { + var k; + var i; + + if (routes.hasOwnProperty('exact')) { + for (k in routes.exact) { + arangodb.printf("%sEXACT '%s'\n", indent, k); + + if (routes.exact.hasOwnProperty(k)) { + printRoutingMethod(indent + " ", routes.exact[k]); + } + } + } + + if (routes.hasOwnProperty('parameters')) { + for (i = 0; i < routes.parameters.length; ++i) { + var parameter = routes.parameters[i]; + + if (parameter.hasOwnProperty('constraint')) { + arangodb.printf("%PARAMETER '%s'\n", indent, parameter.constraint); + } + else { + arangodb.printf("%PARAMETER\n", indent); + } + + printRoutingMethod(indent + " ", parameter.match); + } + } + + if (routes.hasOwnProperty('callback')) { + arangodb.printf("%sCALLBACK\n", indent); + } + + if (routes.hasOwnProperty('prefix')) { + arangodb.printf("%sPREFIX\n", indent); + printRoutingMethod(indent + " ", routes.prefix); + } +} + +// ----------------------------------------------------------------------------- +// --SECTION-- public functions +// ----------------------------------------------------------------------------- + +//////////////////////////////////////////////////////////////////////////////// +/// @brief returns the routing cache +//////////////////////////////////////////////////////////////////////////////// + +exports.routingCache = internal.routingCache; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief prints the flatten routing cache +//////////////////////////////////////////////////////////////////////////////// + +function printFlatRouting (method) { + var cache = exports.routingCache(); + + if (method === undefined) { + method = "GET"; + } + else { + method = method.toUpperCase(); + } + + arangodb.printf("METHOD %s\n", method); + printFlatRoutingMethod(" ", cache.flat[method]); +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief prints the routing cache +//////////////////////////////////////////////////////////////////////////////// + +function printRouting (method) { + var cache = exports.routingCache(); + + if (method === undefined) { + method = "GET"; + } + else { + method = method.toUpperCase(); + } + + arangodb.printf("METHOD %s\n", method); + arangodb.printf(" ROUTES\n"); + printRoutingMethod(" ", cache.routes[method]); + + arangodb.printf("METHOD %s\n", method); + arangodb.printf(" MIDDLEWARE\n"); + printRoutingMethod(" ", cache.middleware[method]); +} + +// ----------------------------------------------------------------------------- +// --SECTION-- MODULE EXPORTS +// ----------------------------------------------------------------------------- + +exports.printFlatRouting = printFlatRouting; +exports.printRouting = printRouting; + // ----------------------------------------------------------------------------- // --SECTION-- END-OF-FILE // ----------------------------------------------------------------------------- // Local Variables: // mode: outline-minor -// outline-regexp: "\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}\\)" +// outline-regexp: "/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}" // End: diff --git a/js/server/modules/org/arangodb/actions.js b/js/server/modules/org/arangodb/actions.js index 3feabbe7d3..24b7cfb4f6 100644 --- a/js/server/modules/org/arangodb/actions.js +++ b/js/server/modules/org/arangodb/actions.js @@ -735,12 +735,25 @@ function defineRoutePart (route, subwhere, parts, pos, constraint, callback) { subwhere.exact[part] = {}; } + var subpart = subwhere.exact[part]; + if (pos + 1 < parts.length) { - defineRoutePart(route, subwhere.exact[part], parts, pos + 1, constraint, callback); + defineRoutePart(route, subpart, parts, pos + 1, constraint, callback); } else { - subwhere.exact[part].route = route; - subwhere.exact[part].callback = callback; + if (subpart.hasOwnProperty('route')) { + var p1 = subpart.route.priority || 0; + var p2 = route.priority || 0; + + if (p1 <= p2) { + subpart.route = route; + subpart.callback = callback; + } + } + else { + subpart.route = route; + subpart.callback = callback; + } } } else if (part.hasOwnProperty('parameters')) { @@ -788,12 +801,25 @@ function defineRoutePart (route, subwhere, parts, pos, constraint, callback) { subwhere.prefix = {}; } + var subprefix = subwhere.prefix; + if (pos + 1 < parts.length) { console.error("cannot define prefix match within url, ignoring route"); } else { - subwhere.prefix.route = route; - subwhere.prefix.callback = callback; + if (subprefix.hasOwnProperty('route')) { + var p1 = subprefix.route.priority || 0; + var p2 = route.priority || 0; + + if (p1 <= p2) { + subprefix.route = route; + subprefix.callback = callback; + } + } + else { + subprefix.route = route; + subprefix.callback = callback; + } } } } @@ -834,6 +860,7 @@ function flattenRouting (routes, path, urlParameters, depth, prefix) { var match; var result = []; + // start with exact matches if (routes.hasOwnProperty('exact')) { for (k in routes.exact) { if (routes.exact.hasOwnProperty(k)) { @@ -849,6 +876,7 @@ function flattenRouting (routes, path, urlParameters, depth, prefix) { } } + // next are parameter matches if (routes.hasOwnProperty('parameters')) { for (i = 0; i < routes.parameters.length; ++i) { parameter = routes.parameters[i]; @@ -886,6 +914,7 @@ function flattenRouting (routes, path, urlParameters, depth, prefix) { } } + // next use the current callback if (routes.hasOwnProperty('callback')) { result = result.concat([{ path: path, @@ -898,9 +927,10 @@ function flattenRouting (routes, path, urlParameters, depth, prefix) { }]); } + // finally use a prefix match if (routes.hasOwnProperty('prefix')) { if (! routes.prefix.hasOwnProperty('callback')) { - console.error("prefix match must end in '/*'"); + console.error("prefix match must specify a callback"); } else { cur = path + "(/[^/]+)*"; diff --git a/js/server/version-check.js b/js/server/version-check.js index 9c22e8c09e..d3298643cf 100644 --- a/js/server/version-check.js +++ b/js/server/version-check.js @@ -261,7 +261,8 @@ permanently: true, destination: "/_admin/html/index.html" } - } + }, + priority: -1000000 }); }