ESPResult.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. /*##############################################################################
  2. # HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems.
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. ############################################################################## */
  16. define([
  17. "dojo/_base/declare",
  18. "dojo/_base/array",
  19. "dojo/_base/Deferred",
  20. "dojo/_base/lang",
  21. "dojo/data/ObjectStore",
  22. "dojo/store/util/QueryResults",
  23. "dojo/store/Observable",
  24. "dojo/dom-construct",
  25. "dojox/xml/parser",
  26. "dojox/xml/DomParser",
  27. "dojox/html/entities",
  28. "hpcc/ESPBase",
  29. "hpcc/ESPRequest",
  30. "hpcc/WsWorkunits"
  31. ], function (declare, arrayUtil, Deferred, lang, ObjectStore, QueryResults, Observable, domConstruct,
  32. parser, DomParser, entities,
  33. ESPBase, ESPRequest, WsWorkunits) {
  34. var Store = declare([ESPRequest.Store, ESPBase], {
  35. service: "WsWorkunits",
  36. action: "WUResult",
  37. responseQualifier: "WUResultResponse.Result",
  38. responseTotalQualifier: "WUResultResponse.Total",
  39. idProperty: "rowNum",
  40. startProperty: "Start",
  41. countProperty: "Count",
  42. preRequest: function (request) {
  43. if (this.name) {
  44. request['LogicalName'] = this.name;
  45. } else {
  46. request['Wuid'] = this.wuid;
  47. request['Sequence'] = this.sequence;
  48. }
  49. if (request.includeXmlSchema) {
  50. request['SuppressXmlSchema'] = false;
  51. } else {
  52. request['SuppressXmlSchema'] = true;
  53. }
  54. },
  55. preProcessResponse: function (response, request) {
  56. var xml = "<Result>" + response.Result + "</Result>";
  57. var domXml = parser.parse(xml);
  58. if (request.includeXmlSchema) {
  59. this.XmlSchema = this.getValues(domXml, "XmlSchema");
  60. } else {
  61. this.XmlSchema = [];
  62. }
  63. var rows = this.getValues(domXml, "Row");
  64. arrayUtil.forEach(rows, function (item, index) {
  65. item.rowNum = request.Start + index + 1;
  66. });
  67. response.Result = rows;
  68. }
  69. });
  70. var Result = declare(null, {
  71. store: null,
  72. Total: "-1",
  73. constructor: function (args) {
  74. declare.safeMixin(this, args);
  75. if (lang.exists("Sequence", this)) {
  76. this.store = new Store({
  77. wuid: this.Wuid,
  78. sequence: this.Sequence,
  79. isComplete: this.isComplete()
  80. });
  81. } else {
  82. this.store = new Store({
  83. wuid: this.Wuid,
  84. cluster: this.Cluster,
  85. name: this.Name,
  86. isComplete: true
  87. });
  88. }
  89. },
  90. getName: function () {
  91. return this.Name;
  92. },
  93. getID: function () {
  94. if (this.Sequence != null) {
  95. return this.Sequence;
  96. }
  97. return this.Name;
  98. },
  99. isComplete: function () {
  100. return this.Total != "-1";
  101. },
  102. canShowResults: function () {
  103. if (lang.exists("Sequence", this)) { // Regular WU result
  104. return true;
  105. } else if (lang.exists("RecordCount", this) && this.RecordCount != "") { // DFU Sprayed CSV File will fail here
  106. return true;
  107. }
  108. return false;
  109. },
  110. getFirstSchemaNode: function (node, name) {
  111. if (node && node.attributes) {
  112. if ((node.baseName && node.baseName == name) || (node.localName && node.localName == name) || (typeof (node.getAttribute) != "undefined" && node.getAttribute("name") == name)) {
  113. return node;
  114. }
  115. }
  116. for (var i = 0; i < node.childNodes.length; ++i) {
  117. var retVal = this.getFirstSchemaNode(node.childNodes[i], name);
  118. if (retVal) {
  119. return retVal;
  120. }
  121. }
  122. return null;
  123. },
  124. getFirstSequenceNode: function (schemaNode) {
  125. var row = this.getFirstSchemaNode(schemaNode, "Row");
  126. if (!row)
  127. return null;
  128. var complexType = this.getFirstSchemaNode(row, "complexType");
  129. if (!complexType)
  130. return null;
  131. return this.getFirstSchemaNode(complexType, "sequence");
  132. },
  133. rowToTable: function (cell) {
  134. var table = domConstruct.create("table", { border: 1, cellspacing: 0, width: "100%" });
  135. if (cell && cell.Row) {
  136. if (!cell.Row.length) {
  137. cell.Row = [cell.Row];
  138. }
  139. for (var i = 0; i < cell.Row.length; ++i) {
  140. if (i == 0) {
  141. var tr = domConstruct.create("tr", null, table);
  142. for (key in cell.Row[i]) {
  143. var th = domConstruct.create("th", { innerHTML: entities.encode(key) }, tr);
  144. }
  145. }
  146. var tr = domConstruct.create("tr", null, table);
  147. for (var key in cell.Row[i]) {
  148. if (cell.Row[i][key]) {
  149. if (cell.Row[i][key].Row) {
  150. var td = domConstruct.create("td", null, tr);
  151. td.appendChild(this.rowToTable(cell.Row[i][key]));
  152. } else {
  153. var td = domConstruct.create("td", { innerHTML: entities.encode(cell.Row[i][key]) }, tr);
  154. }
  155. } else {
  156. var td = domConstruct.create("td", { innerHTML: "" }, tr);
  157. }
  158. }
  159. }
  160. }
  161. return table;
  162. },
  163. getRowStructureFromSchema: function (parentNode, prefix) {
  164. var sequence = this.getFirstSequenceNode(parentNode, "sequence");
  165. if (!sequence)
  166. return null;
  167. var retVal = [];
  168. for (var i = 0; i < sequence.childNodes.length; ++i) {
  169. var node = sequence.childNodes[i];
  170. if (typeof (node.getAttribute) != "undefined") {
  171. var name = node.getAttribute("name");
  172. var type = node.getAttribute("type");
  173. var children = this.getRowStructureFromSchema(node, name + "_");
  174. if (name && type) {
  175. retVal.push({
  176. label: name,
  177. field: prefix + name,
  178. width: this.extractWidth(type, name) * 9,
  179. className: "resultGridCell",
  180. sortable: false
  181. });
  182. } else if (children) {
  183. var childWidth = 0;
  184. arrayUtil.forEach(children, function(item, idx) {
  185. childWidth += item.width;
  186. });
  187. /*
  188. retVal.push({
  189. label: name,
  190. children: children,
  191. width: childWidth,
  192. className: "resultGridCell",
  193. sortable: false
  194. });
  195. */
  196. var context = this;
  197. retVal.push({
  198. label: name,
  199. field: name,
  200. formatter: function (cell, row, grid) {
  201. var div = document.createElement("div");
  202. div.appendChild(context.rowToTable(cell));
  203. return div.innerHTML;
  204. },
  205. width: childWidth,
  206. className: "resultGridCell",
  207. sortable: false
  208. });
  209. }
  210. }
  211. }
  212. return retVal.length ? retVal : null;
  213. },
  214. getRowStructureFromData: function (rows) {
  215. var retVal = [];
  216. for (var key in rows[0]) {
  217. if (key != "myInjectedRowNum") {
  218. var context = this;
  219. retVal.push({
  220. label: key,
  221. field: key,
  222. formatter: function (cell, row, grid) {
  223. if (cell && cell.Row) {
  224. var div = document.createElement("div");
  225. div.appendChild(context.rowToTable(cell));
  226. return div.innerHTML;
  227. }
  228. return cell;
  229. },
  230. width: context.extractWidth("string12", key) * 9,
  231. className: "resultGridCell"
  232. });
  233. }
  234. }
  235. return retVal;
  236. },
  237. getStructure: function () {
  238. var structure = [
  239. {
  240. cells: [
  241. [
  242. {
  243. label: "##", field: this.store.idProperty, width: 54, className: "resultGridCell", sortable: false
  244. }
  245. ]
  246. ]
  247. }
  248. ];
  249. var dom = parser.parse(this.XmlSchema);
  250. var dataset = this.getFirstSchemaNode(dom, "Dataset");
  251. var innerStruct = this.getRowStructureFromSchema(dataset, "");
  252. for (var i = 0; i < innerStruct.length; ++i) {
  253. structure[0].cells[structure[0].cells.length - 1].push(innerStruct[i]);
  254. }
  255. return structure[0].cells[0];
  256. },
  257. fetchStructure: function (callback) {
  258. if (this.XmlSchema) {
  259. callback(this.getStructure());
  260. } else {
  261. var context = this;
  262. var request = {};
  263. if (this.Wuid && lang.exists("Sequence", this)) {
  264. request['Wuid'] = this.Wuid;
  265. request['Sequence'] = this.Sequence;
  266. } else if (this.Name) {
  267. request['LogicalName'] = this.Name;
  268. }
  269. request['Start'] = 0;
  270. request['Count'] = 1;
  271. WsWorkunits.WUResult({
  272. request: request,
  273. load: function (response) {
  274. if (lang.exists("WUResultResponse.Result", response)) {
  275. context.XmlSchema = "<Result>" + response.WUResultResponse.Result + "</Result>";
  276. callback(context.getStructure());
  277. }
  278. /*
  279. if (rows.length) {
  280. var innerStruct = context.getRowStructureFromData(rows);
  281. for (var i = 0; i < innerStruct.length; ++i) {
  282. structure[0].cells[structure[0].cells.length - 1].push(innerStruct[i]);
  283. }
  284. }
  285. */
  286. }
  287. });
  288. }
  289. },
  290. getRowWidth: function (parentNode) {
  291. var retVal = 0;
  292. var sequence = this.getFirstSequenceNode(parentNode, "sequence");
  293. if (!sequence)
  294. return retVal;
  295. for (var i = 0; i < sequence.childNodes.length; ++i) {
  296. var node = sequence.childNodes[i];
  297. if (typeof (node.getAttribute) != "undefined") {
  298. var name = node.getAttribute("name");
  299. var type = node.getAttribute("type");
  300. if (name && type) {
  301. retVal += this.extractWidth(type, name);
  302. } else if (node.hasChildNodes()) {
  303. retVal += this.getRowWidth(node);
  304. }
  305. }
  306. }
  307. return retVal;
  308. },
  309. extractWidth: function (type, name) {
  310. var retVal = -1;
  311. switch (type) {
  312. case "xs:boolean":
  313. retVal = 5;
  314. break;
  315. case "xs:integer":
  316. retVal = 8;
  317. break;
  318. case "xs:nonNegativeInteger":
  319. retVal = 8;
  320. break;
  321. case "xs:double":
  322. retVal = 8;
  323. break;
  324. case "xs:string":
  325. retVal = 32;
  326. break;
  327. default:
  328. var numStr = "0123456789";
  329. var underbarPos = type.lastIndexOf("_");
  330. var length = underbarPos > 0 ? underbarPos : type.length;
  331. var i = length - 1;
  332. for (; i >= 0; --i) {
  333. if (numStr.indexOf(type.charAt(i)) == -1)
  334. break;
  335. }
  336. if (i + 1 < length) {
  337. retVal = parseInt(type.substring(i + 1, length));
  338. }
  339. if (type.indexOf("data") == 0) {
  340. retVal *= 2;
  341. }
  342. break;
  343. }
  344. if (retVal < name.length)
  345. retVal = name.length;
  346. return retVal;
  347. },
  348. getStore: function () {
  349. return this.store;
  350. },
  351. getObjectStore: function () {
  352. return new ObjectStore({
  353. objectStore: this.store
  354. });
  355. },
  356. getLoadingMessage: function () {
  357. if (lang.exists("wu.state", this)) {
  358. return "<span class=\'dojoxGridWating\'>[" + this.wu.state + "]</span>";
  359. }
  360. return "<span class=\'dojoxGridWating\'>[unknown]</span>";
  361. },
  362. getECLRecord: function () {
  363. var retVal = "RECORD\n";
  364. for (var i = 0; i < this.ECLSchemas.ECLSchemaItem.length; ++i) {
  365. retVal += "\t" + this.ECLSchemas.ECLSchemaItem[i].ColumnType + "\t" + this.ECLSchemas.ECLSchemaItem[i].ColumnName + ";\n";
  366. }
  367. retVal += "END;\n";
  368. return retVal;
  369. }
  370. });
  371. return {
  372. CreateWUResultObjectStore: function (options) {
  373. var store = new Store(options);
  374. store = Observable(store);
  375. var objStore = new ObjectStore({ objectStore: store });
  376. return objStore;
  377. },
  378. Get: function (params) {
  379. return new Result(params);
  380. }
  381. }
  382. });