IOAdapters.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528
  1. /* Copyright (c) Business Objects 2006. All rights reserved. */
  2. /**
  3. * Abstract base class. IOAdapters allow the ViewerListener to request data from
  4. * a server without knowing the details of how a particular framework requires
  5. * the request to be made.
  6. */
  7. bobj.crv.IOAdapterBase = {
  8. /**
  9. * Send a viewer request to the Server.
  10. *
  11. * @param pageState [Object] The composite view state for all viewers on the page
  12. * @param viewerName [String] The name of the viewer that should handle the request
  13. * @param eventArgs [Object] Event arguements
  14. * @param allowAsynch [bool] True if asynchronous requests are allowed
  15. *
  16. * @return [MochiKit.Async.Deferred] Returns a Deferred if an asynchronous
  17. * request is pending.
  18. */
  19. request: function() {},
  20. /**
  21. * Add a parameter to server requests.
  22. *
  23. * @param fldName [String] Name of the parameter
  24. * @param fldValue [String] Value of the parameter
  25. */
  26. addRequestField: function(fldName, fldValue) {},
  27. /**
  28. * Remove a parameter from server requests.
  29. *
  30. * @param fldName [String] Name of the parameter
  31. */
  32. removeRequestField: function(fldName) {},
  33. /**
  34. * Save the page state. Persist the state in a manner apropriate
  35. * for the framework.
  36. *
  37. * @param pageState [Object] The composite view state for all viewers on the page
  38. * @param viewerName [String] The name of the viewer that making the request
  39. */
  40. saveViewState: function(pageState, viewerName) {},
  41. /**
  42. * Get the postback data queryString to use for Active X print control
  43. *
  44. * @param pageState [Object] The composite view state for all viewers on the page
  45. * @param viewerName [String] The name of the viewer that making the request
  46. * @return [String] the postback data in a query string format
  47. */
  48. getPostDataForPrinting: function(pageState, viewerName) {},
  49. /**
  50. * Allows the IOAdapter to manipulate the error before the Viewer processes it for display to the user.
  51. */
  52. processError: function(response) {return response;},
  53. canUseAjax: function() {
  54. try {
  55. return (MochiKit.Async.getXMLHttpRequest() !== null);
  56. }
  57. catch (e) {
  58. return false;
  59. }
  60. }
  61. };
  62. /*
  63. ================================================================================
  64. ServletAdapter. ServletAdapter issues requests to the Java DHTML viewer.
  65. ================================================================================
  66. */
  67. /**
  68. * Constructor for ServletAdapter.
  69. *
  70. * @param pageUrl [string] URL of the page
  71. * @param servletUrl [string] URL to which requests to a servlet should be made
  72. * It doubles as the url for all asyncronous requests
  73. */
  74. bobj.crv.ServletAdapter = function(pageUrl, servletUrl) {
  75. this._pageUrl = pageUrl;
  76. this._servletUrl = servletUrl;
  77. this._form = null;
  78. };
  79. bobj.crv.ServletAdapter._requestParams = {
  80. STATE: 'CRVCompositeViewState',
  81. TARGET: 'CRVEventTarget',
  82. ARGUMENT: 'CRVEventArgument'
  83. };
  84. bobj.crv.ServletAdapter.prototype = MochiKit.Base.merge(bobj.crv.IOAdapterBase, {
  85. request: function(pageState, viewerName, eventArgs, allowAsync) {
  86. if (!this._form) {
  87. this._createForm();
  88. }
  89. var rp = bobj.crv.ServletAdapter._requestParams;
  90. var toJSON = MochiKit.Base.serializeJSON;
  91. this._form[rp.STATE].value = encodeURIComponent(toJSON(pageState));
  92. this._form[rp.TARGET].value = encodeURIComponent(viewerName);
  93. this._form[rp.ARGUMENT].value = encodeURIComponent(toJSON(eventArgs));
  94. var deferred = null;
  95. if (allowAsync && this._servletUrl) {
  96. var req = MochiKit.Async.getXMLHttpRequest();
  97. req.open("POST", this._servletUrl, true);
  98. req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  99. req.setRequestHeader('Accept','application/json');
  100. deferred = MochiKit.Async.sendXMLHttpRequest(req, MochiKit.Base.queryString(this._form));
  101. }
  102. else {
  103. this._form.submit();
  104. }
  105. // once the form is submitted it is not intended to be reused.
  106. this._form = null;
  107. return deferred;
  108. },
  109. redirectToServlet: function () {
  110. if (!this._form) {
  111. this._createForm();
  112. }
  113. this._form.action = this._servletUrl;
  114. },
  115. _createForm: function() {
  116. var d = MochiKit.DOM;
  117. var rp = bobj.crv.ServletAdapter._requestParams;
  118. this._form = d.FORM({
  119. name: bobj.uniqueId(),
  120. style: 'display:none',
  121. method: 'POST',
  122. enctype: 'application/x-www-form-urlencoded;charset=utf-8',
  123. action: this._pageUrl},
  124. d.INPUT({type: 'hidden', name: rp.STATE}),
  125. d.INPUT({type: 'hidden', name: rp.TARGET}),
  126. d.INPUT({type: 'hidden', name: rp.ARGUMENT}));
  127. document.body.appendChild(this._form);
  128. },
  129. addRequestField: function(fldName, fldValue) {
  130. if (fldName && fldValue) {
  131. if (!this._form) {
  132. this._createForm();
  133. }
  134. var existingElem = this._form[fldName];
  135. if (existingElem) {
  136. existingElem.value = fldValue;
  137. }
  138. else {
  139. this._form.appendChild(MochiKit.DOM.INPUT({type: 'hidden', name:fldName, value:fldValue}));
  140. }
  141. }
  142. },
  143. removeRequestField: function(fldName) {
  144. if (fldName) {
  145. var form = this._form;
  146. if (form) {
  147. var existingElem = form[fldName];
  148. if (existingElem) {
  149. MochiKit.DOM.removeElement(existingElem);
  150. if(form[fldName]) { // Fix for FF
  151. form[fldName] = null;
  152. }
  153. }
  154. existingElem = null;
  155. }
  156. }
  157. },
  158. getPostDataForPrinting: function(pageState, viewerName) {
  159. var toJSON = MochiKit.Base.serializeJSON;
  160. var rp = bobj.crv.ServletAdapter._requestParams;
  161. var state = toJSON(pageState);
  162. var postData = rp.STATE;
  163. postData += '=';
  164. postData += encodeURIComponent(state);
  165. postData += '&';
  166. postData += rp.TARGET;
  167. postData += '=';
  168. postData += encodeURIComponent(viewerName);
  169. postData += '&';
  170. postData += rp.ARGUMENT;
  171. postData += '=';
  172. postData += encodeURIComponent('"axprint="');
  173. if(document.getElementById('com.sun.faces.VIEW')) {
  174. postData += "&com.sun.faces.VIEW=" + encodeURIComponent(document.getElementById('com.sun.faces.VIEW').value);
  175. }
  176. return postData;
  177. },
  178. processError: function(response) {
  179. if (!(typeof(response.number) == 'undefined') && response.number == 404) {
  180. return L_bobj_crv_ServletMissing;
  181. }
  182. return response;
  183. }
  184. });
  185. /*
  186. ================================================================================
  187. AspDotNetAdapter. AspDotNetAdapter issues requests to the WebForm DHTML viewer.
  188. ================================================================================
  189. */
  190. /**
  191. * Constructor for AspDotNetAdapter.
  192. *
  193. * @param postbackEventReference [string] The full functiona call to the ASP.NET dopostback function
  194. * @param replacementParameter [string] the string to replace in the dopostback function
  195. * @param stateID [string] the name of the input field to save the state to
  196. */
  197. bobj.crv.AspDotNetAdapter = function(postbackEventReference, replacementParameter, stateID, callbackEventReference) {
  198. this._postbackEventReference = postbackEventReference;
  199. this._replacementParameter = replacementParameter;
  200. this._stateID = stateID;
  201. this._form = null;
  202. this._callbackEventReference = callbackEventReference;
  203. this._additionalReqFlds = null;
  204. var tmpState = bobj.getElementByIdOrName(this._stateID);
  205. if (tmpState) {
  206. this._form = tmpState.form;
  207. }
  208. };
  209. bobj.crv.AspDotNetAdapter.prototype = MochiKit.Base.merge(bobj.crv.IOAdapterBase, {
  210. request: function(pageState, viewerName, eventArgs, allowAsync, callbackHandler, errbackHandler) {
  211. var toJSON = MochiKit.Base.serializeJSON;
  212. if (eventArgs && this._additionalReqFlds) {
  213. eventArgs = MochiKit.Base.update(eventArgs, this._additionalReqFlds);
  214. }
  215. this._additionalReqFlds = null;
  216. var jsonEventArgs = toJSON(eventArgs);
  217. if (allowAsync) {
  218. this.saveViewState(pageState, viewerName);
  219. if(typeof WebForm_InitCallback == "function") {
  220. __theFormPostData = ""; //Used by WeForm_InitCallback
  221. __theFormPostCollection = []; //Used by WeForm_InitCallback
  222. WebForm_InitCallback(); //Need to call this to work around a problem where ASP.NET2 callback does not collect form data prior to request
  223. }
  224. var callback = this._callbackEventReference.replace("'arg'", "jsonEventArgs");
  225. callback = callback.replace("'cb'", "callbackHandler");
  226. callback = callback.replace("'errcb'", "errbackHandler");
  227. callback = callback.replace("'frmID'", "this._form.id");
  228. return eval(callback);
  229. }
  230. else {
  231. var postbackCall;
  232. if(this._postbackEventReference.indexOf("'" + this._replacementParameter + "'") >= 0){
  233. postbackCall = this._postbackEventReference.replace("'" + this._replacementParameter + "'", "jsonEventArgs");
  234. }
  235. else {
  236. postbackCall = this._postbackEventReference.replace('"' + this._replacementParameter + '"', "jsonEventArgs");
  237. }
  238. eval(postbackCall);
  239. this._clearEventFields()
  240. }
  241. },
  242. saveViewState: function(pageState, viewerName) {
  243. var toJSON = MochiKit.Base.serializeJSON;
  244. var viewState = pageState[viewerName];
  245. var state = bobj.getElementByIdOrName(this._stateID);
  246. if (state) {
  247. state.value = toJSON(viewState);
  248. }
  249. },
  250. getPostDataForPrinting: function(pageState, viewerName) {
  251. var nv = MochiKit.DOM.formContents(this.form);
  252. var names = nv[0];
  253. var values = nv[1];
  254. names.push('crprint');
  255. values.push(viewerName);
  256. var queryString = MochiKit.Base.queryString(names, values);
  257. return queryString;
  258. },
  259. addRequestField: function(fldName, fldValue) {
  260. if (!this._additionalReqFlds) {
  261. this._additionalReqFlds = {};
  262. }
  263. this._additionalReqFlds[fldName] = fldValue;
  264. /*if (fldName && fldValue) {
  265. var existingElem = this._form[fldName];
  266. if (existingElem) {
  267. existingElem.value = fldValue;
  268. }
  269. else {
  270. this._form.appendChild(MochiKit.DOM.INPUT({type: 'hidden', name:fldName, value:fldValue}));
  271. }
  272. }*/
  273. },
  274. _clearRequestField: function(fldName) {
  275. if (fldName) {
  276. if (this._form) {
  277. var existingElem = this._form[fldName];
  278. if (existingElem) {
  279. existingElem.value = "";
  280. }
  281. }
  282. }
  283. },
  284. _clearEventFields: function() {
  285. this._clearRequestField("__EVENTTARGET");
  286. this._clearRequestField("__EVENTARGUMENT");
  287. }
  288. });
  289. /*
  290. ================================================================================
  291. FacesAdapter. FacesAdapter issues requests to a JSF viewer component.
  292. ================================================================================
  293. */
  294. /**
  295. * Constructor for FacesAdapter.
  296. *
  297. * @param formName [string] Name of the form to submit
  298. * @param servletUrl [string] URL to which requests to a servlet should be made
  299. * It doubles as the url for all asyncronous requests
  300. */
  301. bobj.crv.FacesAdapter = function(formName, servletUrl) {
  302. this._formName = formName;
  303. this._servletUrl = servletUrl;
  304. this._useServlet = false;
  305. if (!bobj.crv.FacesAdapter._hasInterceptedSubmit) {
  306. this._interceptSubmit();
  307. bobj.crv.FacesAdapter._hasInterceptedSubmit = true;
  308. }
  309. };
  310. bobj.crv.FacesAdapter._requestParams = {
  311. STATE: 'CRVCompositeViewState',
  312. TARGET: 'CRVEventTarget',
  313. ARGUMENT: 'CRVEventArgument'
  314. };
  315. bobj.crv.FacesAdapter.prototype = MochiKit.Base.merge(bobj.crv.IOAdapterBase, {
  316. request: function(pageState, viewerName, eventArgs, allowAsync) {
  317. var rp = bobj.crv.FacesAdapter._requestParams;
  318. var toJSON = MochiKit.Base.serializeJSON;
  319. var INPUT = MochiKit.DOM.INPUT;
  320. var deferred = null;
  321. var form = this._getForm();
  322. if (!form) {
  323. return;
  324. }
  325. if (!form[rp.TARGET]) {
  326. form.appendChild( INPUT({type: 'hidden', name: rp.TARGET}) );
  327. }
  328. form[rp.TARGET].value = encodeURIComponent(viewerName);
  329. if (!form[rp.ARGUMENT]) {
  330. form.appendChild( INPUT({type: 'hidden', name: rp.ARGUMENT}) );
  331. }
  332. form[rp.ARGUMENT].value = encodeURIComponent(toJSON(eventArgs));
  333. if (!form[rp.STATE]) {
  334. form.appendChild( INPUT({type: 'hidden', name: rp.STATE}) );
  335. }
  336. form[rp.STATE].value = encodeURIComponent(toJSON(pageState));
  337. if (allowAsync && this._servletUrl) {
  338. var req = MochiKit.Async.getXMLHttpRequest();
  339. req.open("POST", this._servletUrl, true);
  340. req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  341. req.setRequestHeader('Accept','application/json');
  342. deferred = MochiKit.Async.sendXMLHttpRequest(req, MochiKit.Base.queryString(form));
  343. }
  344. else {
  345. var pageUrl = form.action;
  346. if (this._useServlet === true) {
  347. form.action = this._servletUrl;
  348. }
  349. form.submit();
  350. form.action = pageUrl;
  351. this._useServlet = false;
  352. }
  353. // clear out the request fields so that the form can be reused
  354. form[rp.TARGET].value = "";
  355. form[rp.ARGUMENT].value = "";
  356. form[rp.STATE].value = "";
  357. // TODO Post Titan: we shouldn't need to have explicit knowledge of this parameter
  358. this.removeRequestField ('ServletTask');
  359. return deferred;
  360. },
  361. redirectToServlet: function () {
  362. this._useServlet = true;
  363. },
  364. addRequestField: function(fldName, fldValue) {
  365. if (fldName && fldValue) {
  366. var form = this._getForm();
  367. if (form) {
  368. var existingElem = form[fldName];
  369. if (existingElem) {
  370. existingElem.value = fldValue;
  371. }
  372. else {
  373. form.appendChild(MochiKit.DOM.INPUT({type: 'hidden', name:fldName, value:fldValue}));
  374. }
  375. }
  376. }
  377. },
  378. removeRequestField: function(fldName) {
  379. if (fldName) {
  380. var form = this._getForm();
  381. if (form) {
  382. var existingElem = form[fldName];
  383. if (existingElem) {
  384. MochiKit.DOM.removeElement(existingElem);
  385. if(form[fldName]) { // Fix for FF
  386. form[fldName] = null;
  387. }
  388. }
  389. existingElem = null;
  390. }
  391. }
  392. },
  393. saveViewState: function(pageState, viewerName) {
  394. if (!bobj.crv.FacesAdapter._isStateSaved) {
  395. var form = this._getForm();
  396. if (form) {
  397. var rp = bobj.crv.FacesAdapter._requestParams;
  398. var toJSON = MochiKit.Base.serializeJSON;
  399. var INPUT = MochiKit.DOM.INPUT;
  400. if (!form[rp.STATE]) {
  401. form.appendChild( INPUT({type: 'hidden', name: rp.STATE}) );
  402. }
  403. form[rp.STATE].value = encodeURIComponent(toJSON(pageState));
  404. }
  405. bobj.crv.FacesAdapter._isStateSaved = true;
  406. }
  407. },
  408. _getForm: function() {
  409. return document.forms[this._formName];
  410. },
  411. _interceptSubmit: function() {
  412. var form = this._getForm();
  413. if (form) {
  414. var oldSubmit = form.submit;
  415. form.submit = function() {
  416. bobj.event.publish('saveViewState');
  417. form.submit = oldSubmit; // IE needs this
  418. form.submit(); // Can't apply args because IE misbehaves
  419. };
  420. }
  421. },
  422. getPostDataForPrinting: function(pageState, viewerName) {
  423. var toJSON = MochiKit.Base.serializeJSON;
  424. var rp = bobj.crv.ServletAdapter._requestParams;
  425. var state = toJSON(pageState);
  426. var postData = rp.STATE;
  427. postData += '=';
  428. postData += encodeURIComponent(state);
  429. postData += '&';
  430. postData += rp.TARGET;
  431. postData += '=';
  432. postData += encodeURIComponent(viewerName);
  433. postData += '&';
  434. postData += rp.ARGUMENT;
  435. postData += '=';
  436. postData += encodeURIComponent('"axprint="');
  437. if(document.getElementById('com.sun.faces.VIEW')) {
  438. postData += "&com.sun.faces.VIEW=" + encodeURIComponent(document.getElementById('com.sun.faces.VIEW').value);
  439. }
  440. return postData;
  441. },
  442. processError: function(response) {
  443. if (!(typeof(response.number) == 'undefined') && response.number == 404) {
  444. return L_bobj_crv_ServletMissing;
  445. }
  446. return response;
  447. }
  448. });