From d7c5ad7d6263fd1baf9bfdbaa4c50b70ef2fbdb2 Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Tue, 8 Jun 2010 08:22:05 +0200 Subject: reverted folder structure change for better mergeing with upstream --- .../framework-src/modules/dispatch.js | 149 +++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 trunk/infrastructure/framework-src/modules/dispatch.js (limited to 'trunk/infrastructure/framework-src/modules/dispatch.js') diff --git a/trunk/infrastructure/framework-src/modules/dispatch.js b/trunk/infrastructure/framework-src/modules/dispatch.js new file mode 100644 index 0000000..e7e3ef0 --- /dev/null +++ b/trunk/infrastructure/framework-src/modules/dispatch.js @@ -0,0 +1,149 @@ +/** + * Copyright 2009 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS-IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @fileOverview Dispatching for dynamic pages and static files rendered from disk. + */ + +import("jsutils.eachProperty"); +import("stringutils"); + +jimport("java.lang.System.out.println"); + +//---------------------------------------------------------------- +// Util +//---------------------------------------------------------------- + +function PrefixMatcher(p) { + var rs = p.replace(/([\[\]\^\$\\\.\*\+\?\(\)\{\}\|])/g, "\\$1"); + var r = new RegExp('^' + rs + '(.*)$'); + return function(path) { + return r.exec(path); + } +} + +// Like PrefixMatcher, but makes trailing '/' optional, as in /ep/admin or /ep/admin/. +// If trailing '/' is omitted, will redirect to same path with trailing /. +function DirMatcher(p) { + if (p.substr(-1) == '/') { + p = p.substr(0, p.length-1); + } + var prefixMatcher = PrefixMatcher(p+'/'); + return function(path) { + if (path == p) { + response.redirect(p+'/'); + } + return prefixMatcher(path); + } +} + +function _pathMatches(p, loc) { + // returns a regex-result kind of array with length >= 1, or null + if (typeof(loc) == 'string') { + return (p == loc) ? [loc] : null; + } + if (typeof(loc) == 'function') { + return (loc(p) || null); + } + if (loc.exec) { // regexp + var r = loc.exec(p); + return r || null; + } + throw new Error('Uknown type of location: '+loc); +} + +//---------------------------------------------------------------- +// Dispatcher +//---------------------------------------------------------------- + +var Dispatcher = function() { + this._routes = []; // Array([location, (local file path or function)]) +}; + +Dispatcher.prototype.addLocations = function(l) { + var that = this; + l.forEach(function(x) { that._routes.push(x); }); +}; + +Dispatcher.prototype.dispatch = function() { + var p = request.path; + var served = false; + + for (var i = 0; (i < this._routes.length) && (served == false); i++) { + var loc = this._routes[i][0]; + var dst = this._routes[i][1]; + + var match = _pathMatches(p, loc); + if (match) { + if (typeof(dst) != 'function') { + throw new Error('dispatch only dispatches to functions, and this is not a function: '+typeof(dst)); + } + + // call dst(group1, group2, group3, ...) + served = dst.apply(this, Array.prototype.slice.call(match, 1)); + } + }; + + return served; +}; + +//---------------------------------------------------------------- +// fdisp +//---------------------------------------------------------------- + +function forward(module) { + return function(name) { + if (name === "") { + name = "main"; + } + if (name) { + name = name.replace(/\-/g, '_'); + } + var onreq = module['onRequest']; + var f = module['render_'+name]; + var fg = module['render_'+name+'_get']; + var fp = module['render_'+name+'_post']; + + var served = false; + + if (onreq) { + served = onreq(name); + } + + if (served) { + return true; + } + + var method = request.method; + if (method == "HEAD") { + method = "GET"; + } + + if (f) { + f(); + served = true; + } else if (method == "GET" && fg) { + fg(); + served = true; + } else if (method == "POST" && fp) { + fp(); + served = true; + } + + return served; + }; +} + -- cgit v1.2.3