/* Copyright (c) 2013 [Web App Solution, Inc.](mailto:admin@webappsolution.com) FlowMVC is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. FlowMVC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with FlowMVC. If not, see <http://www.gnu.org/licenses/>. */ /** * The base class for services. Provides some helper methods for calling the successful and failed callbacks * provided by the client object using this service. * * In order to use this object and ensure the callbacks work correctly, please follow these steps: * * Get a reference to your service and set the responder on it like: * * var service = this.getAuthenticationService(); // DeftJS injection * * or * * var service = Ext.create("CafeTownsend.service.AuthenticationService"); // traditional instance creation * * var responder = Ext.create("FlowMVC.mvc.service.rpc.Responder", this.logoutSuccess, this.logoutFailure, this); * service.setResponder(responder); * * or * * service.setResponder({ * success: me.loginSuccess, * fault: me.loginFailure, * scope: me * }); * * Where "me" is usually this in the object using the service. */ Ext.define("FlowMVC.mvc.service.AbstractService", { requires: [ "FlowMVC.mvc.service.rpc.Responder", "FlowMVC.mvc.service.rpc.AsyncToken" ], statics: { /** * @property {FlowMVC.logger.Logger} logger The logger for the object. * @static */ logger: FlowMVC.logger.Logger.getLogger("FlowMVC.mvc.service.AbstractService"), /** * @property {String} NO_RESPONDER_DEFINED Error message for no responder defined. * @static */ NO_RESPONDER_DEFINED: "You must provide a responder object to the service that contains either a custom defined " + "success method that exists on the service's caller or a default 'success()' or 'failure()' callback." + "Set the responder on the object by doing:\n" + "var responder = Ext.create('FlowMVC.mvc.service.rpc.Responder', this.myCustomSuccess, this.myCustomFailure, this);\n" + "service.setResponder(responder);\n" + "or\n" + "service.setResponder({ success: this.myCustomSuccess, fault: this.myCustomFailure, scope: this});" }, config: { /** * @cfg {Boolean} usePromise Flag indicating if the service should use promises. * @accessor */ usePromise: false, /** * @cfg {FlowMVC.mvc.service.rpc.Responder} responder The responder object for this service contains * custom success and failure callback methods. * @accessor */ responder: null }, /** * Examines the responder set for the service and attempts to execute the specified callback * function and pass it the response. * * @param {Object} response The data packet from the service response. * @param {Function} responderMethod The string property name of the responder's 'success' or 'failure' property. * Allows for hash lookup of custom defined callback methods. */ applyResponderMethod: function(response, responderMethod) { FlowMVC.mvc.service.AbstractService.logger.debug("applyResponderMethod: ", responderMethod); var callbackFunction = null; if(this.getResponder() && this.getResponder().scope) { var scope = this.getResponder().scope; if(this.getResponder()[responderMethod]) { FlowMVC.mvc.service.AbstractService.logger.debug("applyResponderMethod: using service caller's custom defined " + responderMethod + " callback"); callbackFunction = this.getResponder()[responderMethod]; } else if(typeof scope[responderMethod] === "function") { FlowMVC.mvc.service.AbstractService.logger.debug("applyResponderMethod: using service caller's default " + responderMethod + " callback"); callbackFunction = scope[responderMethod]; } else { Ext.Error.raise({ msg: "["+ Ext.getDisplayName(arguments.callee) +"] " + CafeTownsend.service.AbstractService.NO_RESPONDER_DEFINED }); } FlowMVC.mvc.service.AbstractService.logger.groupEnd(); // execute the callback callbackFunction.call(scope, response); this.setResponder(null); } else { Ext.Error.raise({ msg: "["+ Ext.getDisplayName(arguments.callee) +"] " + CafeTownsend.service.AbstractService.NO_RESPONDER_DEFINED }); } }, /** * Default handler for service's successful execution. Relies on the applyResponderMethod() to * actually call the service's client object's (object that used the service) success handler. * * @param response The data packet response from the successful service call. */ success: function(response, token) { // FlowMVC.mvc.service.AbstractService.logger.group("AbstractService.success", true); FlowMVC.mvc.service.AbstractService.logger.info("success"); FlowMVC.mvc.service.AbstractService.logger.info(response); // if the service response isn't successful just kick this over to the fault handler if((response.success != null) && (response.success !== true)) { this.failure(response, token); return; } FlowMVC.mvc.service.AbstractService.logger.groupEnd(); if(token && (token instanceof FlowMVC.mvc.service.rpc.AsyncToken)) { token.applySuccess(response); } else if(token && (token instanceof Deft.promise.Deferred)) { token.resolve(response); } else { this.applyResponderMethod(response, "success"); } }, /** * Default handler for service's failed execution. Relies on the applyResponderMethod() to * actually call the service's client object's (object that used the service) failure handler. * * @param response The data packet response from the failed service call. */ failure: function(response, token) { FlowMVC.mvc.service.AbstractService.logger.info("failure"); FlowMVC.mvc.service.AbstractService.logger.groupEnd(); if(token && (token instanceof FlowMVC.mvc.service.rpc.AsyncToken)) { token.applyFailure(response); } else if(token && (token instanceof Deft.promise.Deferred)) { deferred.reject("There was a service error."); } else { this.applyResponderMethod(response, "failure"); } } });