C_rsRestRequest.js 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. /*
  2. IBM Confidential
  3. OCO Source Materials
  4. IBM Cognos Products: rs
  5. (C) Copyright IBM Corp. 2018, 2019
  6. The source code for this program is not published or otherwise divested of its trade secrets, irrespective of what has been deposited with the U.S. Copyright Office.
  7. */
  8. define(['bi/authoring/utils/U_Object', 'bi/authoring/utils/rsPromptHandler'], function(U_Object, rsPromptHandler){
  9. /*
  10. C_RestRequest.prototype.F_GetStatusText = function()
  11. {
  12. // Firefox and Ie can throw an exception when accessing this property
  13. return this.m_oXHR ? U_JsUtils.F_GetPropertyInTryCatch( this.m_oXHR, "statusText" ) : null;
  14. };
  15. C_RestRequest.prototype.F_GetUrl = function()
  16. {
  17. return this.m_sUrl;
  18. };
  19. C_RestRequest.prototype.f_processTracking = function()
  20. {
  21. G_Debug.F_Print("C_RestRequest.f_processTracking");
  22. var v_sTracking = this.m_oXHR.getResponseHeader('busTracking');
  23. if (v_sTracking)
  24. {
  25. this.F_PushRequestTrackingForReuse(v_sTracking);
  26. }
  27. };
  28. C_RestRequest.prototype.F_PushRequestTrackingForReuse = function(v_sTracking)
  29. {
  30. };
  31. */
  32. function C_rsRestRequest( v_oGlassContext, v_oListener, v_oRequest )
  33. {
  34. this.m_oGlassContext = v_oGlassContext;
  35. this.m_oListener = v_oListener;
  36. this.m_oRequest = v_oRequest;
  37. this.m_oPromptCallbackResponse = null;
  38. this.M_iResponseDelay = 0;
  39. };
  40. function f_fireEvent( v_sEvent )
  41. {
  42. if (this.m_oListener && this.m_oListener[v_sEvent])
  43. {
  44. // fire events in a timeout because the glass ajax service will catch and discard any errors that occur, doing in a timeout avoids their catch
  45. setTimeout( this.m_oListener[v_sEvent].bind( this.m_oListener, this ), 0 );
  46. }
  47. };
  48. function f_isSuccessStatus()
  49. {
  50. var v_iStatus = this.F_GetStatus();
  51. return v_iStatus >= 200 && v_iStatus < 300;
  52. };
  53. function f_onRestResponseDontCare()
  54. {
  55. // Intentionally empty since there is nothing to be done.
  56. };
  57. var f_processAsyncResponse;
  58. function f_doResponseProcessing()
  59. {
  60. if (this.F_GetStatus() == 202)
  61. {
  62. f_processAsyncResponse.bind(this)();
  63. }
  64. else
  65. {
  66. if (this.m_bAborted)
  67. {
  68. return;
  69. }
  70. //this.f_processTracking(); NOT SUPPORTED
  71. this.F_ProcessResponse();
  72. f_fireEvent.bind(this)("F_Request_OnComplete"); //TODO use promise?
  73. }
  74. };
  75. function f_initiateResponseProcessing()
  76. {
  77. if (this.M_iResponseDelay)
  78. {
  79. setTimeout(f_doResponseProcessing.bind(this), this.M_iResponseDelay);
  80. return;
  81. }
  82. f_doResponseProcessing.bind(this)();
  83. };
  84. function f_onRestResponseOK(v_oResponseData, v_sStatus, v_oXHR )
  85. {
  86. this.m_oResponseData = v_oResponseData;
  87. this.m_oXHR = v_oXHR;
  88. f_initiateResponseProcessing.bind(this)();
  89. };
  90. function f_onRestResponseFailed(v_sStatus, v_oXHR, v_sErrorThrown)
  91. {
  92. this.m_oXHR = v_oXHR;
  93. this.m_oFailed = { status: v_sStatus, error: v_sErrorThrown, response: this.F_GetResponseText() };
  94. this.F_OnFailed();
  95. f_initiateResponseProcessing.bind(this)();
  96. };
  97. function f_processAsyncResponse()
  98. {
  99. // Determine if prompting
  100. var v_bPrompting = this.m_oResponseData && this.m_oResponseData.status == 'prompting';
  101. var v_sLocation = this.m_oXHR.getResponseHeader('Location');
  102. var v_sAffinity = this.m_oXHR.getResponseHeader('X-CA-Affinity');
  103. var v_oRequestHeaders = {};
  104. if (v_sAffinity)
  105. {
  106. // This ensures request is routed to the right report_service instance.
  107. v_oRequestHeaders['X-CA-Affinity'] = v_sAffinity;
  108. }
  109. var v_oRequest = {
  110. url : v_sLocation,
  111. headers : v_oRequestHeaders
  112. };
  113. if (this.m_bAborted)
  114. {
  115. v_oRequest.type = 'DELETE';
  116. Application.GlassContext.services.ajax.ajax(v_oRequest)
  117. .done(f_onRestResponseDontCare.bind(this))
  118. .fail(f_onRestResponseDontCare.bind(this));
  119. }
  120. else
  121. {
  122. v_oRequest.type = 'GET';
  123. if (v_bPrompting)
  124. {
  125. // By default, jquery will convert the response based on the content-type. In this case that means
  126. // parsing the SOAP response into a document (content-type: text/xml). However, the resulting document
  127. // is not compatible with the documents used by RS. Therefore, we tell jquery to leave
  128. // the XML response as plain text and we will handle the parsing ourselves.
  129. v_oRequest.dataType = "text";
  130. if (!rsPromptHandler.F_DoRestPrompting(this, v_oRequest, this.m_oGlassContext))
  131. {
  132. this.m_oFailed = { status: 'popup blocked' }; //F_SetNewErrorRes( "IDS_CCHL_REQUEST_CANCELLED_PROMPTING" );
  133. this.F_ProcessResponse();
  134. f_fireEvent.bind(this)("F_Request_OnComplete");
  135. }
  136. }
  137. else
  138. {
  139. this.m_oGlassContext.services.ajax.ajax(v_oRequest)
  140. .done(f_onRestResponseOK.bind(this))
  141. .fail(f_onRestResponseFailed.bind(this));
  142. }
  143. }
  144. };
  145. function f_getPropertyInTryCatch( o, p )
  146. {
  147. try
  148. {
  149. return o[p];
  150. }
  151. catch ( e )
  152. {
  153. return null;
  154. }
  155. };
  156. /////////////////////////////
  157. C_rsRestRequest.prototype.F_GetListener = function()
  158. {
  159. //TODO use promise?
  160. return this.m_oListener;
  161. };
  162. C_rsRestRequest.prototype.F_SetListener = function(v_oListener)
  163. {
  164. //TODO use promise?
  165. this.m_oListener = v_oListener;
  166. };
  167. C_rsRestRequest.prototype.F_SetHeaders = function( v_oRequestHeaders )
  168. {
  169. // Override as required
  170. return v_oRequestHeaders;
  171. };
  172. C_rsRestRequest.prototype.F_Send = function()
  173. {
  174. this.m_oRequest.headers = this.F_SetHeaders( this.m_oRequest.headers );
  175. this.m_oGlassContext.services.ajax.ajax(this.m_oRequest)
  176. .done(f_onRestResponseOK.bind(this))
  177. .fail(f_onRestResponseFailed.bind(this));
  178. };
  179. C_rsRestRequest.prototype.F_Abort = function()
  180. {
  181. // glass ajax requests are not cancellable, so the best we can do is to stop listening
  182. this.m_bAborted = true;
  183. f_fireEvent.bind(this)("F_Request_OnAborted"); //TODO use promise?
  184. this.F_SetListener(null);
  185. };
  186. C_rsRestRequest.prototype.F_GetStatus = function()
  187. {
  188. // Firefox and IE can throw an exception when accessing this property
  189. return this.m_oXHR ? f_getPropertyInTryCatch( this.m_oXHR, "status" ) : null;
  190. };
  191. C_rsRestRequest.prototype.F_ProcessResponse = function()
  192. {
  193. // Intentionally empty since there is nothing to be done.
  194. // Classes extending this class are expected to override this method.
  195. };
  196. C_rsRestRequest.prototype.F_GetResponseData = function()
  197. {
  198. return this.m_oResponseData;
  199. };
  200. C_rsRestRequest.prototype.F_GetResponseText = function()
  201. {
  202. return this.m_oXHR ? this.m_oXHR.responseText : null;
  203. };
  204. C_rsRestRequest.prototype.F_OnFailed = function()
  205. {
  206. // Override as required
  207. };
  208. C_rsRestRequest.prototype.F_GetFailed = function()
  209. {
  210. return this.m_oFailed;
  211. };
  212. C_rsRestRequest.prototype.F_SetPromptCallbackResponse = function( v_oResponse, v_oAttachments )
  213. {
  214. // v_oResponse is an object created by a child window but this code is running
  215. // in the context of the parent window. We need to clone v_oResponse because
  216. // when the child goes out of scope, v_oResponse may disappear (in IE 11 it does).
  217. this.m_oPromptCallbackResponse = v_oResponse ? U_Object.F_Clone(v_oResponse) : null;
  218. };
  219. C_rsRestRequest.prototype.F_OnServerPromptingComplete = function()
  220. {
  221. if (this.m_oPromptCallbackResponse)
  222. {
  223. this.m_oResponseData = this.m_oPromptCallbackResponse;
  224. this.m_oPromptCallbackResponse = null;
  225. this.m_oFailed = null; //this.F_SetError(null);
  226. this.F_ProcessResponse();
  227. }
  228. else
  229. {
  230. this.m_oFailed = { status: 'cancelled' }; //F_SetNewErrorRes( "IDS_CCHL_REQUEST_CANCELLED_PROMPTING" );
  231. }
  232. f_fireEvent.bind(this)("F_Request_OnComplete");
  233. };
  234. return C_rsRestRequest;
  235. });