util.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. // Licensed Materials - Property of IBM
  2. //
  3. // IBM Cognos Products: ps
  4. //
  5. // (C) Copyright IBM Corp. 2013
  6. //
  7. // US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  8. dojo.provide('ps.util');
  9. (function() {
  10. if (typeof ps == "undefined") {
  11. this.ps = {};
  12. }
  13. ps._checkStartsWith = function(text, value) {
  14. return value == text.substr(0, value.length);
  15. };
  16. ps._checkContains = function(text, value) {
  17. return -1 != text.indexOf(value);
  18. };
  19. ps._isEmpty = function(text) {
  20. return (!text || dojo.trim(text).length === 0);
  21. };
  22. ps.setGateway = function(gateway) {
  23. ps._gateway = gateway;
  24. };
  25. ps.setWebcontent = function(webcontent) {
  26. ps._webcontent = webcontent;
  27. };
  28. ps.xhrGet = function(/*dojo.__XhrArgs*/args) {
  29. return ps._setupDeferred('GET', dojo.xhrGet(args));
  30. };
  31. /*
  32. logon handler
  33. */
  34. ps.getLogonHandler = function() {
  35. return function(error, ioArgs) {
  36. var dfd = new dojo.Deferred();
  37. //open logon iframe
  38. if (!ps._logonDialog) {
  39. ps._logonDialog = new ps.LogonDialog({
  40. okHandler: function() {
  41. ps._logonDialog = null;
  42. dfd.callback(true);
  43. },
  44. cancelHandler: function() {
  45. ps._logonDialog = null;
  46. dfd.errback(error);
  47. }
  48. });
  49. }
  50. ps._logonDialog.startup();
  51. ps._logonDialog.show();
  52. // after a successful logon, re-invoke original request and return its new deferred object
  53. dfd.addCallback(dojo.hitch(this, function(result) {
  54. var newdfd;
  55. if (dojo.isIE) {
  56. newdfd = dojo.xhr(this._method, this, ("postData" in this) || ("putData" in this));
  57. } else {
  58. newdfd = ps.xhrGet(this);
  59. }
  60. return newdfd;
  61. }));
  62. return dfd; // dojo.Deferred
  63. };
  64. };
  65. ps._errorTypeHandlers = [];
  66. ps.registerErrorTypeHandler = function(type, fn) {
  67. ps._errorTypeHandlers[type] = fn;
  68. };
  69. /**
  70. * @param {Object} method
  71. * @param {Object} dfd
  72. * @return {dojo.Deferred}
  73. */
  74. ps._setupDeferred = function(method, dfd) {
  75. // keep a copy of the method for later use
  76. dfd.ioArgs.args._method = method;
  77. // setup error handling with the error type handlers
  78. dfd.addErrback(dojo.hitch(dfd, function(error) {
  79. error = ps.parseError(error, this.ioArgs);
  80. if (typeof ps._errorTypeHandlers[error.code] === 'function') {
  81. ps._errorTypeHandlers[error.code].call(dfd.ioArgs.args, error, dfd.ioArgs);
  82. return null; // prevent original error from being displayed, it's already handled here.
  83. }
  84. // the error is forwarded to the next deferrer in the chain
  85. return error;
  86. }));
  87. return dfd; // dojo.Deferred
  88. };
  89. /**
  90. * Parse the error object. If error.responseText is present and looks like an error
  91. * object in JSON, XML or HTML formats, parse it. If ioArgs was provided, grab its status and responseText.
  92. * The Error object has these members: "message", "status", "responseText" & "stack".
  93. * The "code" and "details" members can be available too.
  94. * @param {Error} error
  95. * @param {Object} ioArgs (optional)
  96. * @return {Error}
  97. */
  98. ps.parseError = function(error, ioArgs) {
  99. if (!error.code) {
  100. if (!error.responseText && ioArgs && ioArgs.xhr) {
  101. if (!error.status) {
  102. error.status = ioArgs.xhr.status;
  103. }
  104. if (!error.responseText) {
  105. error.responseText = ioArgs.xhr.responseText;
  106. }
  107. error.code = 'http_' + error.status;
  108. error.message = dojo.string.substitute(PSMSG.ERR.IDS_EDG_HTTP_ERROR, [error.status]);
  109. }
  110. var text = dojo.string.trim(error.responseText || '');
  111. for (var i = 0, len = ps._errorTranslators.length; i < len; i++) {
  112. var trans = ps._errorTranslators[i];
  113. if (trans.check(text, trans.text)) {
  114. var err_fixed = trans.convert(text);
  115. if (err_fixed) {
  116. error = dojo.mixin(new Error(), error, err_fixed);
  117. }
  118. break;
  119. }
  120. }
  121. }
  122. return error;
  123. };
  124. /**
  125. * When an error is reported, these handlers have a chance to mangle the
  126. * error object to something else.
  127. */
  128. ps._errorTranslators = [
  129. {
  130. check: ps._checkStartsWith,
  131. text: '{"error":',
  132. convert: function(text) {
  133. // looks like json
  134. var obj = dojo.fromJson(text);
  135. return (obj.error) ? obj.error : null;
  136. }
  137. },
  138. {
  139. check: ps._checkContains,
  140. text: '<ERROR_CODE>SERVER_NOT_AVAILABLE</ERROR_CODE>',
  141. convert: function(text) {
  142. // this is an html markup response
  143. return {
  144. status: 500,
  145. code: 'serverNotAvailable',
  146. message: PSMSG.ERR.IDS_EDG_ERROR_SERVER_NOT_AVAILABLE
  147. };
  148. }
  149. },
  150. {
  151. check: ps._checkContains,
  152. text: '<ERROR_CODE>CAM_PASSPORT_ERROR</ERROR_CODE>',
  153. convert: function(text) {
  154. // this is an html markup response
  155. return {
  156. status: 403,
  157. code: 'camAuthUserRecoverable',
  158. message: dojo.string.substitute(PSMSG.ERR.IDS_EDG_HTTP_ERROR, [403])
  159. };
  160. }
  161. },
  162. {
  163. check: ps._checkContains,
  164. text: 'metricsManagerService',
  165. convert: function(text) {
  166. // this is an html markup response
  167. return {
  168. status: 500,
  169. code: 'CMMServiceNotAvailable',
  170. message: PSMSG.ERR.IDS_EDG_ERROR_CMM_SERVER_NOT_AVAILABLE
  171. };
  172. }
  173. },
  174. { //No error response returned
  175. check: ps._isEmpty,
  176. convert: function(text) {
  177. return {
  178. status:0,
  179. code: 'noResponseReturned',
  180. message: PSMSG.ERR.IDS_NAV_ERROR_SERVER_NOT_AVAILABLE
  181. };
  182. }
  183. }
  184. ];
  185. /**
  186. * Register an error translator. Any function can be use to scan the error text,
  187. * however two functions are available: ps._checkStartsWith and ps._checkContains.
  188. * The function signature of the error translator function is:
  189. * <code>
  190. * func(text) {
  191. * // use text to figure the proper error
  192. * var obj = {status: 500, code: "errorcode": message: "some message"};
  193. * return obj;
  194. * }
  195. * </code>
  196. * @param {String} checkFunc
  197. * @param {String} text
  198. * @param {Object} func
  199. */
  200. ps.registerErrorTranslator = function(checkFunc, text, convert) {
  201. ps._errorTranslators.push({
  202. check: checkFunc,
  203. text: text,
  204. convert: convert
  205. });
  206. };
  207. })();