CDispatcher.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  1. /*
  2. *+------------------------------------------------------------------------+
  3. *| Licensed Materials - Property of IBM
  4. *| BI and PM: prmt
  5. *| (C) Copyright IBM Corp. 2002, 2016
  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. //DISPATCHER CONTROL
  13. function CDispatcher(maxNumSCs)
  14. {
  15. if (typeof maxNumSCs == "undefined") {
  16. this.m_oQueueManager = new CQueueManager();
  17. }
  18. else {
  19. this.m_oQueueManager = new CQueueManager(maxNumSCs);
  20. }
  21. }
  22. // @param extraHeaders [[key1,value1],[key2,value2],../[keyN,valueN],
  23. CDispatcher.prototype.createRequest = function(gateway, requestParams, callbackFunction, extraHeaders)
  24. {
  25. return new CRequest(gateway, requestParams, callbackFunction, extraHeaders);
  26. };
  27. CDispatcher.prototype.dispatchRequest = function(CRequest)
  28. {
  29. return this.m_oQueueManager.addRequestToQueue(CRequest);
  30. };
  31. CDispatcher.prototype.getRequestStatus = function(CRequest)
  32. {
  33. return CRequest.getStatus();
  34. };
  35. CDispatcher.prototype.cancelRequest = function(CRequest)
  36. {
  37. var isCancelled = this.m_oQueueManager.removeRequestFromQueue(CRequest.getId(), false);
  38. if (isCancelled >= 1) {
  39. return 1;
  40. }
  41. return isCancelled;
  42. };
  43. CDispatcher.prototype.setErrorHandlerFunction = function(errorFunction)
  44. {
  45. this.m_oQueueManager.setErrorHandlerFunction(errorFunction);
  46. };
  47. //REQUEST CONTROL
  48. function CRequest(gateway, requestParams, callbackFunction, extraHeaders)
  49. {
  50. this.m_sGateway = gateway;
  51. this.m_sRequestParams = requestParams;
  52. this.m_fCallbackFunction = callbackFunction;
  53. this.m_iRequestId = generateUniqueId();
  54. this.m_sStatus = 0;
  55. this.m_oSC = null;
  56. this.m_sResponseType = "HTML";
  57. this.m_extraHeaders = (typeof extraHeaders != "undefined"? extraHeaders : null);
  58. }
  59. CRequest.prototype.getId = function()
  60. {
  61. return this.m_iRequestId;
  62. };
  63. CRequest.prototype.setResponseType = function(responseType)
  64. {
  65. this.m_sResponseType = responseType;
  66. };
  67. CRequest.prototype.getResponseType = function()
  68. {
  69. return this.m_sResponseType;
  70. };
  71. CRequest.prototype.setStatus = function(statusVal)
  72. {
  73. try
  74. {
  75. this.m_sStatus = statusVal;
  76. }
  77. catch (e)
  78. {
  79. return false;
  80. }
  81. return true;
  82. };
  83. CRequest.prototype.getStatus = function()
  84. {
  85. return this.m_sStatus;
  86. };
  87. CRequest.prototype.getSC = function()
  88. {
  89. return this.m_oSC;
  90. };
  91. CRequest.prototype.setSC = function(sSCval)
  92. {
  93. try
  94. {
  95. this.m_oSC = sSCval;
  96. }
  97. catch (e)
  98. {
  99. return false;
  100. }
  101. return true;
  102. };
  103. CRequest.prototype.getGateway = function()
  104. {
  105. return this.m_sGateway;
  106. };
  107. CRequest.prototype.getRequestParams = function()
  108. {
  109. return this.m_sRequestParams;
  110. };
  111. CRequest.prototype.getCallbackFunction = function()
  112. {
  113. return this.m_fCallbackFunction;
  114. };
  115. CRequest.prototype.getExtraHeaders = function()
  116. {
  117. return this.m_extraHeaders;
  118. };
  119. //QUEUE MANAGER CONTROL
  120. var XMLHttpRequests;
  121. /* Do not reset this variable if it is already set.
  122. It could happen if this file is included twice in a page. */
  123. if (typeof XMLHttpRequests == "undefined") {
  124. XMLHttpRequests = new Array();
  125. }
  126. function CQueueManager(maxNumSCs)
  127. {
  128. this.m_arQueue = new Array();
  129. this.m_arSCs = new Array();
  130. if (typeof maxNumSCs != "undefined") {
  131. this.iMaxNumSCs = maxNumSCs;
  132. }
  133. else {
  134. this.iMaxNumSCs = 2;
  135. }
  136. for (var i = 0; i < this.iMaxNumSCs; i++)
  137. {
  138. var arLen = XMLHttpRequests.length;
  139. var newSC = new CServerCommunicator(this, arLen);
  140. XMLHttpRequests[arLen] = new Array(null, newSC);
  141. this.m_arSCs[this.m_arSCs.length] = newSC;
  142. }
  143. this.errorHandlerFunction = null;
  144. }
  145. CQueueManager.prototype.setErrorHandlerFunction = function(errorFunction)
  146. {
  147. this.errorHandlerFunction = errorFunction;
  148. };
  149. CQueueManager.prototype.addRequestToQueue = function(CRequest)
  150. {
  151. var returnStatus = -1;
  152. try
  153. {
  154. CRequest.setStatus(1);
  155. this.m_arQueue[this.m_arQueue.length] = CRequest;
  156. returnStatus = 0;
  157. var requestSuccess = this.sendNextRequest();
  158. if (requestSuccess == true) {
  159. return 1;
  160. }
  161. else
  162. {
  163. CRequest.setStatus(-1);
  164. return returnStatus;
  165. }
  166. }
  167. catch (e)
  168. {
  169. CRequest.setStatus(-1);
  170. if (typeof this.errorHandlerFunction == "function") {
  171. this.errorHandlerFunction("addRequestToQueue", e);
  172. }
  173. return returnStatus;
  174. }
  175. };
  176. CQueueManager.prototype.removeRequestFromQueue = function(requestId, callCallback, response)
  177. {
  178. try
  179. {
  180. var thisArrayEntry = -1;
  181. for (var i = 0; i < this.m_arQueue.length; i++)
  182. {
  183. if (this.m_arQueue[i] != null && this.m_arQueue[i].getId() == requestId)
  184. {
  185. thisArrayEntry = i;
  186. break;
  187. }
  188. }
  189. if (callCallback == true)
  190. {
  191. var callbackFunction = this.m_arQueue[thisArrayEntry].getCallbackFunction();
  192. if (callbackFunction && typeof callbackFunction.processResponse == "function")
  193. {
  194. callbackFunction.processResponse(response);
  195. }
  196. else if (typeof callbackFunction == "function")
  197. {
  198. try
  199. {
  200. callbackFunction(response);
  201. }
  202. catch (e)
  203. {
  204. if (typeof this.errorHandlerFunction == "function") {
  205. this.errorHandlerFunction("removeRequestFromQueue_1", e);
  206. }
  207. return -1;
  208. }
  209. }
  210. else if (typeof callbackFunction == "string")
  211. {
  212. try
  213. {
  214. eval(callbackFunction);
  215. }
  216. catch (e)
  217. {
  218. if (typeof this.errorHandlerFunction == "function") {
  219. this.errorHandlerFunction("removeRequestFromQueue_1", e);
  220. }
  221. return -1;
  222. }
  223. }
  224. this.m_arQueue[thisArrayEntry].setStatus(3);
  225. delete (this.m_arQueue[thisArrayEntry]);
  226. return 1;
  227. }
  228. else
  229. {
  230. if (this.m_arQueue[thisArrayEntry].getStatus() == 2)
  231. {
  232. try
  233. {
  234. this.m_arSCs[this.m_arQueue[thisArrayEntry].getSC()].cancelRequest();
  235. }
  236. catch (e)
  237. {
  238. if (typeof this.errorHandlerFunction == "function") {
  239. this.errorHandlerFunction("removeRequestFromQueue_2", e);
  240. }
  241. return 0;
  242. }
  243. }
  244. this.m_arQueue[thisArrayEntry].setStatus(-2);
  245. delete (this.m_arQueue[i]);
  246. }
  247. var requestSuccess = this.sendNextRequest();
  248. if (requestSuccess == false) {
  249. return 3;
  250. }
  251. return 2;
  252. }
  253. catch (e)
  254. {
  255. if (typeof this.errorHandlerFunction == "function") {
  256. this.errorHandlerFunction("removeRequestFromQueue_3", e);
  257. }
  258. return -1;
  259. }
  260. };
  261. CQueueManager.prototype.sendNextRequest = function()
  262. {
  263. try
  264. {
  265. var theNextSC = -1;
  266. var i = 0;
  267. for (i = 0; i < this.m_arSCs.length; i++)
  268. {
  269. if (this.m_arSCs[i].getBusy() <= 0)
  270. {
  271. theNextSC = i;
  272. break;
  273. }
  274. }
  275. if (theNextSC > -1)
  276. {
  277. var theNextRequest = -1;
  278. for (i = 0; i < this.m_arQueue.length; i++)
  279. {
  280. if (this.m_arQueue[i] != null && this.m_arQueue[i].getStatus() == 1)
  281. {
  282. this.m_arQueue[i].setStatus(2);
  283. theNextRequest = i;
  284. break;
  285. }
  286. }
  287. if (theNextRequest > -1)
  288. {
  289. this.m_arQueue[theNextRequest].setSC(theNextSC);
  290. this.m_arSCs[theNextSC].sendRequest(this.m_arQueue[theNextRequest]);
  291. }
  292. else
  293. {
  294. //This will empty the queue if there's nothing left in it
  295. var activeRequests = false;
  296. for (i = 0; i < this.m_arQueue.length; i++)
  297. {
  298. if (this.m_arQueue[i] != null && (this.m_arQueue[i].getStatus() == 1 || this.m_arQueue[i].getStatus() == 2))
  299. {
  300. activeRequests = true;
  301. break;
  302. }
  303. }
  304. if (activeRequests == false) {
  305. this.m_arQueue = new Array();
  306. }
  307. }
  308. }
  309. }
  310. catch (e)
  311. {
  312. if (typeof this.errorHandlerFunction == "function") {
  313. this.errorHandlerFunction("sendNextRequest", e);
  314. }
  315. return false;
  316. }
  317. return true;
  318. };
  319. //SERVER COMMUNICATOR CONTROL
  320. function CServerCommunicator(CQueueManager, XMLHttpRequestArrayIndex)
  321. {
  322. this.m_bIsBusy = -1;
  323. this.m_oQueueManager = CQueueManager;
  324. this.m_oRequest = null;
  325. this.m_oXMLHttpRequestIndex = XMLHttpRequestArrayIndex;
  326. }
  327. CServerCommunicator.prototype.sendRequest = function( v_oRequest )
  328. {
  329. this.setBusy(1);
  330. this.m_oRequest = v_oRequest;
  331. var v_oHTTPRequest = this.getHttpRequestObj();
  332. v_oHTTPRequest.onreadystatechange = XMLHttpRequestReadyStateChanged;
  333. v_oHTTPRequest.open("POST", v_oRequest.getGateway(), true);
  334. v_oHTTPRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  335. // add extra headers when available
  336. var v_aExtraHeadersArray = v_oRequest.getExtraHeaders();
  337. if (v_aExtraHeadersArray) {
  338. var kCount = v_aExtraHeadersArray.length;
  339. var v_aHeaders = null;
  340. for (var i = 0; i < kCount; i++) {
  341. v_aHeaders = v_aExtraHeadersArray[i];
  342. if (v_aHeaders.length == 2 && v_aHeaders[0] && v_aHeaders[0].length && v_aHeaders[1] && v_aHeaders[1].length) {
  343. v_oHTTPRequest.setRequestHeader(v_aHeaders[0], v_aHeaders[1]);
  344. }
  345. }
  346. }
  347. v_oHTTPRequest.send( v_oRequest.getRequestParams() );
  348. XMLHttpRequests[this.m_oXMLHttpRequestIndex][0] = v_oHTTPRequest;
  349. };
  350. CServerCommunicator.prototype.getHttpRequestObj = function()
  351. {
  352. var v_oHTTPRequest = null;
  353. if ("ActiveXObject" in window)
  354. {
  355. v_oHTTPRequest = new ActiveXObject("Msxml2.XMLHTTP");
  356. }
  357. else
  358. {
  359. v_oHTTPRequest = new XMLHttpRequest();
  360. }
  361. return v_oHTTPRequest;
  362. };
  363. CServerCommunicator.prototype.getStatus = function()
  364. {
  365. return XMLHttpRequests[this.m_oXMLHttpRequestIndex][0].status;
  366. };
  367. CServerCommunicator.prototype.getBusy = function()
  368. {
  369. return this.m_bIsBusy;
  370. };
  371. CServerCommunicator.prototype.setBusy = function(busyVal)
  372. {
  373. try
  374. {
  375. this.m_bIsBusy = busyVal;
  376. }
  377. catch (e)
  378. {
  379. return false;
  380. }
  381. return true;
  382. };
  383. CServerCommunicator.prototype.cancelRequest = function()
  384. {
  385. return XMLHttpRequests[this.m_oXMLHttpRequestIndex][0].abort();
  386. };
  387. // Ready State Function
  388. function XMLHttpRequestReadyStateChanged()
  389. {
  390. for (var i = 0; i < XMLHttpRequests.length; i++)
  391. {
  392. if (XMLHttpRequests[i] && XMLHttpRequests[i][0] && XMLHttpRequests[i][0].readyState == 4)
  393. {
  394. try
  395. {
  396. XMLHttpRequests[i][1].setBusy(0);
  397. var responseType = XMLHttpRequests[i][1].m_oRequest.getResponseType();
  398. var removeSuccess = -1;
  399. if (responseType == "HTML") {
  400. removeSuccess = XMLHttpRequests[i][1].m_oQueueManager.removeRequestFromQueue(XMLHttpRequests[i][1].m_oRequest.getId(), true, XMLHttpRequests[i][0].responseText);
  401. }
  402. else if (responseType == "XML") {
  403. removeSuccess = XMLHttpRequests[i][1].m_oQueueManager.removeRequestFromQueue(XMLHttpRequests[i][1].m_oRequest.getId(), true, XMLHttpRequests[i][0].responseXML);
  404. }
  405. else if (responseType == "XMLHTML") {
  406. removeSuccess = XMLHttpRequests[i][1].m_oQueueManager.removeRequestFromQueue(XMLHttpRequests[i][1].m_oRequest.getId(), true, new Array(XMLHttpRequests[i][0].responseXML, XMLHttpRequests[i][0].responseText));
  407. }
  408. else if (responseType == "HTTP") {
  409. removeSuccess = XMLHttpRequests[i][1].m_oQueueManager.removeRequestFromQueue(XMLHttpRequests[i][1].m_oRequest.getId(), true, XMLHttpRequests[i][0]);
  410. }
  411. XMLHttpRequests[i][0] = null;
  412. if (removeSuccess >= 1) {
  413. XMLHttpRequests[i][1].m_oQueueManager.sendNextRequest();
  414. }
  415. else {
  416. return false;
  417. }
  418. }
  419. catch (e)
  420. {
  421. return false;
  422. }
  423. return true;
  424. }
  425. }
  426. return false;
  427. }
  428. // Utility Functions
  429. function generateUniqueId()
  430. {
  431. return (Date.parse((new Date()).toString()) / 1000000) + Math.random();
  432. }