1 /* 2 * Copyright (C) 2008-2009 WaveMaker Software, Inc. 3 * 4 * This file is part of the WaveMaker Client Runtime. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 dojo.provide("wm.base.components.Service"); 19 dojo.require("wm.base.Component"); 20 21 /** 22 Component that can be configured to perform a task. 23 <br/><br/> 24 @name wm.Service 25 @class 26 @extends wm.Component 27 */ 28 dojo.declare("wm.Service", wm.Component, { 29 /** @lends wm.Service.prototype */ 30 _operations: {}, 31 /** 32 Result data (if any) returned from the last invocation. 33 */ 34 result: null, 35 /** 36 Error data (if any) returned from the last invocation. 37 */ 38 error: null, 39 getOperationsList: function() { 40 var l = []; 41 for (var i in this._operations) 42 l.push(i); 43 l.sort(); 44 return l; 45 }, 46 getOperation: function(inOperation) { 47 return this._operations[inOperation]; 48 }, 49 initService: function() { 50 }, 51 /** 52 Invoke a method on this service object with arguments. 53 <br/><br/> 54 Invocations may be asynchronous. Responses are available 55 via the returned Deferred object or from the 56 <a href="#onResult">onResult</a> and 57 <a href="#onError">onError</a> events. 58 @param {String} inMethod The method to invoke on this object. 59 @param {Array} inArgs An array of parameters for the method. 60 @returns {dojo.Deferred} Response handler object. 61 */ 62 invoke: function(inMethod, inArgs) { 63 var 64 d = new dojo.Deferred(), 65 m = this[inMethod]; 66 if (m) { 67 var result = m.apply(this, inArgs); 68 this.onResult(); 69 wm.onidle(function() { 70 d.callback(result); 71 }); 72 } else { 73 this.onError(); 74 wm.onidle(function() { 75 d.errback("operation: " + inMethod + " does not exist."); 76 }); 77 } 78 return d; 79 }, 80 /** 81 Event that fires after a succesful service invocation. 82 @param {Any} inResult Any result data returned from the service. 83 */ 84 onResult: function(inResult) { 85 this.error = null; 86 return this.result = inResult; 87 }, 88 /** 89 Event that fires after a service invocation has resulted in an error. 90 @param {Any} inError Any error data returned from the service. 91 */ 92 onError: function(inError) { 93 this.result = null; 94 return this.error = inError; 95 } 96 }); 97 98 // FIXME: needs its own module 99 // ========================================================== 100 // Services registry (provides info about available services) 101 // ========================================================== 102 103 wm.services = { 104 byName: {}, 105 _services: {}, 106 add: function(inService){ 107 return wm.services.byName[inService.name] = inService; 108 }, 109 remove: function(inService){ 110 var n = inService.name; 111 this._destroyService(n); 112 delete wm.services.byName[n]; 113 }, 114 getNamesList: function() { 115 var l = [], services = wm.services.byName, s; 116 for (var i in services) { 117 s = services[i]; 118 if (!s.clientHide) 119 l.push(i); 120 } 121 l.sort(); 122 return l; 123 }, 124 forEach: function(inFunction) { 125 wm.forEach(this.byName, function(s) { 126 inFunction(s); 127 }); 128 }, 129 clear: function() { 130 var n = wm.services.byName, s; 131 for (var i in n) { 132 s = n[i]; 133 if (!s.isClientService) 134 this.remove(s); 135 else 136 this._destroyService(s); 137 } 138 }, 139 getService: function(inName) { 140 var s; 141 if (inName) { 142 s = this._services[inName] || this._createService(inName); 143 if (!s._service) 144 s.initService(); 145 } 146 return s; 147 }, 148 _createService: function(inName) { 149 var 150 defaultCtor = "wm.JsonRpcService", 151 s = this.byName[inName]; 152 if (!s) 153 s = this.add({name: inName, ctor: defaultCtor}); 154 var ctor = dojo.getObject(s.ctor || defaultCtor); 155 // FIXME: we don't want to be streamed so don't include owner 156 // otoh without owner, we don't know how to resolve paths at designTime 157 var service = new ctor({name: inName, service: inName}); 158 service.owner = dojo.getObject("studio.wip.app") || app; 159 return service; 160 }, 161 _destroyService: function(inService) { 162 wm.fire(this._services[inService.name], "destroy"); 163 } 164 }; 165