智慧水务管理系统 - 精河县供水工程综合管理平台

service.js 6.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. "use strict";
  2. module.exports = Service;
  3. // extends Namespace
  4. var Namespace = require("./namespace");
  5. ((Service.prototype = Object.create(Namespace.prototype)).constructor = Service).className = "Service";
  6. var Method = require("./method"),
  7. util = require("./util"),
  8. rpc = require("./rpc");
  9. /**
  10. * Constructs a new service instance.
  11. * @classdesc Reflected service.
  12. * @extends NamespaceBase
  13. * @constructor
  14. * @param {string} name Service name
  15. * @param {Object.<string,*>} [options] Service options
  16. * @throws {TypeError} If arguments are invalid
  17. */
  18. function Service(name, options) {
  19. Namespace.call(this, name, options);
  20. /**
  21. * Service methods.
  22. * @type {Object.<string,Method>}
  23. */
  24. this.methods = {}; // toJSON, marker
  25. /**
  26. * Cached methods as an array.
  27. * @type {Method[]|null}
  28. * @private
  29. */
  30. this._methodsArray = null;
  31. }
  32. /**
  33. * Service descriptor.
  34. * @interface IService
  35. * @extends INamespace
  36. * @property {string} [edition] Edition
  37. * @property {Object.<string,IMethod>} methods Method descriptors
  38. * @property {string|null} [comment] Service comment
  39. */
  40. /**
  41. * Constructs a service from a service descriptor.
  42. * @param {string} name Service name
  43. * @param {IService} json Service descriptor
  44. * @param {number} [depth] Current nesting depth, defaults to `0`
  45. * @returns {Service} Created service
  46. * @throws {TypeError} If arguments are invalid
  47. */
  48. Service.fromJSON = function fromJSON(name, json, depth) {
  49. if (depth === undefined)
  50. depth = 0;
  51. if (depth > util.recursionLimit)
  52. throw Error("max depth exceeded");
  53. var service = new Service(name, json.options);
  54. /* istanbul ignore else */
  55. if (json.methods)
  56. for (var names = Object.keys(json.methods), i = 0; i < names.length; ++i)
  57. service.add(Method.fromJSON(names[i], json.methods[names[i]]));
  58. if (json.nested)
  59. service.addJSON(json.nested, depth);
  60. if (json.edition)
  61. service._edition = json.edition;
  62. service.comment = json.comment;
  63. service._defaultEdition = "proto3"; // For backwards-compatibility.
  64. return service;
  65. };
  66. /**
  67. * Converts this service to a service descriptor.
  68. * @param {IToJSONOptions} [toJSONOptions] JSON conversion options
  69. * @returns {IService} Service descriptor
  70. */
  71. Service.prototype.toJSON = function toJSON(toJSONOptions) {
  72. var inherited = Namespace.prototype.toJSON.call(this, toJSONOptions);
  73. var keepComments = toJSONOptions ? Boolean(toJSONOptions.keepComments) : false;
  74. return util.toObject([
  75. "edition" , this._editionToJSON(),
  76. "options" , inherited && inherited.options || undefined,
  77. "methods" , Namespace.arrayToJSON(this.methodsArray, toJSONOptions) || /* istanbul ignore next */ {},
  78. "nested" , inherited && inherited.nested || undefined,
  79. "comment" , keepComments ? this.comment : undefined
  80. ]);
  81. };
  82. /**
  83. * Methods of this service as an array for iteration.
  84. * @name Service#methodsArray
  85. * @type {Method[]}
  86. * @readonly
  87. */
  88. Object.defineProperty(Service.prototype, "methodsArray", {
  89. get: function() {
  90. return this._methodsArray || (this._methodsArray = util.toArray(this.methods));
  91. }
  92. });
  93. function clearCache(service) {
  94. service._methodsArray = null;
  95. return service;
  96. }
  97. /**
  98. * @override
  99. */
  100. Service.prototype.get = function get(name) {
  101. return Object.prototype.hasOwnProperty.call(this.methods, name)
  102. ? this.methods[name]
  103. : Namespace.prototype.get.call(this, name);
  104. };
  105. /**
  106. * @override
  107. */
  108. Service.prototype.resolveAll = function resolveAll() {
  109. if (!this._needsRecursiveResolve) return this;
  110. Namespace.prototype.resolve.call(this);
  111. var methods = this.methodsArray;
  112. for (var i = 0; i < methods.length; ++i)
  113. methods[i].resolve();
  114. return this;
  115. };
  116. /**
  117. * @override
  118. */
  119. Service.prototype._resolveFeaturesRecursive = function _resolveFeaturesRecursive(edition) {
  120. if (!this._needsRecursiveFeatureResolution) return this;
  121. edition = this._edition || edition;
  122. Namespace.prototype._resolveFeaturesRecursive.call(this, edition);
  123. this.methodsArray.forEach(method => {
  124. method._resolveFeaturesRecursive(edition);
  125. });
  126. return this;
  127. };
  128. /**
  129. * @override
  130. */
  131. Service.prototype.add = function add(object) {
  132. /* istanbul ignore if */
  133. if (this.get(object.name))
  134. throw Error("duplicate name '" + object.name + "' in " + this);
  135. if (object instanceof Method) {
  136. if (object.name === "__proto__")
  137. return this;
  138. this.methods[object.name] = object;
  139. object.parent = this;
  140. return clearCache(this);
  141. }
  142. return Namespace.prototype.add.call(this, object);
  143. };
  144. /**
  145. * @override
  146. */
  147. Service.prototype.remove = function remove(object) {
  148. if (object instanceof Method) {
  149. /* istanbul ignore if */
  150. if (this.methods[object.name] !== object)
  151. throw Error(object + " is not a member of " + this);
  152. delete this.methods[object.name];
  153. object.parent = null;
  154. return clearCache(this);
  155. }
  156. return Namespace.prototype.remove.call(this, object);
  157. };
  158. /**
  159. * Creates a runtime service using the specified rpc implementation.
  160. * @param {RPCImpl} rpcImpl RPC implementation
  161. * @param {boolean} [requestDelimited=false] Whether requests are length-delimited
  162. * @param {boolean} [responseDelimited=false] Whether responses are length-delimited
  163. * @returns {rpc.Service} RPC service. Useful where requests and/or responses are streamed.
  164. */
  165. Service.prototype.create = function create(rpcImpl, requestDelimited, responseDelimited) {
  166. var rpcService = new rpc.Service(rpcImpl, requestDelimited, responseDelimited);
  167. for (var i = 0, method; i < /* initializes */ this.methodsArray.length; ++i) {
  168. var methodName = util.lcFirst((method = this._methodsArray[i]).resolve().name).replace(/[^$\w_]/g, "");
  169. rpcService[methodName] = (function(method, requestType, responseType) {
  170. return function rpcMethod(request, callback) {
  171. return rpc.Service.prototype.rpcCall.call(this, method, requestType, responseType, request, callback);
  172. };
  173. })(method, method.resolvedRequestType.ctor, method.resolvedResponseType.ctor);
  174. }
  175. return rpcService;
  176. };