dotnode
Version:
.NET-like MVC framework for Node.js
191 lines (122 loc) • 5.87 kB
JavaScript
var BaseController = require('../controllers/controller'),
ControllerFactory = require('../controllers/controllerFactory'),
Injector = require('../ioc/injector'),
url = require('url'),
extend = require('xtend');
var Router = function (expressApp, mvcAppContext) {
this._app = expressApp;
this._appContext = mvcAppContext;
this._controllerFactory = new ControllerFactory(mvcAppContext);
this._injector = new Injector();
this._controllersFolder = mvcAppContext.appConfig && mvcAppContext.appConfig.controllersFolder
? mvcAppContext.appConfig.controllersFolder
: 'controllers';
};
Router.prototype._defaultRouteHandler = function (routeOptions, request, response, next) {
var queryStringParams = url.parse(request.url, true).query,
routeParams = request.params;
var actionName = routeOptions.defaults ? routeOptions.defaults.action : null,
controllerName = routeOptions.defaults ? routeOptions.defaults.controller : null,
areaName = '';
if (typeof routeOptions.handler == 'function') {
if (!routeOptions.methods || routeOptions.methods.indexOf(request.method) != -1) {
return routeOptions.handler(request, response, next);
}
}
if (typeof routeOptions.routeValues.controller == 'string') {
var isVariable = this._paramIsVariable(routeOptions.routeValues.controller);
var controllerProp = isVariable
? this._unwrapParam(routeOptions.routeValues.controller)
: routeOptions.routeValues.controller;
controllerName = isVariable
? routeParams[controllerProp]
: routeOptions.routeValues.controller;
}
if (typeof routeOptions.routeValues.action == 'string') {
var isVariable = this._paramIsVariable(routeOptions.routeValues.action);
var actionProp = isVariable
? this._unwrapParam(routeOptions.routeValues.action)
: routeOptions.routeValues.action;
actionName = isVariable
? routeParams[actionProp]
: routeOptions.routeValues.action;
}
if (typeof routeParams.area == 'string') {
var areaProp = this._paramIsVariable(routeOptions.routeValues.area)
? this._unwrapParam(routeOptions.routeValues.area)
: routeOptions.routeValues.area;
areaName = routeParams[areaProp];
}
var inferredParams = routeOptions.defaults && routeOptions.defaults.params ? routeOptions.defaults.params : {};
if (routeOptions.routeValues && routeOptions.routeValues.params) {
for (var prop in routeOptions.routeValues.params) {
if (routeOptions.routeValues.params.hasOwnProperty(prop)) {
var param = routeOptions.routeValues.params[prop];
if (this._paramIsVariable(param)) {
var paramProp = this._unwrapParam(param);
inferredParams[prop] = routeParams[paramProp];
} else {
inferredParams[prop] = param;
}
}
}
}
if (!this._controllerFactory.controllerIsRegistered(controllerName)) {
var areaPrefix = typeof areaName == 'string' && areaName !== '' ? 'areas/' + areaName + '/' : '';
var relativePath = areaPrefix + this._controllersFolder + '/' + controllerName;
var controllerPath = '../../' + relativePath;
var bindings = this._appContext.bindings.getBindings();
if (bindings) {
this._injector.registerBindings(this._appContext.bindings);
}
if (bindings && bindings[relativePath]) {
var AugmentedController = this._injector.create(relativePath);
this._controllerFactory.registerController(controllerName, AugmentedController);
} else {
var Controller = require(controllerPath);
this._controllerFactory.registerController(controllerName, Controller);
}
}
var params = extend(inferredParams, queryStringParams);
var requestMethod = request.method;
var verbs = routeOptions.methods || this._controllerFactory.getVerbs(actionName, controllerName);
if (verbs.indexOf(requestMethod) != -1) {
var invokeOptions = {
actionName: actionName,
controllerName: controllerName,
areaName: areaName,
request: request,
response: response,
params: params
};
return this._controllerFactory.invoke(invokeOptions);
} else {
response.writeHead(404, { 'Content-Type': 'text/html' });
response.end('not found :\'(');
}
};
Router.prototype._getRouteOptions = function (routeString) {
};
Router.prototype._paramIsVariable = function (param) {
return param.indexOf(':') === 0;
};
Router.prototype._wrapParam = function (param) {
return ':' + param;
};
Router.prototype._unwrapParam = function (param) {
return param.replace(':', '');
};
// #region public methods
Router.prototype.registerRoutes = function (routeTable) {
this._routeTable = routeTable;
var routes = this._routeTable.getRoutes();
for (var i in routes) {
var routeOptions = routes[i];
this._app.all(routeOptions.route, this._defaultRouteHandler.bind(this, routeOptions));
}
};
Router.prototype.getRoutes = function () {
this._routeTable.getRoutes();
};
// #endregion
module.exports = Router;