<commit_before>/**
 * Application.js
 *
 * @author: <NAME> <<EMAIL>>
 * @copyright 2015, QuorraJS. All rights reserved.
 * @license Licensed under MIT
 */

var fs = require('fs');
var http = require('http');
var path = require('path');
var util = require('util');

var _ = require('lodash');

// load global helper methods
require('../support/helpers');
//@todo: require longjohn in dev environment only
//https://github.com/mattinsler/longjohn/issues/19
//require('longjohn');

var load = require('./start');
var Builder = require('../stack/Builder');
var InitializationMiddleware = require('../http/InitializationMiddleware');
var FaviconMiddleware = require('../http/FaviconMiddleware');
var ServeStaticMiddleware = require('../http/ServeStaticMiddleware');
var QueryParserMiddleware = require('../http/QueryParserMiddleware');
var BodyParserMiddleware = require('../http/BodyParserMiddleware');
var CookieParserMiddleware = require('../http/CookieParserMiddleware');
var SessionMiddleware = require('../http/SessionMiddleware');
var Container = require('../container/Container');
var environmentDetector = require('./environmentDetector');
var FileEnvironmentVariablesLoader = require('../config/FileEnvironmentVariablesLoader');
var FileLoader = require('../config/FileLoader');

var domain = require('domain');

/**
 * Create a Quorra application.
 *
 * @extend Container
 * @return {Function}
 * @api public
 */
function App(req, res, next)
{
    // Calling superclass constructor
    App.super_.call(this);

    /**
     * All of the developer defined middlewares.
     *
     * @var {Array}
     */
    this.__middlewares = [];

    /**
     * The filter instance
     */
    this.__filter;

    var self = this;

    /**
     * Run the application and send the response.
     *
     * @param  request
     * @param  response
     * @return {void}
     */
    this.run = function(request, response)
    {
        var reqDomain = domain.create();

        reqDomain
            .on('error', function(error) {
                self.exception.handle(error, request, response);
            })
            .run(function() {
                self.__getStackedClient().handle(request, response);
            });
    };

}

util.inherits(App, Container);

/**
 * Register a "before" application filter.
 *
 * @param  callback
 * @return void
 */
App.prototype.before = function(callback)
{
    return this.router.before(callback);
};

/**
 * Handle a http request.
 * @param request
 * @param response
 */
App.prototype.handle = function(request, response) {
    this.dispatch(request, response);
};

/**
 * Handle the given request and get the response.
 *
 * @param  request
 * @param  response
 * @return
 */
//@todo: note
App.prototype.dispatch = function(request, response) {
    this.isDownForMaintenance(function(down){
        function CB(){
            this.router.dispatch(this.prepareRequest(request), response);
        }

        if(down) {
            this.__filter.callFilter('positron.app.down', request, response, CB.bind(this));
        } else {
            CB.call(this);
        }
    });
};

/**
 * Prepare the request by injecting any services.
 *
 * @param  request
 * @return
 */
App.prototype.prepareRequest = function(request)
{
//    @todo: note session driver

    return request;
};

/**
 * Determine if the application is currently down for maintenance.
 *
 * @return bool
 */
App.prototype.isDownForMaintenance = function(CB)
{
    var self = this;
    fs.exists(this.path.storage+'/meta/down',function(exists){
        if(exists)
            CB.call(self, true);
        else
            CB.call(self, false);
    });
};

/**
 * Register a maintenance mode event listener
 *
 * @param CB
 */
App.prototype.down = function(CB)
{
    //@todo: move to event class
    this.__filter.register('positron.app.down', CB)
};

/**
 * Register an application error handler.
 *
 * @param  {function} callback
 */
App.prototype.error = function(callback)
{
    this.exception.error(callback);<commit_msg>Add method to register 404 handlers<commit_after>/**
 * Application.js
 *
 * @author: <NAME> <<EMAIL>>
 * @copyright 2015, QuorraJS. All rights reserved.
 * @license Licensed under MIT
 */

var fs = require('fs');
var http = require('http');
var path = require('path');
var util = require('util');

var _ = require('lodash');

// load global helper methods
require('../support/helpers');
//@todo: require longjohn in dev environment only
//https://github.com/mattinsler/longjohn/issues/19
//require('longjohn');

var load = require('./start');
var Builder = require('../stack/Builder');
var InitializationMiddleware = require('../http/InitializationMiddleware');
var FaviconMiddleware = require('../http/FaviconMiddleware');
var ServeStaticMiddleware = require('../http/ServeStaticMiddleware');
var QueryParserMiddleware = require('../http/QueryParserMiddleware');
var BodyParserMiddleware = require('../http/BodyParserMiddleware');
var CookieParserMiddleware = require('../http/CookieParserMiddleware');
var SessionMiddleware = require('../http/SessionMiddleware');
var Container = require('../container/Container');
var environmentDetector = require('./environmentDetector');
var FileEnvironmentVariablesLoader = require('../config/FileEnvironmentVariablesLoader');
var FileLoader = require('../config/FileLoader');

var domain = require('domain');

/**
 * Create a Quorra application.
 *
 * @extend Container
 * @return {Function}
 * @api public
 */
function App(req, res, next)
{
    // Calling superclass constructor
    App.super_.call(this);

    /**
     * All of the developer defined middlewares.
     *
     * @var {Array}
     */
    this.__middlewares = [];

    /**
     * The filter instance
     */
    this.__filter;

    var self = this;

    /**
     * Run the application and send the response.
     *
     * @param  request
     * @param  response
     * @return {void}
     */
    this.run = function(request, response)
    {
        var reqDomain = domain.create();

        reqDomain
            .on('error', function(error) {
                self.exception.handle(error, request, response);
            })
            .run(function() {
                self.__getStackedClient().handle(request, response);
            });
    };

}

util.inherits(App, Container);

/**
 * Register a "before" application filter.
 *
 * @param  callback
 * @return void
 */
App.prototype.before = function(callback)
{
    return this.router.before(callback);
};

/**
 * Handle a http request.
 * @param request
 * @param response
 */
App.prototype.handle = function(request, response) {
    this.dispatch(request, response);
};

/**
 * Handle the given request and get the response.
 *
 * @param  request
 * @param  response
 * @return
 */
//@todo: note
App.prototype.dispatch = function(request, response) {
    this.isDownForMaintenance(function(down){
        function CB(){
            this.router.dispatch(this.prepareRequest(request), response);
        }

        if(down) {
            this.__filter.callFilter('positron.app.down', request, response, CB.bind(this));
        } else {
            CB.call(this);
        }
    });
};

/**
 * Prepare the request by injecting any services.
 *
 * @param  request
 * @return
 */
App.prototype.prepareRequest = function(request)
{
//    @todo: note session driver

    return request;
};

/**
 * Determine if the application is currently down for maintenance.
 *
 * @return bool
 */
App.prototype.isDownForMaintenance = function(CB)
{
    var self = this;
    fs.exists(this.path.storage+'/meta/down',function(exists){
        if(exists)
            CB.call(self, true);
        else
            CB.call(self, false);
    });
};

/**
 * Register a maintenance mode event listener
 *
 * @param CB
 */
App.prototype.down = function(CB)
{
    //@todo: move to event class
    this.__filter.register('positron.app.down', CB)
};

/**
 * Register a 404 error handler.
 *
 * @param  {function} CB
 * @return void
 */
App.prototype.missing = function(CB)
{
    this.error(function(error, code, request, response, next) {
        if(error.status && error.status == 404) {
            CB(error, request, response, next);
        } else {
            next();
        }
    });
};

/**
 * Register an application error handler.
 *
 * @param  {function} callback
 */
App.prototype.error = function(callback)
{
    this.exception.error(callback);
{'fraction_non_alphanumeric': 0.14802044941148496, 'fraction_numerical': 0.0024967304720009513, 'mean_word_length': 2.9530075187969924, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7222577', 'n_tokens_mistral': 2425, 'n_tokens_neox': 2400, 'n_words': 578}