<commit_before>/*
 * Copyright (c) 2013, 2014, Erik Wienhold
 * All rights reserved.
 *
 * Licensed under the BSD 3-Clause License.
 */

/* global define */

define([
  'sulfur/schema/file',
  'sulfur/schema/value/simple/fileRef',
  'sulfur/ui/model'
], function (File, FileRefValue, Model) {

  'use strict';

  return Model.clone({

    attributes: {
      id: { default: '' },
      blob: { default: null }
    },

    _extract: function (value) {
      return {
        id: value.value,
        file: null
      };
    }

  }).augment({

    validateWithType: function (type) {
      var value = this.object;
      var err = false;
      if (value) {
        var v = type.createValidator();
        var errors = [];
        var isValid = v.validate(value, errors);
        isValid || (err = errors.join('\n'));
      }
      this.updateExternalErrors({ value: err });
    },

    _construct: function () {
      var id = this.get('id');
      var blob = this.get('blob');
      var file;
      blob && (file = File.create(blob));
      if (id || file) {
        return FileRefValue.create(id, file);
      }
    }

  });

});
<commit_msg>validate file size<commit_after>/*
 * Copyright (c) 2013, 2014, Erik Wienhold
 * All rights reserved.
 *
 * Licensed under the BSD 3-Clause License.
 */

/* global define */

define([
  'sulfur/schema/file',
  'sulfur/schema/value/simple/fileRef',
  'sulfur/ui/model'
], function (File, FileRefValue, Model) {

  'use strict';

  return Model.clone({

    attributes: {
      id: { default: '' },
      blob: { default: null }
    },

    _extract: function (value) {
      return {
        id: value.value,
        file: null
      };
    }

  }).augment({

    _validate: function (errors) {
      var blob = this.get('blob');
      if (blob) {
        blob.size || (errors.blob = "the file must not be empty");
      }
    },

    validateWithType: function (type) {
      var value = this.object;
      var err = false;
      if (value) {
        var v = type.createValidator();
        var errors = [];
        var isValid = v.validate(value, errors);
        isValid || (err = errors.join('\n'));
      }
      this.updateExternalErrors({ value: err });
    },

    _construct: function () {
      var id = this.get('id');
      var blob = this.get('blob');
      var file;
      blob && (file = File.create(blob));
      if (id || file) {
        return FileRefValue.create(id, file);
      }
    }

  });

});
<|endoftext|>


<commit_before>/*
    "IncludeJS" jQuery plugin

    This is a straightforward plug-in that allows you to dynamically load templates (for
    underscore, defined as <script type='text/template'> blocks) and .js files. It is not
    like RequireJS where the loaded .js files are treated as modules. It is understood that
    what you load will be defined in the global namespace.

    Personally, I used it to avoid having to load all of my `Backbone.View` files all at once
    on the main page. This way I can spread them out to where they are needed.

    Note that it does NOT load .css files, as that turned out to be a nasty mess to get
    working, so you will have to do that manually on the main page for all .js files that
    require it.

    Dependencies:
    -------------

    * http://jquery.com/
    * http://underscorejs.org - for templates
    * http://eleventyone.github.io/jquery.gettype/jquery.gettype.js - for $.gettype()

    Methods/Usage:
    --------------

        $.includejs.options = {...}
        $.includejs.include({...});
        $.includejs.getTemplate("...");

    Examples:
    --------

        See the example provided on the github project page.

*/

(function($) {

    $.includejs = (function(){

        //
        // Private Data
        //

        // any templates loaded are kept here. key=id(html), value=template.
        var templates = {};

        // tracks all of the .tpl.htm files that have been successfully loaded.
        // key = name, value = undefined.
        var tplFiles = {};

        // tracks all of the .js files that have been successfully loaded.
        // key = name, value = undefined.
        var jsFiles = {};

        // a dictionary of all the templates that are being loaded currently
        // key = name, value = array of request ids waiting for it.
        var loadingTPLFiles = {};

        // a dictionary of all the .js files that are being loaded currently.
        // key = name, value = array of ids(int) waiting for it.
        var loadingJSFiles = {};

        // a dictionary of `include` requests that are currently waiting for file(s) to
        // load - could be waiting on templates and/or .js files. key = id, value = req object
        var requestsPending = {};

        // used to hand out unique IDs
        var id = 0;

        //
        // Public Data
        //

        // the paths are used when AJAX calls are made. `cache` determines whether
        // or not we are allowed to use cached versions of the files that are
        // requested (again, via AJAX).

        var settings = {
            ROOT : "/",
            JS_PATH : "_inc/js/",
            TPL_PATH : "_inc/tpl/",
            cache : true
        };

        //
        // Private Methods
        //

        ///////////////////////////////////////////////////////////////////////
        // Gives out a unique ID, by using our private counter (which is increased
        // for the next call).
        ///////////////////////////////////////////////////////////////////////

        var makeUniqueID = function includejs__makeUniqueID() {
            return id++;
        }

        ///////////////////////////////////////////////////////////////////////
        // Grab/add an include request from our pending list.
        ///////////////////////////////////////////////////////////////////////

        var getIncRequest = function includejs__getIncRequest(id) {
            return requestsPending[id];
        }

        var addIncRequest = function includejs__addIncRequest(incRequest) {
            requestsPending[incRequest.id] = incRequest;
        }

        ///////////////////////////////////////////////////////////////////////
        // Abort all of the active AJAX requests for a particular incRequest.
        ///////////////////////////////////////////////////////////////////////

        var abortAllAJAX = function includejs__abortAllAJAX(incRequest) {

            // this is a private method. any errors discovered should be
            // exceptions, as they are not user-generated.

            if ( $.gettype(incRequest).base !== "object" ) {
                throw new Error("Invalid `incRequest`");
            }

            incRequest.isAborting = true;

            // if there are ajax requests to abort, then do so now then
            // empty out the array.

            _.each(incRequest.ajaxRequests,function(elem,idx){
                if ( $.gettype(elem).base === "object" ) {
                    elem.abort(); // this ends up calling this function again.
                    elem = null;
                }
            });

            incRequest.ajaxRequests.splice(0,incRequest.ajaxRequests.length);
            incRequest.ajaxRequests = null;
        }

        ///////////////////////////////////////////////////////////////////////
        // Grab a file, either script or template, via AJAX and then tell the
        // appropriate callback our result.
        //
        //  @options - object containing the following:
        //
        //          isScript - false for template data
        //          fileName
        //          id - the id for the object that requested this.
        //          success - callback
        //          error - callback
        //
        ///////////////////////////////////////////////////////////////////////

        var getViaAJAX = function includejs__getViaAJAX(options) {

            options = $.gettype(options).base === "object" ? options : {};
            options.isScript = !!options.isScript;
            options.fileName = options.fileName || "notset";
            options.id = $.gettype(options.id).base === "number" ? options.id : "notset";

            var incRequest = getIncRequest(options.id);

            // this method is only ever called from within the class, as it's private.
            // any errors that occur here should be dealt with via exception. user-generated
            // errors will be caught higher up in the calling hierarchy.

            if ( $.gettype(incRequest).base !== "object" ) {
                throw new Error("Invalid `incRequest`");
            }

            // if the callbacks aren't setup properly, notifications won't be passed around
            // which defeats the whole purpose.

            if ( $.gettype(options.success).base !== "function" ) {
                throw new Error("Invalid `success` callback");
            }

            if ( $.gettype(options.error).base !== "function" ) {
                throw new Error("Invalid `error` callback");
            }

            // request the file.
            var path = options.isScript ? settings.JS_PATH : settings.TPL_PATH;
            var ext = options.isScript ? ".js" : ".tpl.htm";
            var dtype = options.isScript ? "script" : "html";

            var jqXHR = $.ajax({
                url : settings.ROOT + path + options.fileName + ext,
                type : "GET",
                timeout : 10000,
                dataType : dtype,
                context : this
            })
            .done(function(data,textStatus,jqXHR) {

                if ( !incRequest.isAborting ) {
                    options.success(options,data);
                }
            })
            .fail(function(jqXHR,textStatus,errorThrown) {

                // no notifications of error are sent when aborting.
                if ( !incRequest.isAborting ) {
                    options.error(options,jqXHR);
                }
            })
            .always(function(a,textStatus,c){

                // if we're not aborting then try to remove
                // the jqXHR object from our tracking list.

                if ( !incRequest.isAborting ) {
                    var jqXHR = null;
                    jqXHR = ( textStatus === "success" ) ? c : a;
                    incRequest.ajaxRequests = _.without(incRequest.ajaxRequests,jqXHR);
                }
            });

            // add this request to our main list.
            incRequest.ajaxRequests.push(jqXHR);
        }

        ///////////////////////////////////////////////////////////////////////
        // A file of templates has been retrieved through AJAX. Let's parse what
        // we have and then see if the requestor is waiting for anything else.
        //
        //  @options - the options sent to `getViaAJAX`
        //  @templateData - contents of the .tpl.htm file
        //
        ///////////////////////////////////////////////////////////////////////

        var receivedTemplate = function includejs__receivedTemplate(options,templateData) {

            // We have the contents of an html file full of script-based
            // template blocks (i.e., <script type="text/template">), let's
            // parse all of the individual templates that are in it. Those
            // templates are stored as member data, within a dictionary.

            // key = id of template, value = template.

            var templateDict = {};
            var data = $(templateData).filter("script[type='text/template']");
            data.each(function(idx,elem){
                templateDict[$(elem).attr("id")] = $(elem).html();
            });

            // add the templates that we loaded in to our main dictionary.
            _.extend(templates,templateDict);

            // grab an array of all the `incRequest` instances that are
            // waiting for this template. then go through them all
            // and see if this was the last one they were waiting
            // for (if so, we can trigger `success` for them).

            waitList = loadingTPLFiles[options.fileName];
            _.each(waitList,function(elem,idx){

                // we have their id(int). let's get the actual request and
                // remove this template file from their list.

                var incRequest = requestsPending[elem];
                incRequest.pendingTemplates = _.without(incRequest.pendingTemplates,options.fileName);

                // check to see if it's been fulfilled.
                checkRequestFulfilled(incRequest);
            });

            // this tpl file is no longer being loaded.

            loadingTPLFiles[options.fileName] = null;
            delete loadingTPLFiles[options.fileName];
            tplFiles[options.fileName] = true;
        }

        ///////////////////////////////////////////////////////////////////////
        // A .js file has been loaded through AJAX. Let's see if the requestor
        // is waiting for anything else.
        //
        //  @options - the options sent to `getViaAJAX`
        //  @scriptData - the contents of the .js file (ignored)
        //
        ///////////////////////////////////////////////////////////////////////

        var receivedScript = function includejs__receivedScript(options,scriptData) {

            // grab an array of all the `incRequest` instances that are
            // waiting for this js file. then go through them all
            // and see if this was the last one they were waiting
            // for (if so, we can trigger `success` for them).

            waitList = loadingJSFiles[options.fileName];
            _.each(waitList,function(elem,idx){

                // we have their id(int). let's get the actual request and
                // remove this js file from their list.

                var incRequest = requestsPending[elem];
                incRequest.pendingJS = _.without(incRequest.pendingJS,options.fileName);

                // check to see if it's been fulfilled.
                checkRequestFulfilled(incRequest);
            });

            // this js file is no longer being loaded.

            loadingJSFiles[options.fileName] = null;
            delete loadingJSFiles[options.fileName];
            jsFiles[options.fileName] = true;
        }

        ///////////////////////////////////////////////////////////////////////
        // A file has failed to be loaded via AJAX. SHUT DOWN EVERYTHING!
        ///////////////////////////////////////////////////////////////////////

        var loadFailed = function includejs__loadFailed(options,jqXHR,textStatus,errorThrown) {

            var incRequest = getIncRequest(options.id);
            incRequest.ajaxRequests = _.without(incRequest.ajaxRequests,jqXHR);

            if ( !incRequest.isAborting ) {
                abortAllAJAX(incRequest);
                incRequest.error(options,jqXHR,textStatus,errorThrown);
            }
        }

        ///////////////////////////////////////////////////////////////////////
        // Checking to see if this request has been fulfilled. If so, call
        // success callback.
        ///////////////////////////////////////////////////////////////////////

        var checkRequestFulfilled = function includejs__checkRequestFulfilled(incRequest) {

            // if there are no more scripts/templates needed for this
            // request, then it's done.

            if (
                    ( !incRequest.pendingTemplates || !incRequest.pendingTemplates.length ) &&
                    ( !incRequest.pendingJS || !incRequest.pendingJS.length )
                )
            {
                incRequest.success();
                requestsPending[incRequest.id] = null;
                delete requestsPending[incRequest.id];
            }
        }

        ///////////////////////////////////////////////////////////////////////
        // We have sent a request to load template and/or .js files. Let's load
        // what isn't already here and then tell them the good news.
        ///////////////////////////////////////////////////////////////////////

        var addRequest = function includejs__addRequest(incRequest) {

            // assume everything has already been loaded

            var neededTPL = [];
            var neededJS = [];

            /*
                * Loading/waiting needed?
            */

            // look to see if we require any templates.
            if ( incRequest.tpl.length ) {

                neededTPL = _.filter(incRequest.tpl,function(elem){
                    return !tplFiles[elem];
                });
            }

            // look to see if we require any js files.
            if ( incRequest.js.length ) {

                neededJS = _.filter(incRequest.js,function(elem){
                    return !jsFiles[elem];
                });
            }

            // if everything has already been loaded, then just
            // send our success now.

            if ( ( !neededTPL.length ) && ( !neededJS.length ) ) {
                incRequest.success();
                return;
            }

            // otherwise we have to wait. execute the callback and
            // add to our request to the list. we'll update that request here.

            else {
                incRequest.waiting();
                addIncRequest(incRequest);
            }

            // go through both arrays of filenames. let's load them in or, if
            // they are already loading in, we'll just add our request to the list
            // that are waiting for them to load.

            var neededFiles = incRequestPending = incRequest.pendingTemplates = neededTPL;
            var loadingFiles = loadingTPLFiles;
            var isScript = false;
            var successCallback = receivedTemplate;

            do {

                if ( neededFiles.length ) {

                    // some of these files may already be loading. if they are
                    // we'll just add our name to the waiting list. if not, we have
                    // to load them ourselves here.

                    incRequestPending = neededFiles;

                    _.each(incRequestPending,function(elem,idx){

                        // already loading. add our id to waiting list.

                        if ( loadingFiles[elem] ) {
                            loadingFiles[elem].push(incRequest.id);
                        }

                        // we are the first to request it. let's load
                        // it in.

                        else {

                            // create the dictionary entry.
                            loadingFiles[elem] = [incRequest.id];

                            // save the current cache setting before we
                            // set it to what we want.

                            var cache = !!$.ajaxSetup().cache;
                            $.ajaxSetup({cache:!!settings.cache});

                            getViaAJAX({
                                isScript : isScript,
                                fileName : elem,
                                id : incRequest.id,
                                success : successCallback,
                                error : loadFailed
                            });

                            // reset the cache setting, as we're done.
                            $.ajaxSetup({cache:cache});
                        }
                    });
                }

                // if we just did templates, now do the same for scripts. just
                // change some references to different vars.

                if ( neededFiles === neededTPL ) {
                    neededFiles = incRequestPendeing = incRequest.pendingJS = neededJS;
                    loadingFiles = loadingJSFiles;
                    isScript = true;
                    successCallback = receivedScript;
                }
                else {
                    neededFiles = null;
                }
            }
            while ( neededFiles );
        }

        //
        // Public Methods
        //

        ///////////////////////////////////////////////////////////////////////
        // The main workhorse. Loads templates and/or .js files. Send success
        // and error callback functions if you're interested.
        //
        // Note that the templates and .js files are loaded concurrently, so if
        // you want to add a .js file that is going to execute immediately, and
        // requires a template to be available, then you'll have to make
        // separate calls.
        //
        //  @options -  an object containing the following members:
        //
        //      tpl (0+) - array of filenames
        //      js (0+) - array filenames
        //      waiting - callback
        //      success - callback
        //      error - callback
        //
        ///////////////////////////////////////////////////////////////////////

        var include = function includejs__include(options) {

            options = $.gettype(options).base === "object" ? options : {};
            options.tpl = $.gettype(options.tpl).base === "array" ? options.tpl : [];
            options.js = $.gettype(options.js).base === "array" ? options.js : [];
            options.waiting = $.gettype(options.waiting).base === "function" ? options.waiting : function(){};
            options.success = $.gettype(options.success).base === "function" ? options.success : function(){};
            options.error = $.gettype(options.error).base === "function" ? options.error : function(){};

            // create an object representing the request
            var incRequest = _.extend({},options,{
                id:makeUniqueID(),
                isAborting:false,
                ajaxRequests:[]
            });
            addRequest(incRequest);
        }

        ///////////////////////////////////////////////////////////////////////
        // Evaluate and return a template that has been loaded in.
        // The advantage of doing all this here is that we can add the ROOT
        // value to all of the template data objects, freeing the caller from
        // doing it everytime (if they need it).
        //
        //  @tplName - the id(html) that was assigned to the template
        //  @data - the data object to pass to the function returned by
        //          _.template().
        //
        ///////////////////////////////////////////////////////////////////////

        var getTemplate = function includejs__getTemplate(tplName,data) {

            if ( !templates[tplName] ) {
                console.error("`tplName` not found in $.includejs dictionary: "+tplName);
                return null;
            }

            data = $.gettype(data).base === "object" ? data : {};
            var year = new Date().getFullYear();
            _.extend(data,{
                ROOT:settings.ROOT,
                YEAR:year
            });
            year = null;

            return _.template(templates[tplName])(data);
        }

        //
        // Public interface
        //

        return {

            // data
            settings : settings,

            // methods
            include : include,
            getTemplate : getTemplate
        };

    })();

}(jQuery));<commit_msg>Updated comments a bit.<commit_after>/*
    "IncludeJS" jQuery plugin

    This is a straightforward plug-in that allows you to dynamically load templates (for
    underscore, defined as `<script type='text/template'>` blocks) and .js files. It is not
    like RequireJS where the loaded .js files are treated as modules. It is understood that
    what you load will be defined in the global namespace.

    Personally, I used it to avoid having to load all of my `Backbone.View` files at once
    on the main page. This way I can spread them out to where they are needed.

    Note that it does NOT load .css files, as that turned out to be a nasty mess to get
    working, so you will have to do that manually on the main page for all .js files that
    require it.

    Dependencies:
    -------------

    * http://jquery.com/
    * http://underscorejs.org - for templates
    * http://eleventyone.github.io/jquery.gettype/ - for $.gettype()

    Methods/Usage:
    --------------

        $.includejs.options = {...}
        $.includejs.include({...});
        $.includejs.getTemplate("...");

    Examples:
    --------

        See the example provided on the github project page.

*/

(function($) {

    $.includejs = (function(){

        //
        // Private Data
        //

        // any templates loaded are kept here. key=id(html), value=template.
        var templates = {};

        // tracks all of the .tpl.htm files that have been successfully loaded.
        // key = name, value = undefined.
        var tplFiles = {};

        // tracks all of the .js files that have been successfully loaded.
        // key = name, value = undefined.
        var jsFiles = {};

        // a dictionary of all the templates that are being loaded currently
        // key = name, value = array of request ids waiting for it.
        var loadingTPLFiles = {};

        // a dictionary of all the .js files that are being loaded currently.
        // key = name, value = array of ids(int) waiting for it.
        var loadingJSFiles = {};

        // a dictionary of `include` requests that are currently waiting for file(s) to
        // load - could be waiting on templates and/or .js files. key = id, value = req object
        var requestsPending = {};

        // used to hand out unique IDs
        var id = 0;

        //
        // Public Data
        //

        // the paths are used when AJAX calls are made. `cache` determines whether
        // or not we are allowed to use cached versions of the files that are
        // requested (again, via AJAX).

        var settings = {
            ROOT : "/",
            JS_PATH : "_inc/js/",
            TPL_PATH : "_inc/tpl/",
            cache : true
        };

        //
        // Private Methods
        //

        ///////////////////////////////////////////////////////////////////////
        // Gives out a unique ID, by using our private counter (which is increased
        // for the next call).
        ///////////////////////////////////////////////////////////////////////

        var makeUniqueID = function includejs__makeUniqueID() {
            return id++;
        }

        ///////////////////////////////////////////////////////////////////////
        // Grab/add an include request from our pending list.
        ///////////////////////////////////////////////////////////////////////

        var getIncRequest = function includejs__getIncRequest(id) {
            return requestsPending[id];
        }

        var addIncRequest = function includejs__addIncRequest(incRequest) {
            requestsPending[incRequest.id] = incRequest;
        }

        ///////////////////////////////////////////////////////////////////////
        // Abort all of the active AJAX requests for a particular incRequest.
        ///////////////////////////////////////////////////////////////////////

        var abortAllAJAX = function includejs__abortAllAJAX(incRequest) {

            // this is a private method. any errors discovered should be
            // exceptions, as they are not user-generated.

            if ( $.gettype(incRequest).base !== "object" ) {
                throw new Error("Invalid `incRequest`");
            }

            incRequest.isAborting = true;

            // if there are ajax requests to abort, then do so now then
            // empty out the array.

            _.each(incRequest.ajaxRequests,function(elem,idx){
                if ( $.gettype(elem).base === "object" ) {
                    elem.abort(); // this ends up calling this function again.
                    elem = null;
                }
            });

            incRequest.ajaxRequests.splice(0,incRequest.ajaxRequests.length);
            incRequest.ajaxRequests = null;
        }

        ///////////////////////////////////////////////////////////////////////
        // Grab a file, either script or template, via AJAX and then tell the
        // appropriate callback our result.
        //
        //  @options - object containing the following:
        //
        //          isScript - false for template data
        //          fileName
        //          id - the id for the object that requested this.
        //          success - callback
        //          error - callback
        //
        ///////////////////////////////////////////////////////////////////////

        var getViaAJAX = function includejs__getViaAJAX(options) {

            options = $.gettype(options).base === "object" ? options : {};
            options.isScript = !!options.isScript;
            options.fileName = options.fileName || "notset";
            options.id = $.gettype(options.id).base === "number" ? options.id : "notset";

            var incRequest = getIncRequest(options.id);

            // this method is only ever called from within the class, as it's private.
            // any errors that occur here should be dealt with via exception. user-generated
            // errors will be caught higher up in the calling hierarchy.

            if ( $.gettype(incRequest).base !== "object" ) {
                throw new Error("Invalid `incRequest`");
            }

            // if the callbacks aren't setup properly, notifications won't be passed around
            // which defeats the whole purpose.

            if ( $.gettype(options.success).base !== "function" ) {
                throw new Error("Invalid `success` callback");
            }

            if ( $.gettype(options.error).base !== "function" ) {
                throw new Error("Invalid `error` callback");
            }

            // request the file.
            var path = options.isScript ? settings.JS_PATH : settings.TPL_PATH;
            var ext = options.isScript ? ".js" : ".tpl.htm";
            var dtype = options.isScript ? "script" : "html";

            var jqXHR = $.ajax({
                url : settings.ROOT + path + options.fileName + ext,
                type : "GET",
                timeout : 10000,
                dataType : dtype,
                context : this
            })
            .done(function(data,textStatus,jqXHR) {

                if ( !incRequest.isAborting ) {
                    options.success(options,data);
                }
            })
            .fail(function(jqXHR,textStatus,errorThrown) {

                // no notifications of error are sent when aborting.
                if ( !incRequest.isAborting ) {
                    options.error(options,jqXHR);
                }
            })
            .always(function(a,textStatus,c){

                // if we're not aborting then try to remove
                // the jqXHR object from our tracking list.

                if ( !incRequest.isAborting ) {
                    var jqXHR = null;
                    jqXHR = ( textStatus === "success" ) ? c : a;
                    incRequest.ajaxRequests = _.without(incRequest.ajaxRequests,jqXHR);
                }
            });

            // add this request to our main list.
            incRequest.ajaxRequests.push(jqXHR);
        }

        ///////////////////////////////////////////////////////////////////////
        // A file of templates has been retrieved through AJAX. Let's parse what
        // we have and then see if the requestor is waiting for anything else.
        //
        //  @options - the options sent to `getViaAJAX`
        //  @templateData - contents of the .tpl.htm file
        //
        ///////////////////////////////////////////////////////////////////////

        var receivedTemplate = function includejs__receivedTemplate(options,templateData) {

            // We have the contents of an html file full of script-based
            // template blocks (i.e., <script type="text/template">), let's
            // parse all of the individual templates that are in it. Those
            // templates are stored as member data, within a dictionary.

            // key = id of template, value = template.

            var templateDict = {};
            var data = $(templateData).filter("script[type='text/template']");
            data.each(function(idx,elem){
                templateDict[$(elem).attr("id")] = $(elem).html();
            });

            // add the templates that we loaded in to our main dictionary.
            _.extend(templates,templateDict);

            // grab an array of all the `incRequest` instances that are
            // waiting for this template. then go through them all
            // and see if this was the last one they were waiting
            // for (if so, we can trigger `success` for them).

            waitList = loadingTPLFiles[options.fileName];
            _.each(waitList,function(elem,idx){

                // we have their id(int). let's get the actual request and
                // remove this template file from their list.

                var incRequest = requestsPending[elem];
                incRequest.pendingTemplates = _.without(incRequest.pendingTemplates,options.fileName);

                // check to see if it's been fulfilled.
                checkRequestFulfilled(incRequest);
            });

            // this tpl file is no longer being loaded.

            loadingTPLFiles[options.fileName] = null;
            delete loadingTPLFiles[options.fileName];
            tplFiles[options.fileName] = true;
        }

        ///////////////////////////////////////////////////////////////////////
        // A .js file has been loaded through AJAX. Let's see if the requestor
        // is waiting for anything else.
        //
        //  @options - the options sent to `getViaAJAX`
        //  @scriptData - the contents of the .js file (ignored)
        //
        ///////////////////////////////////////////////////////////////////////

        var receivedScript = function includejs__receivedScript(options,scriptData) {

            // grab an array of all the `incRequest` instances that are
            // waiting for this js file. then go through them all
            // and see if this was the last one they were waiting
            // for (if so, we can trigger `success` for them).

            waitList = loadingJSFiles[options.fileName];
            _.each(waitList,function(elem,idx){

                // we have their id(int). let's get the actual request and
                // remove this js file from their list.

                var incRequest = requestsPending[elem];
                incRequest.pendingJS = _.without(incRequest.pendingJS,options.fileName);

                // check to see if it's been fulfilled.
                checkRequestFulfilled(incRequest);
            });

            // this js file is no longer being loaded.

            loadingJSFiles[options.fileName] = null;
            delete loadingJSFiles[options.fileName];
            jsFiles[options.fileName] = true;
        }

        ///////////////////////////////////////////////////////////////////////
        // A file has failed to be loaded via AJAX. SHUT DOWN EVERYTHING!
        ///////////////////////////////////////////////////////////////////////

        var loadFailed = function includejs__loadFailed(options,jqXHR,textStatus,errorThrown) {

            var incRequest = getIncRequest(options.id);
            incRequest.ajaxRequests = _.without(incRequest.ajaxRequests,jqXHR);

            if ( !incRequest.isAborting ) {
                abortAllAJAX(incRequest);
                incRequest.error(options,jqXHR,textStatus,errorThrown);
            }
        }

        ///////////////////////////////////////////////////////////////////////
        // Checking to see if this request has been fulfilled. If so, call
        // success callback.
        ///////////////////////////////////////////////////////////////////////

        var checkRequestFulfilled = function includejs__checkRequestFulfilled(incRequest) {

            // if there are no more scripts/templates needed for this
            // request, then it's done.

            if (
                    ( !incRequest.pendingTemplates || !incRequest.pendingTemplates.length ) &&
                    ( !incRequest.pendingJS || !incRequest.pendingJS.length )
                )
            {
                incRequest.success();
                requestsPending[incRequest.id] = null;
                delete requestsPending[incRequest.id];
            }
        }

        ///////////////////////////////////////////////////////////////////////
        // We have sent a request to load template and/or .js files. Let's load
        // what isn't already here and then tell them the good news.
        ///////////////////////////////////////////////////////////////////////

        var addRequest = function includejs__addRequest(incRequest) {

            // assume everything has already been loaded

            var neededTPL = [];
            var neededJS = [];

            /*
                * Loading/waiting needed?
            */

            // look to see if we require any templates.
            if ( incRequest.tpl.length ) {

                neededTPL = _.filter(incRequest.tpl,function(elem){
                    return !tplFiles[elem];
                });
            }

            // look to see if we require any js files.
            if ( incRequest.js.length ) {

                neededJS = _.filter(incRequest.js,function(elem){
                    return !jsFiles[elem];
                });
            }

            // if everything has already been loaded, then just
            // send our success now.

            if ( ( !neededTPL.length ) && ( !neededJS.length ) ) {
                incRequest.success();
                return;
            }

            // otherwise we have to wait. execute the callback and
            // add to our request to the list. we'll update that request here.

            else {
                incRequest.waiting();
                addIncRequest(incRequest);
            }

            // go through both arrays of filenames. let's load them in or, if
            // they are already loading in, we'll just add our request to the list
            // that are waiting for them to load.

            var neededFiles = incRequestPending = incRequest.pendingTemplates = neededTPL;
            var loadingFiles = loadingTPLFiles;
            var isScript = false;
            var successCallback = receivedTemplate;

            do {

                if ( neededFiles.length ) {

                    // some of these files may already be loading. if they are
                    // we'll just add our name to the waiting list. if not, we have
                    // to load them ourselves here.

                    incRequestPending = neededFiles;

                    _.each(incRequestPending,function(elem,idx){

                        // already loading. add our id to waiting list.

                        if ( loadingFiles[elem] ) {
                            loadingFiles[elem].push(incRequest.id);
                        }

                        // we are the first to request it. let's load
                        // it in.

                        else {

                            // create the dictionary entry.
                            loadingFiles[elem] = [incRequest.id];

                            // save the current cache setting before we
                            // set it to what we want.

                            var cache = !!$.ajaxSetup().cache;
                            $.ajaxSetup({cache:!!settings.cache});

                            getViaAJAX({
                                isScript : isScript,
                                fileName : elem,
                                id : incRequest.id,
                                success : successCallback,
                                error : loadFailed
                            });

                            // reset the cache setting, as we're done.
                            $.ajaxSetup({cache:cache});
                        }
                    });
                }

                // if we just did templates, now do the same for scripts. just
                // change some references to different vars.

                if ( neededFiles === neededTPL ) {
                    neededFiles = incRequestPendeing = incRequest.pendingJS = neededJS;
                    loadingFiles = loadingJSFiles;
                    isScript = true;
                    successCallback = receivedScript;
                }
                else {
                    neededFiles = null;
                }
            }
            while ( neededFiles );
        }

        //
        // Public Methods
        //

        ///////////////////////////////////////////////////////////////////////
        // The main workhorse. Loads templates and/or .js files. Send success
        // and error callback functions if you're interested.
        //
        // Note that the templates and .js files are loaded concurrently, so if
        // you want to add a .js file that is going to execute immediately, and
        // requires a template to be available, then you'll have to make
        // separate calls.
        //
        //  @options -  an object containing the following members:
        //
        //      tpl (0+) - array of filenames
        //      js (0+) - array filenames
        //      waiting - callback
        //      success - callback
        //      error - callback
        //
        ///////////////////////////////////////////////////////////////////////

        var include = function includejs__include(options) {

            options = $.gettype(options).base === "object" ? options : {};
            options.tpl = $.gettype(options.tpl).base === "array" ? options.tpl : [];
            options.js = $.gettype(options.js).base === "array" ? options.js : [];
            options.waiting = $.gettype(options.waiting).base === "function" ? options.waiting : function(){};
            options.success = $.gettype(options.success).base === "function" ? options.success : function(){};
            options.error = $.gettype(options.error).base === "function" ? options.error : function(){};

            // create an object representing the request
            var incRequest = _.extend({},options,{
                id:makeUniqueID(),
                isAborting:false,
                ajaxRequests:[]
            });
            addRequest(incRequest);
        }

        ///////////////////////////////////////////////////////////////////////
        // Evaluate and return a template that has been loaded in.
        // The advantage of doing all this here is that we can add the ROOT
        // value to all of the template data objects, freeing the caller from
        // doing it everytime (if they need it).
        //
        //  @tplName - the id(html) that was assigned to the template
        //  @data - the data object to pass to the function returned by
        //          _.template().
        //
        ///////////////////////////////////////////////////////////////////////

        var getTemplate = function includejs__getTemplate(tplName,data) {

            if ( !templates[tplName] ) {
                console.error("`tplName` not found in $.includejs dictionary: "+tplName);
                return null;
            }

            data = $.gettype(data).base === "object" ? data : {};
            var year = new Date().getFullYear();
            _.extend(data,{
                ROOT:settings.ROOT,
                YEAR:year
            });
            year = null;

            return _.template(templates[tplName])(data);
        }

        //
        // Public interface
        //

        return {

            // data
            settings : settings,

            // methods
            include : include,
            getTemplate : getTemplate
        };

    })();

}(jQuery));<|endoftext|>


<commit_before>define(['moment', 'lodash'], function(moment, _) {
    'use strict';
    return ['$scope', 'Restangular', 'trackr.services.employee', '$filter', 'base.services.notification', 'holidays',
        function($scope, Restangular, EmployeeService, $filter, NotificationService, holidays) {
            var controller = this;
            $scope.date = moment().toDate();
            $scope.startTime = moment().hour(9).minute(0).second(0).toDate();
            $scope.endTime = moment().hour(17).minute(30).second(0).toDate();

            $scope.errors = [];

            $scope.getProjects = function(searchString) {
                var search = '%' + searchString + '%';
                return Restangular
                    .allUrl('projects', 'api/projects/search/findByNameLikeIgnoreCaseOrIdentifierLikeIgnoreCaseOrderByNameAsc')
                    .getList({name: search, identifier: search, projection: 'withCompanyAndDebitor'});
            };

            $scope.getProjectLabel = function(project) {
                if(project) {
                    return project.name + ' (' + project.company.name + ')';
                }
            };

            controller.formatTime = function(date) {
                return $filter('date')(date, 'HH:mm:ss');
            };

            /**
             * Calculates the difference of end - start in hours (with decimals).
             * @param endTime a date or string parseable by moment.js
             * @param startTime a date or string parseable by moment.js
             * @returns {*} The difference between end and start in hours (e.g. 8.5)
             */
            $scope.totalTime = function(endTime, startTime) {
                var end = moment(endTime).startOf('minute');
                var start = moment(startTime).startOf('minute');
                return end.diff(start, 'hours', true);
            };

            controller.createWorkTimeEntity = function() {
                return {
                    employee: EmployeeService.getEmployeeHref(),
                    project: $scope.project._links.self.href,
                    date: $scope.date,
                    startTime: controller.formatTime($scope.startTime),
                    endTime: controller.formatTime($scope.endTime),
                    comment: $scope.comment
                };
            };

            /**
             * Advance to the next monday-friday that is not a public holiday.
             * @param date The date to advance
             * @returns {date|*} The date advanced to the next day.
             */
            controller.advanceToNextWorkDay = function(date) {
                var mdate = moment(date).add('days', 1);
                while(!controller.isWorkDay(mdate, holidays)) {
                    mdate.add('days', 1);
                }
                return mdate.toDate();
            };

            /**
             * Test if a day is a work day given a list of public holidays.
             * @param date The date to test
             * @param holidays A list of public holidays
             * @returns {boolean} true if the date is a monday-friday that is not in the list, false otherwise.
             */
            controller.isWorkDay = function(date, holidays) {
                return date.day() !== 6 && date.day() !== 0 && !_.find(holidays, function(holiday) {
                    return holiday.day === date.format('YYYY-MM-DD');
                });
            };

            $scope.saveTime = function() {
                var workTimeObject = controller.createWorkTimeEntity();
                Restangular.all('workTimes').post(workTimeObject).then(function() {
                    $scope.errors = [];
                    $scope.date = controller.advanceToNextWorkDay($scope.date);
                    NotificationService.info('Working time saved.');
                }, function(response) {
                    $scope.errors = response.data.errors;
                    NotificationService.error('Error saving working time');
                });
            };
        }];
});<commit_msg>TRACKR-213 - Use lodash _.pluck and _.where style instead of callbacks Timesheet employee controller.<commit_after>define(['moment', 'lodash'], function(moment, _) {
    'use strict';
    return ['$scope', 'Restangular', 'trackr.services.employee', '$filter', 'base.services.notification', 'holidays',
        function($scope, Restangular, EmployeeService, $filter, NotificationService, holidays) {
            var controller = this;
            $scope.date = moment().toDate();
            $scope.startTime = moment().hour(9).minute(0).second(0).toDate();
            $scope.endTime = moment().hour(17).minute(30).second(0).toDate();

            $scope.errors = [];

            $scope.getProjects = function(searchString) {
                var search = '%' + searchString + '%';
                return Restangular
                    .allUrl('projects', 'api/projects/search/findByNameLikeIgnoreCaseOrIdentifierLikeIgnoreCaseOrderByNameAsc')
                    .getList({name: search, identifier: search, projection: 'withCompanyAndDebitor'});
            };

            $scope.getProjectLabel = function(project) {
                if(project) {
                    return project.name + ' (' + project.company.name + ')';
                }
            };

            controller.formatTime = function(date) {
                return $filter('date')(date, 'HH:mm:ss');
            };

            /**
             * Calculates the difference of end - start in hours (with decimals).
             * @param endTime a date or string parseable by moment.js
             * @param startTime a date or string parseable by moment.js
             * @returns {*} The difference between end and start in hours (e.g. 8.5)
             */
            $scope.totalTime = function(endTime, startTime) {
                var end = moment(endTime).startOf('minute');
                var start = moment(startTime).startOf('minute');
                return end.diff(start, 'hours', true);
            };

            controller.createWorkTimeEntity = function() {
                return {
                    employee: EmployeeService.getEmployeeHref(),
                    project: $scope.project._links.self.href,
                    date: $scope.date,
                    startTime: controller.formatTime($scope.startTime),
                    endTime: controller.formatTime($scope.endTime),
                    comment: $scope.comment
                };
            };

            /**
             * Advance to the next monday-friday that is not a public holiday.
             * @param date The date to advance
             * @returns {date|*} The date advanced to the next day.
             */
            controller.advanceToNextWorkDay = function(date) {
                var mdate = moment(date).add('days', 1);
                while(!controller.isWorkDay(mdate, holidays)) {
                    mdate.add('days', 1);
                }
                return mdate.toDate();
            };

            /**
             * Test if a day is a work day given a list of public holidays.
             * @param date The date to test
             * @param holidays A list of public holidays
             * @returns {boolean} true if the date is a monday-friday that is not in the list, false otherwise.
             */
            controller.isWorkDay = function(date, holidays) {
                return date.day() !== 6 && date.day() !== 0 && !_.find(holidays, {day: date.format('YYYY-MM-DD')});
            };

            $scope.saveTime = function() {
                var workTimeObject = controller.createWorkTimeEntity();
                Restangular.all('workTimes').post(workTimeObject).then(function() {
                    $scope.errors = [];
                    $scope.date = controller.advanceToNextWorkDay($scope.date);
                    NotificationService.info('Working time saved.');
                }, function(response) {
                    $scope.errors = response.data.errors;
                    NotificationService.error('Error saving working time');
                });
            };
        }];
});<|endoftext|>


<commit_before>var mongoose = require('mongoose');
var Project = mongoose.model('Project');
var User = mongoose.model('User');

//var _ = require( 'lodash' );

module.exports.createProject = function(req, res){
    var project = new Project();

    User.findOne({'userName': req.body.userName}, function (err, obj){
        if (err){
            console.log("something went wrong");
        } else {

            project.projectName = req.body.projectName;
            project.uniqueKey = req.body.uniqueKey;
            project.ownerID = obj._id;
            project.info = req.body.info;
            project.dateCreated = Date.now();
            project.collaborators = req.body.collaborators;

            project.save(function(err) {
                res.status(200);
                res.json({
                    "status": "everything worked fine"
                });
                obj.ownProjects.push({projectName: req.body.projectName, projectID: project._id});
                obj.save(function(error){
                    if(error){
                        console.log("something went wrong");
                    }
                });
            });
            var coll = req.body.collaborators;
            for(var i = 0; i < coll.length; i++){
                User.findOne({'email': coll[i]}, function (err, collabo){
                    if (err){
                        console.log("something went wrong");
                    } else {
                        collabo.coopProjects.push({projectName: project.projectName, projectID: project._id});
                        collabo.save(function(e){
                            if(e){
                                console.log("something went wrong");
                            }
                        })
                    }
                });
            }
        }
    });
    for(var j=0; j < req.body.collaborators.length; j++){
        User.findOne({'email': req.body.collaborators[j]}, function (e, col){
            if(e){
                console.log("something went wrong");
            } else {
                project.collaboratorID.push(col._id);
                project.update();
            }
        });
    }
};

module.exports.projectRead = function(req, res) {

    /*
     Important notice:
     for triggering this function,
     req must contain the Projects ID;

     this means, the respective project._id must be provided as JSON to the function (or otherwise attribute of function call, in this case, change attribute formatting).
     */
    /*
    Project
        .findOne({'ownerID': req.payload._id}, function(err, obj){
            if(err){
                res.status(401).json("couldnt load the project");
            }else{
                res.status(200).json(obj);
            }
        });
        */

    console.log(req.params.id);

    Project
        .findById(req.params.id, function(err, obj){
            if(err){
                res.status(401).json("could not load the project");
            } else {
                res.status(200).json(obj);
            }
        });
};

// ***********
// ** TODO: **
// ***********

// adapt dependencies and mechanics
// to project management requirements

// create and handle edit logging

module.exports.projectUpdate = function(req, res) {

    //var query = {'ownerID': req.payload._id};

    Project
        .findByIdAndUpdate(req.params.id, req.body, function(err, obj) {
            if(err){
                res.status(401).json("couldnt update the project");
            } else{
                res.status(200).json(obj);
            }
        });

    /*
     if (!req.payload._id) {
     res.status(401).json({
     "message": "UnauthorizedError: cannot update project without being logged in as a user"
     });
     } else {
     // authorization needed, so not every user can change a project
     // validate user as author or collaborator,
     // otherwise shoot down request
     Project.findById(req.body._id)
     .exec(function (err, project) {
     if (err) {
     res.status(401).json({
     "message": "dbError: Error performing FindById"
     });
     } else if ( req.payload._id === project.ownerID ) {
     // Editor is owner
     Project.findByIdAndUpdate(req.payload._id, req.body, {runValidators: true, upsert: true})
     .exec(function (err, user) {
     res.status(200).json(project);
     })
     } else if ( _.includes( project.collaborators, req.payload._id )) {
     // Editor is collaborator
     Project.findByIdAndUpdate(req.payload._id, req.body, {runValidators: true, upsert: true})
     .exec(function (err, user) {
     res.status(200).json(project);
     })
     } else {
     res.status(401).json({
     "message": "UnauthorizedError: Must be owner or collaborator to edit project"
     })
     }
     });
     }*/
};

module.exports.projectDelete = function (req, res) {

    //var query = {'ownerID': req.payload._id};

    Project
        .findById(req.params.id, function(err, obj) {
            if(err){
                res.status(401).json("couldnt delete the project");
            } else{
                User.findOneAndUpdate({_id: obj.ownerID}, {$pull: {ownProjects: {projectID: obj._id}}}, function(err, data){
                    if(err){
                        console.log("something went wrong");
                    } else {
                        console.log("perfect");
                    }
                });

                for(var i = 0; i < obj.collaborators.length; i++){
                    User.findOneAndUpdate({email: obj.collaborators[i]}, {$pull: {coopProjects: {projectID: obj._id}}}, function(err, data){
                        if(err){
                            console.log("something went wrong");
                        } else {
                            console.log("nice");
                        }
                    });
                }
                obj.remove();
                res.status(200).json("removed the project");

                /*
                User
                    .findById(obj.ownerID, function (e, owner){
                        if(e){
                            console.log("something went wrong");
                        }else {
                            //owner.ownProjects.pull({projectName: obj.projectName, projectID: obj._id});
                            //for(var j=0; j < owner.ownProjects.length; j++){
                            //if (owner.ownProjects[j].projectID === obj._id) {
                                //delete owner.ownProjects[{projectName: obj.projectName, projectID:obj._id}];
                            //}
                        //}
                        }});
*/

                /*
                var coll = obj.collaborators;
                for(var i = 0; i < coll.length; i++){
                    User.findOne({'email': coll[i]}, function (error, collabo) {
                        if (error) {
                            console.log("something went wrong");
                        } else {
                            //collabo.coopProjects.pull({projectName: obj.projectName, projectID: obj._id});
                            //for(var m=0; m < collabo.coopProjects.length; m++){
                            //if (collabo.coopProjects[m].projectID === obj._id) {
                                //delete collabo.coopProjects[{projectName: obj.projectName, projectID:obj._id}];
                            //}}
                        }
                    });
            }
            */
        }});

    /*
     if (!req.payload._id) {
     res.status(401).json({
     "message": "UnauthorizedError: cannot delete profile without being logged in to it"
     });
     } else {
     Project.findById(req.payload._id)
     .exec(function (err, value) {
     if (err) {
     res.status(401).json({
     "message": "DeleteError: could not delete feature"
     });
     } else if ( req.payload._id === project.ownerID ) {
     console.log('feature removed (logging just for testing)');
     value.remove();
     res.status(200).send('removed Feature');
     } else {
     res.status(401).json({
     "message": "UnauthorizedError: Must be owner to delete project"
     });
     }
     });
     }*/
};<commit_msg>fixed process breakdown issues resulting from aynchronous saving (quick-fix using timeout)<commit_after>var mongoose = require('mongoose');
var Project = mongoose.model('Project');
var User = mongoose.model('User');

//var _ = require( 'lodash' );

module.exports.createProject = function(req, res){
    var project = new Project();

    User.findOne({'userName': req.body.userName}, function (err, obj){
        if (err || obj.id === null || obj.id === undefined){
            console.log("something went wrong");
        } else {

            project.projectName = req.body.projectName;
            project.uniqueKey = req.body.uniqueKey;
            project.ownerID = obj._id;
            project.info = req.body.info;
            project.dateCreated = Date.now();
            project.collaborators = req.body.collaborators;

            project.save(function(err) {
                res.status(200);
                res.json({
                    "status": "everything worked fine"
                });
                setTimeout( function ()
                {
                    obj.ownProjects.push({projectName: req.body.projectName, projectID: project._id});
                    obj.save(function(error){
                        if(error){
                            console.log("something went wrong");
                        }
                    });
                }, 50);
            });
            var coll = req.body.collaborators;
            for(var i = 0; i < coll.length; i++){
                User.findOne({'email': coll[i]}, function (err, collabo){
                    if (err){
                        console.log("something went wrong");
                    } else {
                        collabo.coopProjects.push({projectName: project.projectName, projectID: project._id});
                        collabo.save(function(e){
                            if(e){
                                console.log("something went wrong");
                            }
                        })
                    }
                });
            }
        }
    });
    for(var j=0; j < req.body.collaborators.length; j++){
        User.findOne({'email': req.body.collaborators[j]}, function (e, col){
            if(e) {
                console.log("something went wrong");
            } else if (col === null)
            {
                console.log(req.body.collaborators[j] + " is not a valid collaborator")

            } else {
                project.collaboratorID.push(col._id);
                project.update();
            }
        });
    }
};

module.exports.projectRead = function(req, res) {

    /*
     Important notice:
     for triggering this function,
     req must contain the Projects ID;

     this means, the respective project._id must be provided as JSON to the function (or otherwise attribute of function call, in this case, change attribute formatting).
     */
    /*
    Project
        .findOne({'ownerID': req.payload._id}, function(err, obj){
            if(err){
                res.status(401).json("couldnt load the project");
            }else{
                res.status(200).json(obj);
            }
        });
        */

    console.log(req.params.id);

    Project
        .findById(req.params.id, function(err, obj){
            if(err){
                res.status(401).json("could not load the project");
            } else {
                res.status(200).json(obj);
            }
        });
};

// ***********
// ** TODO: **
// ***********

// adapt dependencies and mechanics
// to project management requirements

// create and handle edit logging

module.exports.projectUpdate = function(req, res) {

    //var query = {'ownerID': req.payload._id};

    Project
        .findByIdAndUpdate(req.params.id, req.body, function(err, obj) {
            if(err){
                res.status(401).json("couldnt update the project");
            } else{
                res.status(200).json(obj);
            }
        });

    /*
     if (!req.payload._id) {
     res.status(401).json({
     "message": "UnauthorizedError: cannot update project without being logged in as a user"
     });
     } else {
     // authorization needed, so not every user can change a project
     // validate user as author or collaborator,
     // otherwise shoot down request
     Project.findById(req.body._id)
     .exec(function (err, project) {
     if (err) {
     res.status(401).json({
     "message": "dbError: Error performing FindById"
     });
     } else if ( req.payload._id === project.ownerID ) {
     // Editor is owner
     Project.findByIdAndUpdate(req.payload._id, req.body, {runValidators: true, upsert: true})
     .exec(function (err, user) {
     res.status(200).json(project);
     })
     } else if ( _.includes( project.collaborators, req.payload._id )) {
     // Editor is collaborator
     Project.findByIdAndUpdate(req.payload._id, req.body, {runValidators: true, upsert: true})
     .exec(function (err, user) {
     res.status(200).json(project);
     })
     } else {
     res.status(401).json({
     "message": "UnauthorizedError: Must be owner or collaborator to edit project"
     })
     }
     });
     }*/
};

module.exports.projectDelete = function (req, res) {

    //var query = {'ownerID': req.payload._id};

    Project
        .findById(req.params.id, function(err, obj) {
            if(err){
                res.status(401).json("couldnt delete the project");
            } else{
                User.findOneAndUpdate({_id: obj.ownerID}, {$pull: {ownProjects: {projectID: obj._id}}}, function(err, data){
                    if(err){
                        console.log("something went wrong");
                    } else {
                        console.log("perfect");
                    }
                });

                for(var i = 0; i < obj.collaborators.length; i++){
                    User.findOneAndUpdate({email: obj.collaborators[i]}, {$pull: {coopProjects: {projectID: obj._id}}}, function(err, data){
                        if(err){
                            console.log("something went wrong");
                        } else {
                            console.log("nice");
                        }
                    });
                }
                obj.remove();
                res.status(200).json("removed the project");

                /*
                User
                    .findById(obj.ownerID, function (e, owner){
                        if(e){
                            console.log("something went wrong");
                        }else {
                            //owner.ownProjects.pull({projectName: obj.projectName, projectID: obj._id});
                            //for(var j=0; j < owner.ownProjects.length; j++){
                            //if (owner.ownProjects[j].projectID === obj._id) {
                                //delete owner.ownProjects[{projectName: obj.projectName, projectID:obj._id}];
                            //}
                        //}
                        }});
*/

                /*
                var coll = obj.collaborators;
                for(var i = 0; i < coll.length; i++){
                    User.findOne({'email': coll[i]}, function (error, collabo) {
                        if (error) {
                            console.log("something went wrong");
                        } else {
                            //collabo.coopProjects.pull({projectName: obj.projectName, projectID: obj._id});
                            //for(var m=0; m < collabo.coopProjects.length; m++){
                            //if (collabo.coopProjects[m].projectID === obj._id) {
                                //delete collabo.coopProjects[{projectName: obj.projectName, projectID:obj._id}];
                            //}}
                        }
                    });
            }
            */
        }});

    /*
     if (!req.payload._id) {
     res.status(401).json({
     "message": "UnauthorizedError: cannot delete profile without being logged in to it"
     });
     } else {
     Project.findById(req.payload._id)
     .exec(function (err, value) {
     if (err) {
     res.status(401).json({
     "message": "DeleteError: could not delete feature"
     });
     } else if ( req.payload._id === project.ownerID ) {
     console.log('feature removed (logging just for testing)');
     value.remove();
     res.status(200).send('removed Feature');
     } else {
     res.status(401).json({
     "message": "UnauthorizedError: Must be owner to delete project"
     });
     }
     });
     }*/
};<|endoftext|>


<commit_before>var libpath = process.env.JMX_COVERAGE ? "./../lib-cov" : "./../lib";

var assert = require("assert"),
    java = require("java"),
    JavaJmx = require(libpath + "/javaJmx.js"),
    MBeanServerConnection = require(libpath + "/adapters/mbeanServerConnection.js");

describe("JavaJmx", function() {
  var javaJmx;
  beforeEach(function() {
    javaJmx = new JavaJmx("localhost", 3000);
    javaJmx.mbeanServerConnection.queryMBeans = function(objName, queryObject, callback, end_callback) {
      var instance = java.newInstanceSync("javax.management.ObjectInstance", "MBean1:type=MBean1", "java.lang.Object");
      callback(instance, end_callback || function() {});
    };
  });

  describe("#JavaJmx", function() {

    it("returns a JavaJmx object passing the correct arguments", function() {
      assert.ok(javaJmx instanceof JavaJmx);
    });

    it("creates an internal MBeanServerConnection object", function() {
      assert.ok(javaJmx.mbeanServerConnection instanceof MBeanServerConnection);
    });

    describe("subscribes to MBeanServerConnection events", function() {
      var emitted;
      beforeEach(function() {
        emitted = [];
        javaJmx.emit = function(ev) {
          emitted.push(ev);
        };
      });

      it("connect event", function() {
        javaJmx.mbeanServerConnection.emit("connect");
        assert.deepEqual(emitted, [ "connect" ]);
      });

      it("disconnect event", function() {
        javaJmx.mbeanServerConnection.emit("disconnect");
        assert.deepEqual(emitted, [ "disconnect" ]);
      });

      it("error event", function() {
        javaJmx.mbeanServerConnection.emit("error");
        assert.deepEqual(emitted, [ "error" ]);
      });

    });

    it("closes the connection when a \"Connection Refused\" java error is returned", function(done) {
      javaJmx.mbeanServerConnection.close = function() {
        done();
      };
      javaJmx.on("error", function(err) {
        assert.strictEqual(err, "java.net.ConnectException: Connection refused");
      });
      javaJmx.mbeanServerConnection.emit("error", "java.net.ConnectException: Connection refused");
    });

  });

  describe("#JmxServiceUrl", function() {
    it("creates a JMXServiceURL java object", function() {
      var jmxServiceUrl = javaJmx.JmxServiceUrl("localhost", 3000);
      assert.strictEqual(
        jmxServiceUrl.getClassSync().getNameSync(),
        "javax.management.remote.JMXServiceURL"
      );
    });
  });

  it("#connect", function(done) {
    javaJmx.mbeanServerConnection.connect = function(jmxServiceUrl, undef) {
      assert.strictEqual(jmxServiceUrl, "jmxServiceUrl");
      assert.strictEqual(undef, undefined);
      done();
    };
    javaJmx.connect("jmxServiceUrl");
  });

  it("#disconnect", function(done) {
    javaJmx.mbeanServerConnection.close = function(undef) {
      assert.strictEqual(undef, undefined);
      done();
    };
    javaJmx.disconnect();
  });

  it("#getAttributes", function(done) {
    javaJmx.mbeanServerConnection.getAttributes = function(objectName, attributes, callback, undef) {
      assert.strictEqual(objectName.toString(), "MBean1:type=MBean1");
      assert.deepEqual(attributes, [ "attribute", "attribute" ] );
      assert.strictEqual(typeof callback, "function");
      assert.strictEqual(undef, undefined);
      attributes = { toArray: function(cb) { cb(false, []); } };
      callback(attributes);
    };
    javaJmx.getAttributes("mbean", [ "attribute", "attribute" ], function(attr) {
      done();
    });
  });

  it("#getAttribute", function(done) {
    javaJmx.mbeanServerConnection.getAttribute = function(objectName, attributeName, callback, undef) {
      assert.strictEqual(objectName.toString(), "MBean1:type=MBean1");
      assert.strictEqual(attributeName, "attributeName");
      assert.strictEqual(typeof callback, "function");
      assert.strictEqual(undef, undefined);
      callback();
    };
    javaJmx.getAttribute("mbean", "attributeName", function(attr) {
      done();
    });
  });

  it("#getDefautlDomain", function(done) {
    javaJmx.mbeanServerConnection.getDefaultDomain = function(undef) {
      assert.strictEqual(undef, undefined);
      done();
    };
    javaJmx.getDefaultDomain();
  });

  it("#getDomains", function(done) {
    javaJmx.mbeanServerConnection.getDomains = function(undef) {
      assert.strictEqual(undef, undefined);
      done();
    };
    javaJmx.getDomains();
  });

  it("#getMBeanCount", function(done) {
    javaJmx.mbeanServerConnection.getMBeanCount = function(undef) {
      assert.strictEqual(undef, undefined);
      done();
    };
    javaJmx.getMBeanCount();
  });

  describe("#setAttribute", function() {

    it("accepts three parameters", function(done) {
      javaJmx.mbeanServerConnection.setAttribute = function(objectName, attribute, callback, undef) {
        assert.strictEqual(objectName.toString(), "MBean1:type=MBean1");
        assert.strictEqual(attribute.getClassSync().getNameSync(), "javax.management.Attribute");
        assert.strictEqual(attribute.getNameSync(), "attributeName");
        assert.strictEqual(attribute.getValueSync(), "value");
        assert.strictEqual(callback, undefined);
        assert.strictEqual(undef, undefined);
        done();
      };
      javaJmx.setAttribute("mbean", "attributeName", "value");
    });

    it("accepts a callback as the third parameter", function(done) {
      javaJmx.mbeanServerConnection.setAttribute = function(objectName, attribute, callback, undef) {
        assert.strictEqual(objectName.toString(), "MBean1:type=MBean1");
        assert.strictEqual(attribute.getClassSync().getNameSync(), "javax.management.Attribute");
        assert.strictEqual(attribute.getNameSync(), "attributeName");
        assert.strictEqual(attribute.getValueSync(), "value");
        assert.strictEqual(typeof callback, "function");
        assert.strictEqual(undef, undefined);
        callback();
      };
      javaJmx.setAttribute("mbean", "attributeName", "value", done);
    });

    it("accepts a className as third parameter with a callback", function(done) {
      javaJmx.mbeanServerConnection.setAttribute = function(objectName, attribute, callback) {
        assert.strictEqual(attribute.getValueSync().getClassSync().getNameSync(), "javax.management.ObjectName");
        assert.strictEqual(attribute.getValueSync().getDomainSync(), "domain");
        callback();
      };
      javaJmx.setAttribute("mbean", "attributeName", [ "domain", "name", "value" ], "javax.management.ObjectName", done);
    });

    it("accepts a className as third parameter without a callback", function(done) {
      javaJmx.mbeanServerConnection.setAttribute = function(objectName, attribute, callback) {
        assert.strictEqual(attribute.getValueSync().getClassSync().getNameSync(), "javax.management.ObjectName");
        assert.strictEqual(attribute.getValueSync().getDomainSync(), "domain");
        done();
      };
      javaJmx.setAttribute("mbean", "attributeName", [ "domain", "name", "value" ], "javax.management.ObjectName");
    });

  });

  it("#setCredentials", function(done) {
    javaJmx.mbeanServerConnection.setCredentials = function(username, password, undef) {
      assert.strictEqual(username, "username");
      assert.strictEqual(password, "password");
      assert.strictEqual(undef, undefined);
      done();
    };
    javaJmx.setCredentials("username", "password");
  });

  describe("#invoke", function() {

    it("accepts three parameters", function(done) {
      javaJmx.mbeanServerConnection.invoke = function(objectName, methodName, params, signature, callback, undef) {
        assert.strictEqual(objectName.toString(), "MBean1:type=MBean1");
        assert.strictEqual(methodName, "methodName");
        assert.deepEqual(params, [ "param1" ]);
        assert.deepEqual(signature, [ "java.lang.String" ]);
        assert.strictEqual(callback, undefined);
        assert.strictEqual(undef, undefined);
        done();
      };
      javaJmx.invoke("mbean", "methodName", [ "param1" ]);
    });

    it("accepts a callback as the fourth parameter", function(done) {
      javaJmx.mbeanServerConnection.invoke = function(objectName, methodName, params, signature, callback, undef) {
        assert.strictEqual(objectName.toString(), "MBean1:type=MBean1");
        assert.strictEqual(methodName, "methodName");
        assert.deepEqual(params, [ "param1" ]);
        assert.deepEqual(signature, [ "java.lang.String" ]);
        assert.strictEqual(typeof callback, "function");
        assert.strictEqual(undef, undefined);
        callback();
      };
      javaJmx.invoke("mbean", "methodName", [ "param1" ], function(value) {
        done();
      });
    });

    it("accepts a signature as the fourth parameter with a callback", function(done) {
      javaJmx.mbeanServerConnection.invoke = function(objectName, methodName, params, signature, callback, undef) {
        assert.strictEqual(objectName.toString(), "MBean1:type=MBean1");
        assert.strictEqual(methodName, "methodName");
        assert.deepEqual(params, [ "param1" ]);
        assert.deepEqual(signature, [ "int" ]);
        assert.strictEqual(typeof callback, "function");
        assert.strictEqual(undef, undefined);
        callback();
      };
      javaJmx.invoke("mbean", "methodName", [ "param1" ], [ "int" ], function(value) {
        done();
      });
    });

    it(" accepts a signature as the fourth parameter without a callback", function(done) {
      javaJmx.mbeanServerConnection.invoke = function(objectName, methodName, params, signature, callback, undef) {
        assert.strictEqual(objectName.toString(), "MBean1:type=MBean1");
        assert.strictEqual(methodName, "methodName");
        assert.deepEqual(params, [ "param1" ]);
        assert.deepEqual(signature, [ "int" ]);
        assert.strictEqual(callback, undefined);
        assert.strictEqual(undef, undefined);
        done();
      };
      javaJmx.invoke("mbean", "methodName", [ "param1" ], [ "int" ]);
    });

    it("throws an exception when params has unknown types", function(done) {
      javaJmx.mbeanServerConnection.invoke = function(objectName, methodName, params, signature, callback, undef) {};
      javaJmx.on("error", function(err) {
        assert.ok(/v8ToJavaClass[(][)]: unknown object type/.test(err));
        done();
      });
      javaJmx.invoke("mbean", "methodName", [ undefined ], function() {});
    });

  });

  it("#listMBeans", function(done) {
    function arrayContains(arr, value) {
      for (var k in arr) {
        if (arr[k] == value) return true;
      }
      return false;
    }

    javaJmx.listMBeans(function(mbeans) {
      assert.ok(arrayContains(mbeans, "MBean1:type=MBean1"));
      done();
    });
  });

});
<commit_msg>test/JavaJmx: remove a space in a description<commit_after>var libpath = process.env.JMX_COVERAGE ? "./../lib-cov" : "./../lib";

var assert = require("assert"),
    java = require("java"),
    JavaJmx = require(libpath + "/javaJmx.js"),
    MBeanServerConnection = require(libpath + "/adapters/mbeanServerConnection.js");

describe("JavaJmx", function() {
  var javaJmx;
  beforeEach(function() {
    javaJmx = new JavaJmx("localhost", 3000);
    javaJmx.mbeanServerConnection.queryMBeans = function(objName, queryObject, callback, end_callback) {
      var instance = java.newInstanceSync("javax.management.ObjectInstance", "MBean1:type=MBean1", "java.lang.Object");
      callback(instance, end_callback || function() {});
    };
  });

  describe("#JavaJmx", function() {

    it("returns a JavaJmx object passing the correct arguments", function() {
      assert.ok(javaJmx instanceof JavaJmx);
    });

    it("creates an internal MBeanServerConnection object", function() {
      assert.ok(javaJmx.mbeanServerConnection instanceof MBeanServerConnection);
    });

    describe("subscribes to MBeanServerConnection events", function() {
      var emitted;
      beforeEach(function() {
        emitted = [];
        javaJmx.emit = function(ev) {
          emitted.push(ev);
        };
      });

      it("connect event", function() {
        javaJmx.mbeanServerConnection.emit("connect");
        assert.deepEqual(emitted, [ "connect" ]);
      });

      it("disconnect event", function() {
        javaJmx.mbeanServerConnection.emit("disconnect");
        assert.deepEqual(emitted, [ "disconnect" ]);
      });

      it("error event", function() {
        javaJmx.mbeanServerConnection.emit("error");
        assert.deepEqual(emitted, [ "error" ]);
      });

    });

    it("closes the connection when a \"Connection Refused\" java error is returned", function(done) {
      javaJmx.mbeanServerConnection.close = function() {
        done();
      };
      javaJmx.on("error", function(err) {
        assert.strictEqual(err, "java.net.ConnectException: Connection refused");
      });
      javaJmx.mbeanServerConnection.emit("error", "java.net.ConnectException: Connection refused");
    });

  });

  describe("#JmxServiceUrl", function() {
    it("creates a JMXServiceURL java object", function() {
      var jmxServiceUrl = javaJmx.JmxServiceUrl("localhost", 3000);
      assert.strictEqual(
        jmxServiceUrl.getClassSync().getNameSync(),
        "javax.management.remote.JMXServiceURL"
      );
    });
  });

  it("#connect", function(done) {
    javaJmx.mbeanServerConnection.connect = function(jmxServiceUrl, undef) {
      assert.strictEqual(jmxServiceUrl, "jmxServiceUrl");
      assert.strictEqual(undef, undefined);
      done();
    };
    javaJmx.connect("jmxServiceUrl");
  });

  it("#disconnect", function(done) {
    javaJmx.mbeanServerConnection.close = function(undef) {
      assert.strictEqual(undef, undefined);
      done();
    };
    javaJmx.disconnect();
  });

  it("#getAttributes", function(done) {
    javaJmx.mbeanServerConnection.getAttributes = function(objectName, attributes, callback, undef) {
      assert.strictEqual(objectName.toString(), "MBean1:type=MBean1");
      assert.deepEqual(attributes, [ "attribute", "attribute" ] );
      assert.strictEqual(typeof callback, "function");
      assert.strictEqual(undef, undefined);
      attributes = { toArray: function(cb) { cb(false, []); } };
      callback(attributes);
    };
    javaJmx.getAttributes("mbean", [ "attribute", "attribute" ], function(attr) {
      done();
    });
  });

  it("#getAttribute", function(done) {
    javaJmx.mbeanServerConnection.getAttribute = function(objectName, attributeName, callback, undef) {
      assert.strictEqual(objectName.toString(), "MBean1:type=MBean1");
      assert.strictEqual(attributeName, "attributeName");
      assert.strictEqual(typeof callback, "function");
      assert.strictEqual(undef, undefined);
      callback();
    };
    javaJmx.getAttribute("mbean", "attributeName", function(attr) {
      done();
    });
  });

  it("#getDefautlDomain", function(done) {
    javaJmx.mbeanServerConnection.getDefaultDomain = function(undef) {
      assert.strictEqual(undef, undefined);
      done();
    };
    javaJmx.getDefaultDomain();
  });

  it("#getDomains", function(done) {
    javaJmx.mbeanServerConnection.getDomains = function(undef) {
      assert.strictEqual(undef, undefined);
      done();
    };
    javaJmx.getDomains();
  });

  it("#getMBeanCount", function(done) {
    javaJmx.mbeanServerConnection.getMBeanCount = function(undef) {
      assert.strictEqual(undef, undefined);
      done();
    };
    javaJmx.getMBeanCount();
  });

  describe("#setAttribute", function() {

    it("accepts three parameters", function(done) {
      javaJmx.mbeanServerConnection.setAttribute = function(objectName, attribute, callback, undef) {
        assert.strictEqual(objectName.toString(), "MBean1:type=MBean1");
        assert.strictEqual(attribute.getClassSync().getNameSync(), "javax.management.Attribute");
        assert.strictEqual(attribute.getNameSync(), "attributeName");
        assert.strictEqual(attribute.getValueSync(), "value");
        assert.strictEqual(callback, undefined);
        assert.strictEqual(undef, undefined);
        done();
      };
      javaJmx.setAttribute("mbean", "attributeName", "value");
    });

    it("accepts a callback as the third parameter", function(done) {
      javaJmx.mbeanServerConnection.setAttribute = function(objectName, attribute, callback, undef) {
        assert.strictEqual(objectName.toString(), "MBean1:type=MBean1");
        assert.strictEqual(attribute.getClassSync().getNameSync(), "javax.management.Attribute");
        assert.strictEqual(attribute.getNameSync(), "attributeName");
        assert.strictEqual(attribute.getValueSync(), "value");
        assert.strictEqual(typeof callback, "function");
        assert.strictEqual(undef, undefined);
        callback();
      };
      javaJmx.setAttribute("mbean", "attributeName", "value", done);
    });

    it("accepts a className as third parameter with a callback", function(done) {
      javaJmx.mbeanServerConnection.setAttribute = function(objectName, attribute, callback) {
        assert.strictEqual(attribute.getValueSync().getClassSync().getNameSync(), "javax.management.ObjectName");
        assert.strictEqual(attribute.getValueSync().getDomainSync(), "domain");
        callback();
      };
      javaJmx.setAttribute("mbean", "attributeName", [ "domain", "name", "value" ], "javax.management.ObjectName", done);
    });

    it("accepts a className as third parameter without a callback", function(done) {
      javaJmx.mbeanServerConnection.setAttribute = function(objectName, attribute, callback) {
        assert.strictEqual(attribute.getValueSync().getClassSync().getNameSync(), "javax.management.ObjectName");
        assert.strictEqual(attribute.getValueSync().getDomainSync(), "domain");
        done();
      };
      javaJmx.setAttribute("mbean", "attributeName", [ "domain", "name", "value" ], "javax.management.ObjectName");
    });

  });

  it("#setCredentials", function(done) {
    javaJmx.mbeanServerConnection.setCredentials = function(username, password, undef) {
      assert.strictEqual(username, "username");
      assert.strictEqual(password, "password");
      assert.strictEqual(undef, undefined);
      done();
    };
    javaJmx.setCredentials("username", "password");
  });

  describe("#invoke", function() {

    it("accepts three parameters", function(done) {
      javaJmx.mbeanServerConnection.invoke = function(objectName, methodName, params, signature, callback, undef) {
        assert.strictEqual(objectName.toString(), "MBean1:type=MBean1");
        assert.strictEqual(methodName, "methodName");
        assert.deepEqual(params, [ "param1" ]);
        assert.deepEqual(signature, [ "java.lang.String" ]);
        assert.strictEqual(callback, undefined);
        assert.strictEqual(undef, undefined);
        done();
      };
      javaJmx.invoke("mbean", "methodName", [ "param1" ]);
    });

    it("accepts a callback as the fourth parameter", function(done) {
      javaJmx.mbeanServerConnection.invoke = function(objectName, methodName, params, signature, callback, undef) {
        assert.strictEqual(objectName.toString(), "MBean1:type=MBean1");
        assert.strictEqual(methodName, "methodName");
        assert.deepEqual(params, [ "param1" ]);
        assert.deepEqual(signature, [ "java.lang.String" ]);
        assert.strictEqual(typeof callback, "function");
        assert.strictEqual(undef, undefined);
        callback();
      };
      javaJmx.invoke("mbean", "methodName", [ "param1" ], function(value) {
        done();
      });
    });

    it("accepts a signature as the fourth parameter with a callback", function(done) {
      javaJmx.mbeanServerConnection.invoke = function(objectName, methodName, params, signature, callback, undef) {
        assert.strictEqual(objectName.toString(), "MBean1:type=MBean1");
        assert.strictEqual(methodName, "methodName");
        assert.deepEqual(params, [ "param1" ]);
        assert.deepEqual(signature, [ "int" ]);
        assert.strictEqual(typeof callback, "function");
        assert.strictEqual(undef, undefined);
        callback();
      };
      javaJmx.invoke("mbean", "methodName", [ "param1" ], [ "int" ], function(value) {
        done();
      });
    });

    it("accepts a signature as the fourth parameter without a callback", function(done) {
      javaJmx.mbeanServerConnection.invoke = function(objectName, methodName, params, signature, callback, undef) {
        assert.strictEqual(objectName.toString(), "MBean1:type=MBean1");
        assert.strictEqual(methodName, "methodName");
        assert.deepEqual(params, [ "param1" ]);
        assert.deepEqual(signature, [ "int" ]);
        assert.strictEqual(callback, undefined);
        assert.strictEqual(undef, undefined);
        done();
      };
      javaJmx.invoke("mbean", "methodName", [ "param1" ], [ "int" ]);
    });

    it("throws an exception when params has unknown types", function(done) {
      javaJmx.mbeanServerConnection.invoke = function(objectName, methodName, params, signature, callback, undef) {};
      javaJmx.on("error", function(err) {
        assert.ok(/v8ToJavaClass[(][)]: unknown object type/.test(err));
        done();
      });
      javaJmx.invoke("mbean", "methodName", [ undefined ], function() {});
    });

  });

  it("#listMBeans", function(done) {
    function arrayContains(arr, value) {
      for (var k in arr) {
        if (arr[k] == value) return true;
      }
      return false;
    }

    javaJmx.listMBeans(function(mbeans) {
      assert.ok(arrayContains(mbeans, "MBean1:type=MBean1"));
      done();
    });
  });

});
<|endoftext|>