reportSpec.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. /********************************************************************************************************************************
  2. * Licensed Materials - Property of IBM *
  3. * *
  4. * IBM Cognos Products: AGS *
  5. * *
  6. * (C) Copyright IBM Corp. 2005, 2015 *
  7. * *
  8. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. *
  9. *********************************************************************************************************************************/
  10. /*
  11. * Build a report specification by calling buildReportSpec.xts. This uses the XHTTP dispatcher
  12. * which utilises a callback to set the report spec into a config parameter. It should
  13. * be called using the command stack manager
  14. * Optional config parameters can be set that change the way specification is built.
  15. * Details are below(default settings shown in brackets).
  16. *
  17. * Inputs
  18. * inlineSpec_items - an array of data items (all current data items)
  19. * inlineSpec_groups - an array of group items (no grouping). Group items contain a 'ref' property
  20. * inlineSpec_sorts - an array of sort items (no sorting). Sort items contain 'ref' and 'order' properties
  21. * inlineSpec_forCount - true or false (false)
  22. * The following options are used when the hidden menu items to import agent spec from clipboard:
  23. * inlineSpec_promptPages - an element containing custom prompt pages.
  24. * inlineSpec_extraQueries - an array of extra query nodes.
  25. *
  26. * Outputs
  27. * inlineSpec - the signed report specification
  28. */
  29. function getReportSpec() {
  30. var cf = getConfigFrame();
  31. var groups = cf.cfgGet("inlineSpec_groups");
  32. var sorts = cf.cfgGet("inlineSpec_sorts");
  33. var promptPages = cf.cfgGet("inlineSpec_promptPages");
  34. if (promptPages == undefined) {
  35. promptPages = null;
  36. }
  37. var extraQueries = cf.cfgGet("inlineSpec_extraQueries");
  38. if (extraQueries == undefined) {
  39. extraQueries = null;
  40. }
  41. //count
  42. var forCount = cf.cfgGet("inlineSpec_forCount");
  43. if (forCount==undefined) {
  44. forCount=false;
  45. }
  46. //items
  47. var items = cf.cfgGet("inlineSpec_items");
  48. if (items == undefined) {
  49. items = null;
  50. }
  51. //start the request
  52. startReportSpecRequest(items,groups,sorts,forCount,promptPages,extraQueries);
  53. }
  54. /*
  55. * Build an XML structure <items>...</item> containing the metadata needed
  56. * to build a report specification. The specification is built on the server by
  57. * the morphlet 'ags/buildReportSpec.xts'. The XHTTP dispatcher is used the run the
  58. * morphlet asynchronously. If no parameters are passed to this function, the current data items
  59. * will be used with no 'sort' and no 'group by' sections.
  60. *
  61. * items - custom list of items taken from the agent items tree. If null then all query items are used
  62. * groups(optional) - the group settings. If missing no sort elements will be created
  63. * sorts(optional) - the sort settings. If missing no group elements will be created
  64. * forCount(optional) - true when building the report spec for the count command. If missing default is false
  65. */
  66. function startReportSpecRequest(items,groups,sorts,forCount,promptPages,extraQueries) {
  67. signedReportSpec="";
  68. var msgFrame = getMessageIFrame();
  69. var frameDoc = getFrameDocument(msgFrame);
  70. var diXML = "<items>";
  71. if (forCount==true) {
  72. diXML+="<type>for_count</type>";
  73. }
  74. if (items==null) {
  75. items = getTreeValues(getDataItemsTree());
  76. }
  77. //build the filter element
  78. diXML += buildFilter();
  79. if (forCount != undefined && forCount==true) {
  80. diXML += buildFixedItemXML("_count","<dataItem name=\"_count\"><expression>count ([_const] for report)</expression></dataItem>");
  81. diXML += buildFixedItemXML("_const","<dataItem name=\"_const\" rollupAggregate=\"total\" aggregate=\"calculated\"><expression>1</expression></dataItem>");
  82. }
  83. //these are jscript objects holding the details of report and agent tasks and their parameter assignments
  84. var reportTasks = getAgentItemsListener().getReportTaskAssignments();
  85. // loop over all the items in the agent items tree
  86. for (var i = 0; items!= null && i < items.length; ++i) {
  87. diXML += buildItemXML(items[i],"", false,reportTasks);
  88. }
  89. // add the group by's if they have been defined
  90. if (groups != undefined && groups != null && groups.length > 0) {
  91. for (var i = 0; i < groups.length; ++i) {
  92. // get the group reference
  93. var group = groups[i];
  94. diXML += "<group ref=\"" + group.ref + "\"/>";
  95. }
  96. }
  97. // add the sort by's if they have been defined
  98. if (sorts != undefined && sorts != null && sorts.length > 0) {
  99. for (var i = 0; i < sorts.length; ++i) {
  100. // get the sorts reference
  101. var sorts = sorts[i];
  102. diXML += "<sort ref=\"" + sorts.ref + "\" order=\""+sorts.order+"\"/>";
  103. }
  104. }
  105. diXML += "</items>";
  106. var holder = new Object();
  107. holder['queryItems'] = diXML;
  108. // serialize the promptPages Element to a string; remove all the attributes to avoid report server death.
  109. if (promptPages != null) {
  110. var promptpage = promptPages.cloneNode(true);
  111. if (promptpage.attributes.length > 0){
  112. promptpage.removeAttribute('xmlns');
  113. }
  114. if (window.clipboardData) {
  115. holder['promptPages'] = promptpage.xml;
  116. } else {
  117. holder['promptPages'] = (new XMLSerializer( )).serializeToString(promptpage);
  118. }
  119. //alert(holder['promptPages']);
  120. }
  121. if (extraQueries != null && extraQueries.length > 0) {
  122. var extraQueriesString = "";
  123. for (var i = 0; i < extraQueries.length; i++) {
  124. if (window.clipboardData) {
  125. //alert(extraQueries[i].xml);
  126. extraQueriesString = extraQueriesString + extraQueries[i].xml;
  127. } else {
  128. extraQueriesString = extraQueriesString + (new XMLSerializer( )).serializeToString(extraQueries[i]);
  129. }
  130. }
  131. holder['extraQueries'] = extraQueriesString;
  132. }
  133. holder['el'] = getExpressionLocale();
  134. holder['model'] = cf.cfgGet("cmLastModel");
  135. holder['m'] = "/ags/buildReportSpec.xts";
  136. // force SOAPFault for passport expire instead of getting a logon page
  137. holder['forceSOAPFault'] = "false";
  138. var dispatcher = new parent.cf.XHTTPDispatcher(processReportSpecResponse, holder);
  139. applicationActionManager.httpStart();
  140. try{
  141. dispatcher.dispatch();
  142. }catch(ex){
  143. applicationActionManager.httpStop();
  144. }
  145. }
  146. function processReportSpecResponse(responseArray) {
  147. var signedReportSpec="";
  148. applicationActionManager.httpStop();
  149. // get the values returned
  150. var responseXML = responseArray[0];
  151. var responseText = responseArray[1];
  152. //Although it is unlikely but there is a chance this may fault when calling
  153. //the xts.
  154. var parsedResponse = parseResponse(responseXML,responseText);
  155. // decide what we're going to do
  156. if (parsedResponse.isLogonFault()) {
  157. doPassportExpire(responseXML,resendGetReportSpec,parsedResponse);
  158. applicationActionManager.httpStop();
  159. return;
  160. } else if (parsedResponse.isSoapFault()) {
  161. // we have a fault which is a genuine fault fault
  162. doSOAPFault(responseXML,null,parsedResponse);
  163. } else {
  164. //get the reportSpec text
  165. signedReportSpec = parsedResponse.getTextValueForXPath("./*[local-name()='value']");
  166. }
  167. if(document.documentMode > 10){ //workaround in IE11 as signedReportSpec is null
  168. //alert('in IE11 signedReportSpec ' +signedReportSpec);
  169. if(signedReportSpec==null){
  170. signedReportSpec = responseText ;
  171. }
  172. //alert('now signedReportSpec ' +signedReportSpec);
  173. }
  174. cf.cfgSet("inlineSpec",signedReportSpec);
  175. clearReportSpecInputs();
  176. setTimeout("getCommandStackManager().processCommandStack();", 100);
  177. }
  178. function resendGetReportSpec() {
  179. getCommandStackManager().getCommandStack().push("getReportSpec()");
  180. }
  181. function buildFixedItemXML(name,dataItemStr) {
  182. var v_sDiXML="";
  183. v_sDiXML += "<item name=\"" + name + "\">";
  184. v_sDiXML += dataItemStr;
  185. v_sDiXML += "</item>";
  186. return v_sDiXML;
  187. }
  188. /*
  189. * item - a tree node
  190. * sort - the sort order 0 or 1, optional
  191. * noAggregate - true to set no aggregates, optional
  192. */
  193. function buildItemXML(item,sort,noAggregate,reportTasks) {
  194. var v_sDiXML="";
  195. //create the item
  196. v_sDiXML += "<item name=\"" + encode(getObjPropName(item)) + "\"";
  197. v_sDiXML += " displayType=\""+item.displayType+"\">";
  198. v_sDiXML += buildDataItemXML(item,sort,noAggregate)
  199. v_sDiXML += createDrillThroughs(item.name, reportTasks);
  200. v_sDiXML += "</item>";
  201. return v_sDiXML;
  202. }
  203. function buildFilter()
  204. {
  205. //The AgentTask-condition holds an XML encoded blob of the summary and details
  206. //filter. We have a hidden input in the defineCondtion.xts that is always updated
  207. //when the summary and detail filter changes.
  208. var filters = "";
  209. var msgFrame = getMessageIFrame();
  210. var msgDoc = getFrameDocument(msgFrame);
  211. // get the task condition element
  212. var conditionElement = msgDoc.getElementById("AgentTask-condition");
  213. var filters_string = cf.cfgGet("AgentTask-condition");
  214. if(conditionElement != null && conditionElement.value != ""){
  215. filters_string = conditionElement.value;
  216. }
  217. // if we have an element - get it's value
  218. if (filters_string != null && filters_string != "") {
  219. // condition element MIGHT be 2 elements if we have both summary and detail filters, so create a dummy root node.
  220. var filters_xml = new XMLParser("<filter>"+ filters_string +"</filter>");
  221. if (filters_xml != null && filters_xml.childNodes != null && filters_xml.childNodes.length > 0) {
  222. //shouldnt have any attributes.. they are probably xts ones which cause report server validation death
  223. filters_xml.attributes = new Array();
  224. // handle the filters and combine as one string
  225. for (var i = 0; i < filters_xml.childNodes.length; i++) {
  226. filters_xml.childNodes[i].attributes = new Array();
  227. filters = filters + filters_xml.childNodes[i].toString();
  228. }
  229. }
  230. }
  231. // return the filters
  232. return filters;
  233. }
  234. function clearReportSpecInputs() {
  235. var cf = getConfigFrame();
  236. cf.cfgSet("inlineSpec_items",undefined);
  237. cf.cfgSet("inlineSpec_groups",undefined);
  238. cf.cfgSet("inlineSpec_sorts",undefined);
  239. cf.cfgSet("inlineSpec_forCount",undefined);
  240. // do not clear the promptPages here
  241. //cf.cfgSet("inlineSpec_promptPages",undefined);
  242. //cf.cfgSet("inlineSpec_extraQueries",undefined);
  243. }
  244. function buildDataItemXML(node,sort,noAggregate) {
  245. var v_sDiXML="";
  246. //create the referenced data item fragment
  247. v_sDiXML += "<dataItem name=\"" + encode(getObjPropName(node)) + "\" label=\"" + encode(getObjPropName(node)) + "\"";
  248. //aggregate
  249. if (noAggregate!=undefined && (noAggregate==true || noAggregate=="true")) {
  250. v_sDiXML += " aggregate=\"none\" rollupAggregate=\"none\"";
  251. }
  252. else {
  253. var v_sAgg = "none";
  254. if (node.regularAggregate != undefined) {
  255. v_sAgg = encode(getObjProp(node, "regularAggregate"));
  256. }
  257. v_sDiXML += " aggregate=\"" + v_sAgg + "\"";
  258. }
  259. //sort
  260. if (sort != undefined && sort.length > 0) {
  261. v_sDiXML += " sort=\"" + sort + "\"";
  262. }
  263. v_sDiXML += ">";
  264. v_sDiXML += "<expression>" + encode(getObjProp(node,"ref")) + "</expression>";
  265. v_sDiXML += "</dataItem>";
  266. return v_sDiXML;
  267. }
  268. /*
  269. * write out a drill through for each promptable report and agent task
  270. * the drills go in the list column bodies in the layout section
  271. I have loosely associated each drill though with the columns for
  272. the topics they contain, if multiple tasks contain the same topic they will all be here
  273. but if there are multiple topics in the same task, then the first
  274. topic to come up will contain the drill
  275. */
  276. function createDrillThroughs(topicName, reportTaskAssignments){
  277. var drillThroughs = "";
  278. var foundDrill = false;
  279. //only one drill through per topic... they all come out the same anyway
  280. //i.e. drill values are not specific to the target, but to the source
  281. for(i = 0; reportTaskAssignments && i < reportTaskAssignments.length; i++){
  282. var reportTaskAssignment = reportTaskAssignments[i];
  283. if(!reportTaskAssignment || !reportTaskAssignment.parameterAssignments ||
  284. reportTaskAssignment.parameterAssignments.length < 1 || !reportTaskAssignment.reportPath
  285. || !reportTaskAssignment.containsTopic(topicName) || foundDrill){
  286. continue;
  287. }
  288. foundDrill = true;
  289. drillThroughs += "<drill id=\""+ reportTaskAssignment.taskId +"\"";
  290. drillThroughs += " path=\""+encode(reportTaskAssignment.reportPath)+"\"";
  291. drillThroughs += " name=\""+encode(reportTaskAssignment.reportName)+"\">";
  292. if (reportTaskAssignment.parameterAssignments.length > 0) {
  293. drillThroughs +="<links>";
  294. }
  295. for(var j = 0; j < reportTaskAssignment.parameterAssignments.length; j++){
  296. var pa = reportTaskAssignment.parameterAssignments[j];
  297. if(!pa || pa.topic != topicName){
  298. continue;
  299. }
  300. drillThroughs += "<link name=\""+encode(pa.parameterName)+"\" topic=\""+encode(pa.topic)+"\"/>";
  301. }
  302. if (reportTaskAssignment.parameterAssignments.length > 0) {
  303. drillThroughs +="</links>";
  304. }
  305. drillThroughs += "</drill>";
  306. }
  307. return drillThroughs;
  308. }