BaseRequestHandler.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551
  1. /*
  2. *+------------------------------------------------------------------------+
  3. *| Licensed Materials - Property of IBM
  4. *| IBM Cognos Products: Viewer
  5. *| (C) Copyright IBM Corp. 2014, 2020
  6. *|
  7. *| US Government Users Restricted Rights - Use, duplication or
  8. *| disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  9. *|
  10. *+------------------------------------------------------------------------+
  11. */
  12. function BaseRequestHandler( oCV ) {
  13. if (oCV) {
  14. this.m_oCV = oCV;
  15. this.m_workingDialog = null;
  16. this.m_requestIndicator = null;
  17. this.m_faultDialog = null;
  18. this.m_logOnDialog = null;
  19. this.m_promptDialog = null;
  20. this.m_httpRequestConfig = this.m_oCV.getConfig() && this.m_oCV.getConfig().getHttpRequestConfig() ? this.m_oCV.getConfig().getHttpRequestConfig() : null;
  21. }
  22. }
  23. BaseRequestHandler.prototype = new IRequestHandler();
  24. BaseRequestHandler.prototype.onError = function(response) {};
  25. BaseRequestHandler.prototype.onComplete = function() {};
  26. BaseRequestHandler.prototype.onPrompting = function() {};
  27. BaseRequestHandler.prototype.resubmitInSafeMode = function() {};
  28. BaseRequestHandler.prototype.massageHtmlBeforeDisplayed = function() {};
  29. BaseRequestHandler.prototype.onPostEntryComplete = function() {
  30. this._processDelayedLoadingQueue();
  31. };
  32. BaseRequestHandler.prototype.getViewer = function() {
  33. return this.m_oCV;
  34. };
  35. BaseRequestHandler.prototype.setDispatcherEntry = function(dispatcherEntry) {
  36. this.m_oDispatcherEntry = dispatcherEntry;
  37. };
  38. BaseRequestHandler.prototype.getDispatcherEntry = function() {
  39. return this.m_oDispatcherEntry;
  40. };
  41. /**
  42. * Should only be called once when the Viewer first loads. This is because
  43. * the initial response from the server didn't go through the dispatcher entries,
  44. * so we need logic to handle complete, working, fault, ...
  45. */
  46. BaseRequestHandler.prototype.processInitialResponse = function(oState) {
  47. this.updateViewerState(oState);
  48. };
  49. BaseRequestHandler.prototype.setLogOnDialog = function(logOnDialog) {
  50. if (logOnDialog == null) {
  51. this.m_logOnDialog = null;
  52. } else if(logOnDialog instanceof ILogOnDialog) {
  53. this.m_logOnDialog = logOnDialog;
  54. } else if(logOnDialog && typeof console != "undefined") {
  55. console.log("The parameter logOnDialog must be an instance of ILogOnDialog");
  56. }
  57. };
  58. BaseRequestHandler.prototype.setWorkingDialog = function(workingDialog) {
  59. if (workingDialog == null) {
  60. this.m_workingDialog = null;
  61. }
  62. else if (this.m_httpRequestConfig && this.m_httpRequestConfig.getWorkingDialog()) {
  63. this.m_workingDialog = this.m_httpRequestConfig.getWorkingDialog();
  64. }
  65. else if(workingDialog instanceof IRequestIndicator) {
  66. this.m_workingDialog = workingDialog;
  67. }
  68. else if(workingDialog && typeof console != "undefined") {
  69. console.log("The parameter workingDialog must be an instance of IRequestIndicator");
  70. }
  71. };
  72. BaseRequestHandler.prototype.getWorkingDialog = function() {
  73. return this.m_workingDialog;
  74. };
  75. BaseRequestHandler.prototype.setRequestIndicator = function(requestIndicator) {
  76. if (requestIndicator == null) {
  77. this.m_requestIndicator = null;
  78. }
  79. else if (this.m_httpRequestConfig && this.m_httpRequestConfig.getRequestIndicator()) {
  80. this.m_requestIndicator = this.m_httpRequestConfig.getRequestIndicator();
  81. }
  82. else if(requestIndicator instanceof IRequestIndicator) {
  83. this.m_requestIndicator = requestIndicator;
  84. }
  85. else if(requestIndicator && typeof console != "undefined") {
  86. console.log("The parameter requestIndicator must be an instance of IRequestIndicator");
  87. }
  88. };
  89. BaseRequestHandler.prototype.getRequestIndicator = function() {
  90. return this.m_requestIndicator;
  91. };
  92. BaseRequestHandler.prototype.setFaultDialog = function(faultDialog) {
  93. if (faultDialog == null) {
  94. this.m_faultDialog = null;
  95. } else if(faultDialog instanceof IFaultDialog) {
  96. this.m_faultDialog = faultDialog;
  97. } else if(faultDialog && typeof console != "undefined") {
  98. console.log("The parameter faultDialog must be an instance of IFaultDialog");
  99. }
  100. };
  101. BaseRequestHandler.prototype.setPromptDialog = function(promptDialog) {
  102. if (promptDialog == null) {
  103. this.m_promptDialog = null;
  104. } else if(promptDialog instanceof IPromptDialog) {
  105. this.m_promptDialog = promptDialog;
  106. } else if(promptDialog && typeof console != "undefined") {
  107. console.log("The parameter promptDialog must be an instance of IPromptDialog");
  108. }
  109. };
  110. BaseRequestHandler.prototype.preHttpRequest = function(request) {
  111. if (request && typeof request.getFormField == "function") {
  112. if (request.getFormField("ui.action") != "wait" && request.getFormField("rapWait") != "true") {
  113. if (this.m_requestIndicator) {
  114. this.m_requestIndicator.show();
  115. }
  116. }
  117. }
  118. };
  119. BaseRequestHandler.prototype.postHttpRequest = function(response) {
  120. if (response && typeof response.getAsynchStatus == "function") {
  121. var status = response.getAsynchStatus();
  122. if (status != "working" && status != "stillWorking") {
  123. if (this.m_workingDialog) {
  124. this.m_workingDialog.hide();
  125. }
  126. if (this.m_requestIndicator) {
  127. this.m_requestIndicator.hide();
  128. }
  129. }
  130. }
  131. else {
  132. if (this.m_workingDialog) {
  133. this.m_workingDialog.hide();
  134. }
  135. if (this.m_requestIndicator) {
  136. this.m_requestIndicator.hide();
  137. }
  138. }
  139. };
  140. BaseRequestHandler.prototype.onFault = function(response) {
  141. var oCV = this.getViewer();
  142. if (this.m_workingDialog) {
  143. this.m_workingDialog.hide();
  144. }
  145. if (this.m_requestIndicator) {
  146. this.m_requestIndicator.hide();
  147. }
  148. if (typeof FaultDialog == "undefined") {
  149. if(typeof console != "undefined") {
  150. console.log("An unhandled fault was returned: %o", response);
  151. }
  152. return;
  153. }
  154. if (!this.m_faultDialog) {
  155. this.m_faultDialog = new FaultDialog(this.getViewer());
  156. }
  157. // onFault was called with an text/html response, we have no idea what this response is
  158. if (response && response.getResponseHeader && response.getResponseHeader("Content-type").indexOf("text/html") != -1) {
  159. this.m_faultDialog.handleUnknownHTMLResponse(response.getResponseText());
  160. }
  161. else if (response && response.getSoapFault) {
  162. this.m_faultDialog.show(response.getSoapFault());
  163. }
  164. else if (oCV.getSoapFault()) {
  165. // if the fault happened right away then it'll be stored in the Viewer object
  166. var soapFault = XMLBuilderLoadXMLFromString(oCV.getSoapFault());
  167. this.m_faultDialog.show(soapFault);
  168. oCV.setSoapFault("");
  169. }
  170. else if(typeof console != "undefined") {
  171. console.log("An unhandled fault was returned: %o", response);
  172. }
  173. };
  174. BaseRequestHandler.prototype.isAuthenticationFault = function(response) {
  175. var oCV = this.getViewer();
  176. var soapFaultDocument = null;
  177. if (response && response.getSoapFault) {
  178. soapFaultDocument = response.getSoapFault();
  179. }
  180. else if (oCV.getSoapFault()) {
  181. // if the fault happened right away then it'll be stored in the Viewer object
  182. soapFaultDocument = XMLBuilderLoadXMLFromString(oCV.getSoapFault());
  183. }
  184. if(soapFaultDocument != null) {
  185. var camElement = XMLHelper_FindChildByTagName(soapFaultDocument, "CAM", true);
  186. return (camElement != null && XMLHelper_FindChildByTagName(camElement, "promptInfo", true) != null);
  187. }
  188. return false;
  189. };
  190. BaseRequestHandler.prototype.onPassportTimeout = function(response) {
  191. var oCV = this.getViewer();
  192. if (this.m_workingDialog) {
  193. this.m_workingDialog.hide();
  194. }
  195. if (this.m_requestIndicator) {
  196. this.m_requestIndicator.hide();
  197. }
  198. if (!this.m_logOnDialog) {
  199. this.m_logOnDialog = new LogOnDialog(this.getViewer());
  200. }
  201. if (response && response.getResponseHeader && response.getResponseHeader("Content-type").indexOf("text/html") != -1) {
  202. var responseText = "";
  203. if (response.getResponseText) {
  204. responseText = response.getResponseText();
  205. }
  206. if ((responseText.indexOf("http-equiv=\"refresh\"") != -1) || (responseText.indexOf("http-equiv='refresh'") != -1)) {
  207. this.m_logOnDialog.show(null);
  208. }
  209. else {
  210. this.m_logOnDialog.handleUnknownHTMLResponse(responseText);
  211. }
  212. }
  213. else if (response && response.getSoapFault) {
  214. this.m_logOnDialog.show(response.getSoapFault());
  215. }
  216. else if (oCV.getSoapFault()) {
  217. // if the fault happened right away then it'll be stored in the Viewer object
  218. var soapFault = XMLBuilderLoadXMLFromString(oCV.getSoapFault());
  219. this.m_logOnDialog.show(soapFault);
  220. oCV.setSoapFault("");
  221. }
  222. else if(typeof console != "undefined") {
  223. console.log("BaseRequestHandler.prototype.onPassportTimeout: An unhandled authentication fault was returned: %o", response);
  224. }
  225. };
  226. BaseRequestHandler.prototype.onWorking = function(response) {
  227. if (this.m_workingDialog) {
  228. var stillWorking = response && typeof response.getAsynchStatus == "function" && response.getAsynchStatus() == "stillWorking" ? true : false;
  229. if (!stillWorking) {
  230. if (this.m_requestIndicator) {
  231. this.m_requestIndicator.hide();
  232. }
  233. this.m_workingDialog.show();
  234. }
  235. }
  236. };
  237. BaseRequestHandler.prototype.onCancel = function() {
  238. if (this.m_workingDialog) {
  239. this.m_workingDialog.hide();
  240. }
  241. if (this.m_requestIndicator) {
  242. this.m_requestIndicator.hide();
  243. }
  244. var oCV = this.getViewer();
  245. // Clear the prompt submitted flag since we've cancelled the request
  246. oCV.gbPromptRequestSubmitted = false;
  247. this._processDelayedLoadingQueue();
  248. };
  249. BaseRequestHandler.prototype._processDelayedLoadingQueue = function() {
  250. var oCV = this.getViewer();
  251. if (oCV && oCV.getViewerWidget()) {
  252. var cvWidget = oCV.getViewerWidget();
  253. if (cvWidget.getLoadManager()) {
  254. cvWidget.getLoadManager().processQueue();
  255. }
  256. }
  257. };
  258. BaseRequestHandler.prototype.onPrompting = function(response) {
  259. var oCV = this.getViewer();
  260. if (this.m_workingDialog) {
  261. this.m_workingDialog.hide();
  262. }
  263. if (this.m_requestIndicator) {
  264. this.m_requestIndicator.hide();
  265. }
  266. if (!this.m_promptDialog) {
  267. this.m_promptDialog = new PromptDialog(this.getViewer());
  268. }
  269. window["AsynchRequestObject"] = response;
  270. window["AsynchRequestPromptDialog"] = this.m_promptDialog;
  271. var cvIdParam = "?cv.id=" + oCV.getId();
  272. window["AsynchRequestPromptDialog"].initialize(oCV.getWebContentRoot() + "/rv/showStandalonePrompts.html" + cvIdParam, 400, 400);
  273. window["AsynchRequestPromptDialog"].show();
  274. };
  275. BaseRequestHandler.prototype.processDATAReportResponse = function(response) {
  276. var oCV = this.getViewer();
  277. if (!oCV || oCV.m_destroyed) {
  278. if (console) {
  279. console.warn("Tried to process a data response on an invalid CCognosViewer", oCV);
  280. }
  281. return;
  282. }
  283. var responseState = response.getResponseState();
  284. if (!responseState) {
  285. this.resubmitInSafeMode();
  286. }
  287. if (this.loadReportHTML(response.getResult()) === false) {
  288. this.resubmitInSafeMode();
  289. }
  290. this.updateViewerState(responseState);
  291. };
  292. BaseRequestHandler.prototype.updateViewerState = function(oState) {
  293. var oCV = this.getViewer();
  294. applyJSONProperties(oCV, oState);
  295. var status = oCV.getStatus();
  296. if(typeof oCV.envParams["ui.spec"] != "undefined" && oCV.envParams["ui.spec"].indexOf("<") === 0) {
  297. oCV.envParams["ui.spec"] = xml_decode(oCV.envParams["ui.spec"]);
  298. }
  299. if(status != "fault") {
  300. if(oCV.envParams["rapReportInfo"]) {
  301. this._processRapReportInfo(oCV);
  302. }
  303. if(typeof oState.clientunencodedexecutionparameters != "undefined") {
  304. var formWarpRequest = document.getElementById("formWarpRequest" + oCV.getId());
  305. if(formWarpRequest != null && typeof formWarpRequest["clientunencodedexecutionparameters"] != "undefined") {
  306. formWarpRequest["clientunencodedexecutionparameters"].value = oState.clientunencodedexecutionparameters;
  307. }
  308. if(typeof document.forms["formWarpRequest"] != "undefined" && typeof document.forms["formWarpRequest"]["clientunencodedexecutionparameters"] != "undefined") {
  309. document.forms["formWarpRequest"]["clientunencodedexecutionparameters"].value = oState.clientunencodedexecutionparameters;
  310. }
  311. }
  312. }
  313. else {
  314. // clear the tracking, so we don't attempt to re-use it on subsequent requests
  315. oCV.setTracking("");
  316. }
  317. };
  318. BaseRequestHandler.prototype._processRapReportInfo = function(oCV) {
  319. if(oCV.envParams["rapReportInfo"]) {
  320. var oReportInfo = eval("(" + oCV.envParams["rapReportInfo"] + ")");
  321. if (typeof RAPReportInfo != "undefined") {
  322. var rapReportInfo = new RAPReportInfo(oReportInfo, oCV);
  323. oCV.setRAPReportInfo(rapReportInfo);
  324. }
  325. }
  326. };
  327. BaseRequestHandler.prototype.loadReportHTML = function(sResponseText) {
  328. if (!sResponseText) {
  329. // There is no response to load.
  330. // Leave current view as is.
  331. return true;
  332. }
  333. var oCV = this.getViewer();
  334. if (window.IBM&&window.IBM.perf){window.IBM.perf.log("viewer_gotHtml", oCV);}
  335. if(oCV.m_undoStack.length > 0) {
  336. oCV.m_undoStack[oCV.m_undoStack.length-1].m_bRefreshPage = true;
  337. }
  338. oCV.pageNavigationObserverArray = [];
  339. oCV.m_flashChartsObjectIds = [];
  340. // IE bug: innerHTML do not handle <form>s, the page will be ignored if there is a <form> tag around the HTML code.
  341. // The main form (formWarpRequest) is wrapped around the <div> we are using for the report, we should not have a <form> in the output anyway.
  342. var sHTML = sResponseText.replace(/<form[^>]*>/gi,"").replace(/<\/form[^>]*>/gi,"");
  343. oCV.m_sHTML = sHTML;
  344. oCV.setHasPrompts(false);
  345. var id = oCV.getId();
  346. var oRVContent = document.getElementById("RVContent" + id);
  347. var oReportDiv = document.getElementById("CVReport" + id);
  348. if (window.gScriptLoader) {
  349. var bUseNamespacedGRS = oCV.getViewerWidget() ? true : false;
  350. var oCVDiv = oCV.getViewerWidget() ? document.getElementById("_" + oCV.getViewerWidget().iContext.widgetId + "_cv") : oReportDiv;
  351. sHTML = window.gScriptLoader.loadCSS(sHTML, oCVDiv, bUseNamespacedGRS, id);
  352. }
  353. if (oCV.sBrowser == 'ie') {
  354. // IE specific 'fix' where if sHTML has script tags at the beginning they won't be loaded into the DOM. Adding
  355. // a valid tag first causes all subsequent scripts to be loaded into the DOM.
  356. sHTML = "<span style='display:none'>&nbsp;</span>" + sHTML;
  357. }
  358. oReportDiv.innerHTML=sHTML;
  359. this.massageHtmlBeforeDisplayed();
  360. if (window.gScriptLoader) {
  361. var callback = GUtil.generateCallback(oCV.showLoadedContent, [oRVContent], oCV);
  362. oCV.m_resizeReady = false;
  363. if (!window.gScriptLoader.loadAll(oReportDiv, callback, id, true) ) {
  364. if (window.gScriptLoader.containsAjaxWarnings()) {
  365. return false;
  366. }
  367. }
  368. }
  369. else {
  370. oRVContent.style.display = "block";
  371. }
  372. // Set focus on reprompt button
  373. var frm_elements = document.querySelectorAll("button");
  374. var kCount = frm_elements.length;
  375. for (var k=0; k<kCount; k++)
  376. {
  377. var v_oElement = frm_elements[k];
  378. var id = v_oElement.id;
  379. var reprompt_id = id.match(/reprompt/);
  380. if (reprompt_id) {
  381. // comparing layoutName of button to set focus
  382. // layoutName = 0: ""reprompt1_NS_""
  383. var sOuter = v_oElement.outerHTML;
  384. var layoutstr = sOuter.match(/layoutname="\w+"/ );
  385. if (layoutstr !== null) {
  386. var layoutString = layoutstr[0];
  387. var Regexp = /".*"/;
  388. var layoutName = Regexp.exec(layoutString);
  389. if (oCV.getCurrentPromptControlFocus() == layoutName) {
  390. v_oElement.focus();
  391. oCV.setCurrentPromptControlFocus(null);
  392. v_oElement = null;
  393. }
  394. }
  395. else {
  396. oCV.setCurrentPromptControlFocus(null);
  397. v_oElement = null;
  398. }
  399. }
  400. }
  401. oCV.updateOutputForA11ySupport();
  402. this._clearFindState();
  403. return true;
  404. };
  405. BaseRequestHandler.prototype._clearFindState = function() {
  406. var oCV = this.getViewer();
  407. var findState = oCV.getState() && oCV.getState().getFindState() ? oCV.getState().getFindState() : null;
  408. if (findState && !findState.findOnServerInProgress()) {
  409. oCV.getState().clearFindState();
  410. }
  411. };
  412. /**
  413. * Make sure the report div is visible
  414. */
  415. BaseRequestHandler.prototype.showReport = function() {
  416. var oCV = this.getViewer();
  417. var oReportDiv = document.getElementById("CVReport" + oCV.getId());
  418. if (oReportDiv) {
  419. oReportDiv.style.display = "";
  420. }
  421. };
  422. /**
  423. * Called once the Viewer state and HTML report have been updated.
  424. * This is last set of 'tweaks' needed to show the UI
  425. */
  426. BaseRequestHandler.prototype.postComplete = function() {
  427. var oCV = this.getViewer();
  428. if (oCV.shouldWriteNavLinks()) {
  429. oCV.writeNavLinks(oCV.getSecondaryRequests().join(" "));
  430. }
  431. if (oCV.getStatus() === "complete") {
  432. oCV.m_undoStack = [new CognosViewerSession(oCV)];
  433. }
  434. };
  435. BaseRequestHandler.prototype.onAsynchStatusUpdate = function(status) {
  436. if (this.m_httpRequestConfig) {
  437. var statusCallback = this.m_httpRequestConfig.getReportStatusCallback(status);
  438. if (statusCallback) {
  439. statusCallback();
  440. }
  441. }
  442. };
  443. BaseRequestHandler.prototype.addCallbackHooks = function() {
  444. if (!this.m_httpRequestConfig) {
  445. return;
  446. }
  447. this._addCallback("complete", "onComplete");
  448. this._addCallback("working", "onWorking");
  449. this._addCallback("prompting", "onPrompting");
  450. };
  451. BaseRequestHandler.prototype._addCallback = function(status, functionToAddTo) {
  452. var callbackStatus = status;
  453. var originalFunction = this[functionToAddTo];
  454. this[functionToAddTo] = function(response) {
  455. originalFunction.apply(this, arguments);
  456. var status = null;
  457. // For working responses we'll have a 'response' object here so get the status from it
  458. // so we can tell the difference between working and stillworking
  459. if (response && typeof response.getAsynchStatus == "function") {
  460. status = response.getAsynchStatus();
  461. }
  462. else {
  463. // Complete can be called when we're in a prompting state, so get the real
  464. // status from the CCognosViewer object
  465. status = callbackStatus == "complete" ? this.getViewer().getStatus() : callbackStatus;
  466. }
  467. // We should only call the working callback once, no use in calling it for every subsequent working/stillWorking
  468. if (status == "stillWorking") {
  469. return;
  470. }
  471. var callback = this.m_httpRequestConfig.getReportStatusCallback(status);
  472. if (typeof callback == "function") {
  473. setTimeout(callback, 10);
  474. }
  475. };
  476. };