Service.js 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. if (!dojo._hasResource["dojox.wire.ml.Service"]) { // _hasResource checks added
  2. // by build. Do not use
  3. // _hasResource directly in
  4. // your code.
  5. dojo._hasResource["dojox.wire.ml.Service"] = true;
  6. dojo.provide("dojox.wire.ml.Service");
  7. dojo.provide("dojox.wire.ml.RestHandler");
  8. dojo.provide("dojox.wire.ml.XmlHandler");
  9. dojo.provide("dojox.wire.ml.JsonHandler");
  10. dojo.require("dijit._Widget");
  11. dojo.require("dojox.data.dom");
  12. dojo.require("dojox.wire._base");
  13. dojo.require("dojox.wire.ml.util");
  14. dojo.declare("dojox.wire.ml.Service", dijit._Widget, {
  15. // summary:
  16. // A widget for a service
  17. // description:
  18. // This widget represents a service defined by a service description
  19. // specified with 'url' attribute.
  20. // If 'serviceType' and 'serviceUrl' attributes are specified, 'url'
  21. // attribute can be omitted.
  22. // url:
  23. // A URL to a service description
  24. // serviceUrl:
  25. // A URL to a service
  26. // serviceType:
  27. // A service type
  28. // handlerClass:
  29. // A service handler class name
  30. url : "",
  31. serviceUrl : "",
  32. serviceType : "",
  33. handlerClass : "",
  34. preventCache : true,
  35. postCreate : function() {
  36. // summary:
  37. // Call _createHandler()
  38. // description:
  39. // See _createHandler().
  40. this.handler = this._createHandler();
  41. },
  42. _handlerClasses : {
  43. "TEXT" : "dojox.wire.ml.RestHandler",
  44. "XML" : "dojox.wire.ml.XmlHandler",
  45. "JSON" : "dojox.wire.ml.JsonHandler",
  46. "JSON-RPC" : "dojo.rpc.JsonService"
  47. },
  48. _createHandler : function() {
  49. // summary:
  50. // Create a service handler
  51. // desription:
  52. // A service handler class is determined by:
  53. // 1. 'handlerClass' attribute
  54. // 2. 'serviceType' attribute
  55. // 3. 'serviceType' property in a service description
  56. // returns:
  57. // A service handler
  58. if (this.url) {
  59. var self = this;
  60. var d = dojo.xhrGet({
  61. url : this.url,
  62. handleAs : "json",
  63. sync : true
  64. });
  65. d.addCallback(function(result) {
  66. self.smd = result;
  67. });
  68. if (this.smd && !this.serviceUrl) {
  69. this.serviceUrl = (this.smd.serviceUrl || this.smd.serviceURL);
  70. }
  71. }
  72. var handlerClass = undefined;
  73. if (this.handlerClass) {
  74. handlerClass = dojox.wire._getClass(this.handlerClass);
  75. } else if (this.serviceType) {
  76. handlerClass = this._handlerClasses[this.serviceType];
  77. if (handlerClass && dojo.isString(handlerClass)) {
  78. handlerClass = dojox.wire._getClass(handlerClass);
  79. this._handlerClasses[this.serviceType] = handlerClass;
  80. }
  81. } else if (this.smd && this.smd.serviceType) {
  82. handlerClass = this._handlerClasses[this.smd.serviceType];
  83. if (handlerClass && dojo.isString(handlerClass)) {
  84. handlerClass = dojox.wire._getClass(handlerClass);
  85. this._handlerClasses[this.smd.serviceType] = handlerClass;
  86. }
  87. }
  88. if (!handlerClass) {
  89. return null; // null
  90. }
  91. return new handlerClass(); // Object
  92. },
  93. callMethod : function(method, parameters) {
  94. // summary:
  95. // Call a service method with parameters
  96. // method:
  97. // A method name
  98. // parameters:
  99. // An array parameters
  100. var deferred = new dojo.Deferred();
  101. this.handler.bind(method, parameters, deferred, this.serviceUrl);
  102. return deferred;
  103. }
  104. });
  105. dojo.declare("dojox.wire.ml.RestHandler", null, {
  106. // summary:
  107. // A REST service handler
  108. // description:
  109. // This class serves as a base REST service.
  110. // Sub-classes may override _getContent() and _getResult() to
  111. // handle
  112. // specific content types.
  113. contentType : "text/plain",
  114. handleAs : "text",
  115. bind : function(method, parameters, deferred, url) {
  116. // summary:
  117. // Call a service method with parameters.
  118. // description:
  119. // A service is called with a URL generated by _getUrl() and
  120. // an HTTP method specified with 'method'.
  121. // For "POST" and "PUT", a content is generated by
  122. // _getContent().
  123. // When data is loaded, _getResult() is used to pass the
  124. // result to
  125. // Deferred.callback().
  126. // method:
  127. // A method name
  128. // parameters:
  129. // An array of parameters
  130. // deferred:
  131. // 'Deferred'
  132. // url:
  133. // A URL for the method
  134. method = method.toUpperCase();
  135. var self = this;
  136. var args = {
  137. url : this._getUrl(method, parameters, url),
  138. contentType : this.contentType,
  139. handleAs : this.handleAs,
  140. headers : this.headers,
  141. preventCache : this.preventCache
  142. };
  143. var d = null;
  144. if (method == "POST") {
  145. args.postData = this._getContent(method, parameters);
  146. d = dojo.rawXhrPost(args);
  147. } else if (method == "PUT") {
  148. args.putData = this._getContent(method, parameters);
  149. d = dojo.rawXhrPut(args);
  150. } else if (method == "DELETE") {
  151. d = dojo.xhrDelete(args);
  152. } else { // "GET"
  153. d = dojo.xhrGet(args);
  154. }
  155. d.addCallbacks(function(result) {
  156. deferred.callback(self._getResult(result));
  157. }, function(error) {
  158. deferred.errback(error);
  159. });
  160. },
  161. _getUrl : function(/* String */method, /* Array */parameters, /* String */
  162. url) {
  163. // summary:
  164. // Generate a URL
  165. // description:
  166. // If 'method' is "GET" or "DELETE", a query string is
  167. // generated
  168. // from a query object specified to the first parameter in
  169. // 'parameters' and appended to 'url'.
  170. // If 'url' contains variable seguments
  171. // ("{parameter_name}"),
  172. // they are replaced with corresponding parameter values,
  173. // instead.
  174. // method:
  175. // A method name
  176. // parameters:
  177. // An array of parameters
  178. // url:
  179. // A base URL
  180. // returns:
  181. // A URL
  182. if (method == "GET" || method == "DELETE") {
  183. var query = parameters[0];
  184. var queryString = "";
  185. for (var name in query) {
  186. var value = query[name];
  187. if (value) {
  188. value = encodeURIComponent(value);
  189. var variable = "{" + name + "}";
  190. var index = url.indexOf(variable);
  191. if (index >= 0) { // encode in path
  192. url = url.substring(0, index)
  193. + value
  194. + url.substring(index
  195. + variable.length);
  196. } else { // encode as query string
  197. if (queryString) {
  198. queryString += "&";
  199. }
  200. queryString += (name + "=" + value);
  201. }
  202. }
  203. }
  204. if (queryString) {
  205. url += "?" + queryString;
  206. }
  207. }
  208. return url; // String
  209. },
  210. _getContent : function(/* String */method, /* Array */parameters) {
  211. // summary:
  212. // Generate a request content
  213. // description:
  214. // If 'method' is "POST" or "PUT", the first parameter in
  215. // 'parameters' is returned.
  216. // method:
  217. // A method name
  218. // parameters:
  219. // An array of parameters
  220. // returns:
  221. // A request content
  222. if (method == "POST" || method == "PUT") {
  223. return (parameters ? parameters[0] : null); // anything
  224. } else {
  225. return null; // null
  226. }
  227. },
  228. _getResult : function(/* anything */data) {
  229. // summary:
  230. // Extract a result
  231. // description:
  232. // A response data is returned as is.
  233. // data:
  234. // A response data returned by a service
  235. // returns:
  236. // A result object
  237. return data; // anything
  238. }
  239. });
  240. dojo.declare("dojox.wire.ml.XmlHandler", dojox.wire.ml.RestHandler, {
  241. // summary:
  242. // A REST service handler for XML
  243. // description:
  244. // This class provides XML handling for a REST service.
  245. contentType : "text/xml",
  246. handleAs : "xml",
  247. _getContent : function(/* String */method, /* Array */parameters) {
  248. // description:
  249. // If 'method' is "POST" or "PUT", the first parameter in
  250. // 'parameters' is used to generate an XML content.
  251. // method:
  252. // A method name
  253. // parameters:
  254. // An array of parameters
  255. // returns:
  256. // A request content
  257. var content = null;
  258. if (method == "POST" || method == "PUT") {
  259. var p = parameters[0];
  260. if (p) {
  261. if (dojo.isString(p)) {
  262. content = p;
  263. } else {
  264. var element = p;
  265. if (element instanceof dojox.wire.ml.XmlElement) {
  266. element = element.element;
  267. } else if (element.nodeType === 9 /* DOCUMENT_NODE */) {
  268. element = element.documentElement;
  269. }
  270. var declaration = "<?xml version=\"1.0\"?>"; // TODO:
  271. // encoding?
  272. content = declaration
  273. + dojox.data.dom.innerXML(element);
  274. }
  275. }
  276. }
  277. return content;
  278. },
  279. _getResult : function(/* Document */data) {
  280. // summary:
  281. // Extract a result
  282. // description:
  283. // A response data (XML Document) is returned wrapped with
  284. // XmlElement.
  285. // data:
  286. // A response data returned by a service
  287. // returns:
  288. // A result object
  289. if (data) {
  290. data = new dojox.wire.ml.XmlElement(data);
  291. }
  292. return data;
  293. }
  294. });
  295. dojo.declare("dojox.wire.ml.JsonHandler", dojox.wire.ml.RestHandler, {
  296. // summary:
  297. // A REST service handler for JSON
  298. // description:
  299. // This class provides JSON handling for a REST service.
  300. contentType : "text/json",
  301. handleAs : "json",
  302. headers : {
  303. "Accept" : "*/json"
  304. },
  305. _getContent : function(/* String */method, /* Array */parameters) {
  306. // summary:
  307. // Generate a request content
  308. // description:
  309. // If 'method' is "POST" or "PUT", the first parameter in
  310. // 'parameter' is used to generate a JSON content.
  311. // method:
  312. // A method name
  313. // parameters:
  314. // An array of parameters
  315. // returns:
  316. // A request content
  317. var content = null;
  318. if (method == "POST" || method == "PUT") {
  319. var p = (parameters ? parameters[0] : undefined);
  320. if (p) {
  321. if (dojo.isString(p)) {
  322. content = p;
  323. } else {
  324. content = dojo.toJson(p);
  325. }
  326. }
  327. }
  328. return content; // String
  329. }
  330. });
  331. }