stacks.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. /********************************************************************************************************************************
  2. * Licensed Materials - Property of IBM *
  3. * *
  4. * IBM Cognos Products: AGS *
  5. * *
  6. * (C) Copyright IBM Corp. 2005, 2008 *
  7. * *
  8. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. *
  9. *********************************************************************************************************************************/
  10. function Stack(max_size){
  11. this.max_size = max_size ? max_size : 50;
  12. this.members = new Array();
  13. }
  14. Stack.prototype.reSize = function(size){
  15. if(this.members.length > size){
  16. var start = this.members.length - size;
  17. this.members = this.members.slice(start, this.members.length - 1);
  18. }
  19. }
  20. //add the peek to Stack
  21. Stack.prototype.peek = function(){
  22. var top = null;
  23. if(this.members.length > 0){
  24. top = this.members[this.members.length - 1];
  25. }
  26. return top;
  27. }
  28. //add the peek to Stack
  29. Stack.prototype.isEmpty = function(){
  30. return this.members.length == 0;
  31. }
  32. //add the push to Stack
  33. Stack.prototype.push = function(pushee){
  34. this.members.push(pushee);
  35. this.reSize(this.max_size);
  36. }
  37. //add the peek to Array
  38. Stack.prototype.pop = function(){
  39. return this.members.pop();
  40. }
  41. //add the peek to Array
  42. Stack.prototype.clear = function(){
  43. this.members = new Array();
  44. }
  45. // check if a item is in stack
  46. Stack.prototype.contains = function(searchid){
  47. var found = false;
  48. for(var i = 0; i < this.members.length; i++){
  49. if(searchid == (this.members[i])){
  50. found = true;
  51. break;
  52. }
  53. }
  54. return found;
  55. }
  56. //return an array of members for which the passed objects search method returns true
  57. //so the caller has to provide an object that has a search method on it that returns a boolean
  58. //hmmm that sounds like an interface
  59. Stack.prototype.search = function(filterer){
  60. var found = new Array();
  61. for(var i = 0; i < this.members.length; i++){
  62. if(filterer && filterer.search){
  63. if(filterer.search(this.members[i])){
  64. found.push(this.members[i]);
  65. }
  66. }
  67. }
  68. return found;
  69. }
  70. //similar to search, but if the matchers search method returns true, then the found
  71. //member is brought to the top ... any other matches subsequently found will be brought to the
  72. //top, but underneath the first found... its lifo so later matches have higher precedence
  73. //default search direction bottom up
  74. //return whether one was brought to the top or not
  75. Stack.prototype.bringToTop = function(matcher){
  76. var new_top = new Array();
  77. var ongoing = new Array();
  78. for(var i = 0; i < this.members.length; i++){
  79. if(matcher && matcher.search){
  80. if(matcher.search(this.members[i])){
  81. new_top.push(this.members[i]);
  82. }
  83. }else{
  84. ongoing.push(this.members[i]);
  85. }
  86. }
  87. this.members = ongoing.concat(new_top);
  88. return new_top.length > 0;
  89. }
  90. Stack.prototype.executeFilter = function(filter, an_object){
  91. if(filter && filter.search){
  92. if(filter.search(an_object)){
  93. return an_object;
  94. }
  95. }
  96. }
  97. /*empty type definition for extension, give it an "execute" method
  98. use this to push on the stack for stateful commands
  99. eg function makeCommandStackObject(value){
  100. var cmdObject = new CommandStackObject();
  101. cmdObject.state = value;
  102. cmdObject.execute = myFunctionRef;
  103. return cmdObject;
  104. }
  105. if you pass in a command.... it will execute that and then call the stack again
  106. this should only be used if the command wont take much time
  107. */
  108. function CommandStackObject(aCommand){
  109. this.command = aCommand;
  110. //lets have some config frame action available
  111. this.cf = parent.getConfigFrame ? parent.getConfigFrame() : getConfigFrame();
  112. //this is a do little... diy
  113. this.execute = function(){
  114. if(this.command){
  115. eval(this.command);
  116. }
  117. setTimeout("getCommandStackManager().processCommandStack();", 100);
  118. }
  119. }
  120. /*
  121. A generic function to create a command stack object with passing in a function name
  122. and it arugments. The function name must always be the last parammeter in the arguments
  123. passed to this function.
  124. */
  125. function createCommandStackObject(){
  126. var cmdObject = new CommandStackObject();
  127. cmdObject.arguments = arguments;
  128. //add the execute method
  129. cmdObject.execute = function(){
  130. var argsLength = this.arguments.length-1;
  131. var fn = this.arguments[argsLength];
  132. var args = "(";
  133. for (var i=0;i < argsLength;i++) {
  134. args += "this.arguments[" +i +"]";
  135. if (i < argsLength-1) {
  136. args += ",";
  137. }
  138. }
  139. args += ")";
  140. eval(fn + args);
  141. setTimeout("getCommandStackManager().processCommandStack();", 100);
  142. }
  143. return cmdObject;
  144. }
  145. /*
  146. the location id is an xpath into the generated report spec of the condition report
  147. */
  148. function createValidateCommandStackObject(location_id, error_div_id){
  149. var cmdObject = new cf.CommandStackObject();
  150. cmdObject.error_div_id = error_div_id;
  151. //add the execute method
  152. cmdObject.execute = function(){
  153. //put this in cfg to be available to the display page
  154. this.cf.cfgSet("ValidateCommandStackObject", this);
  155. //cf is defined in CommandStackObject
  156. this.cf.validateAgentCondition(this.error_div_id);
  157. setTimeout("getCommandStackManager().processCommandStack();", 100);
  158. }
  159. //add a function to test the location_id passed in against the location from an error message
  160. cmdObject.checkLocation = function(location){
  161. if(location_id && location){
  162. return location.indexOf(location_id) != -1;
  163. }
  164. }
  165. return cmdObject;
  166. }
  167. //extend the stack
  168. //pass in either strings to eval, or a CommandStackObject with an execute method
  169. //can pass in a fail command
  170. function CommandStack(commandArray){
  171. var stack = new Stack();
  172. if(commandArray && commandArray.length){
  173. //a little harsh and non oo but quicker (make sure its an array though)
  174. stack.members = commandArray;
  175. }
  176. stack.doNextCommand = function(){
  177. var command = this.pop();
  178. try{
  179. this.evaluateCommand(command);
  180. }catch(ex){
  181. var error_message = ex + " ["+command+"]";
  182. if(ex.message != null){
  183. error_message = ex.message + " ["+command+"]";
  184. }
  185. if(this.failCommand){
  186. try{
  187. this.evaluateCommand(this.failCommand);
  188. alert(error_message);
  189. }catch(ex2){
  190. alert(error_message);
  191. }
  192. }else{
  193. alert(error_message);
  194. }
  195. this.clear();
  196. }
  197. }
  198. stack.evaluateCommand = function(command){
  199. if(command instanceof CommandStackObject){
  200. command.execute();
  201. }else{
  202. eval(command);
  203. }
  204. }
  205. stack.setFailCommand = function(failCommand){
  206. if(failCommand){
  207. this.failCommand = failCommand;
  208. }
  209. }
  210. stack.setCancelCommand = function(cancelCommand){
  211. if(cancelCommand){
  212. this.cancelCommand = cancelCommand;
  213. }
  214. }
  215. stack.concat = function(commandStack){
  216. var concatStack = this.members;
  217. if (commandStack && commandStack instanceof Stack) {
  218. concatStack = this.members.concat(commandStack.members);
  219. }
  220. return new CommandStack(concatStack);
  221. }
  222. stack.doFail = function(){
  223. try{
  224. this.evaluateCommand(this.failCommand);
  225. }catch(ex){
  226. }
  227. this.clear();
  228. }
  229. /**
  230. defaul cancel method
  231. */
  232. stack.cancel = function(){
  233. try{
  234. if(this.cancelCommand){
  235. this.evaluateCommand(this.cancelCommand);
  236. }else{
  237. this.clear();
  238. }
  239. }catch(ex){
  240. }
  241. }
  242. //do a default
  243. stack.setFailCommand("hideDialogFrame();this.clear()");
  244. return stack;
  245. }
  246. //////////////////////////////////
  247. // class (ish) that holds a stack of js commands to be evaluated
  248. // this removes the knowledge of what to do next from cmd.js
  249. ////////////////////////////////
  250. function CommandStackManager(){
  251. }
  252. CommandStackManager.prototype.getCommandStack = function(){
  253. var cmdStack = cfgGet("agsCommandStack");
  254. if(!cmdStack){
  255. cmdStack = new CommandStack();
  256. this.setCommandStack(cmdStack);
  257. }
  258. return cmdStack;
  259. }
  260. CommandStackManager.prototype.setCommandStack = function(cmdStack){
  261. cfgSet("agsCommandStack", cmdStack);
  262. }
  263. //repeated code in following methods is hard to factor out due to the use of the "arguments" key word
  264. CommandStackManager.prototype.createCommandStack = function(){
  265. var cmds = new Array();
  266. //the arguments to this function
  267. var args = arguments;
  268. if(arguments && arguments.length){
  269. //push them in reverse order to maintain the order
  270. for(var i = args.length - 1; i >= 0; i--){
  271. cmds.push(args[i]);
  272. }
  273. }
  274. return new CommandStack(cmds);
  275. }
  276. //takes any amount of arguments and creates a command stack
  277. CommandStackManager.prototype.initiateCommandStack = function(){
  278. if(applicationActionManager.isBlocked()){
  279. return;
  280. }
  281. applicationActionManager.blockActions();
  282. var cmds = new Array();
  283. //the arguments to this function
  284. var args = arguments;
  285. if(arguments && arguments.length){
  286. //push them in reverse order to maintain the order
  287. for(var i = args.length - 1; i >= 0; i--){
  288. cmds.push(args[i]);
  289. }
  290. }
  291. this.setCommandStack(new CommandStack(cmds));
  292. //execute the top
  293. this.processCommandStack();
  294. }
  295. //takes any amount of arguments and creates a command stack
  296. CommandStackManager.prototype.doCommandStack = function(cmdStack){
  297. this.setCommandStack(cmdStack);
  298. this.processCommandStack();
  299. }
  300. CommandStackManager.prototype.processCommandStack = function(){
  301. cmdStack = this.getCommandStack();
  302. if(cmdStack && !cmdStack.isEmpty()){
  303. //alert("cmd stack process: " + cmdStack.peek());
  304. var wasBlocked = applicationActionManager.isBlocked();
  305. // let the user exit, if ES is not usable don't block
  306. if(cmdStack.contains('closeAGS()')) {
  307. var messageIFrame = getMessageIFrame();
  308. var messageIFrame_doc = getFrameDocument(messageIFrame);
  309. wasBlocked = false;
  310. var formsArray = messageIFrame_doc.forms;
  311. //we cannot find a form, something is awry
  312. if (formsArray.length==0) {
  313. // we can't save stuff only option is to exit now
  314. cmdStack.clear();
  315. cmdStack.push('closeAGS()');
  316. }
  317. }
  318. applicationActionManager.allowActions();
  319. //open a window for the action
  320. cmdStack.doNextCommand();
  321. //only reblock when more commands are available
  322. //this needs to be checked because one of the commands
  323. //may have cancelled execution by explicitly clearing the stack
  324. if(wasBlocked && !cmdStack.isEmpty()){
  325. applicationActionManager.blockActions();
  326. }else{
  327. applicationActionManager.allowActions();
  328. }
  329. }
  330. }
  331. var agsCommandStackManager = new CommandStackManager();
  332. function getCommandStackManager(){
  333. return agsCommandStackManager;
  334. }