cvannotations.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752
  1. /*
  2. *+------------------------------------------------------------------------+
  3. *| Licensed Materials - Property of IBM
  4. *| IBM Cognos Products: Viewer
  5. *| (C) Copyright IBM Corp. 2001, 2013
  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. /**
  13. * CognosViewerAnnotation constructor (base class for all annotation rules)
  14. * @constructor
  15. */
  16. function CognosViewerAnnotation() {
  17. this.m_oCV = null;
  18. }
  19. /**
  20. * Sets the cognos viewer object (called by the action factory)
  21. * @param CCognosViewer object
  22. * @private
  23. */
  24. CognosViewerAnnotation.prototype.setCognosViewer = function(oCV) {
  25. this.m_oCV = oCV;
  26. };
  27. /**
  28. * Returns an instance to the cognos viewer object
  29. * @return CCognosViewer object
  30. */
  31. CognosViewerAnnotation.prototype.getCognosViewer = function() {
  32. return this.m_oCV;
  33. };
  34. /**
  35. * Override this function to determine whether or not the specific annotation
  36. * object is enabled.
  37. * @return boolean
  38. */
  39. CognosViewerAnnotation.prototype.isEnabled = function(placeType) {};
  40. CognosViewerAnnotation.prototype.areAnnotationsEnabled = function() {
  41. var widget = this.m_oCV.getViewerWidget();
  42. return widget.getAnnotationHelper().isEnabled();
  43. };
  44. /**
  45. * Override this function to get the base string name for the menu item
  46. * @return String
  47. */
  48. CognosViewerAnnotation.prototype.getMenuItemBaseString = function(){
  49. };
  50. /**
  51. * Override this function to get the icon class name for the menu item
  52. * @return String
  53. */
  54. CognosViewerAnnotation.prototype.getMenuItemIconClass = function(){
  55. };
  56. /**
  57. * Gets the current selections
  58. */
  59. CognosViewerAnnotation.prototype.getSelections = function(){
  60. var selections = [];
  61. var viewer = this.getCognosViewer();
  62. if (viewer) {
  63. var selCon = viewer.getSelectionController();
  64. if (selCon) {
  65. selections = selCon.getSelections();
  66. }
  67. }
  68. return selections;
  69. };
  70. /**
  71. * Check if the widget has any annotation
  72. * @return boolean
  73. */
  74. CognosViewerAnnotation.prototype.hasAnnotation = function(){
  75. var has = false;
  76. var viewer = this.getCognosViewer();
  77. if (viewer) {
  78. var widget = viewer.getViewerWidget();
  79. if (widget) {
  80. var store = widget.getAnnotationStore();
  81. if (store) {
  82. has = store.hasAnnotation();
  83. }
  84. }
  85. }
  86. return has;
  87. };
  88. function CognosViewerCellAnnotation(){}
  89. CognosViewerCellAnnotation.prototype = new CognosViewerAnnotation();
  90. /**
  91. * Concatenates the defult menu string with the selected object representation
  92. * @param defaultText - the default value when nothing is selected
  93. * @return String
  94. */
  95. CognosViewerCellAnnotation.prototype.getMenuItemString = function(defaultText){
  96. var selText = defaultText;
  97. var selections = this.getSelections();
  98. if (selections && selections.length == 1) {
  99. var sel = selections[0];
  100. selText = sel.getDisplayValues()[0];
  101. }
  102. var text = this.getMenuItemBaseString();
  103. if (selText && selText.length > 0) {
  104. text += " - " + enforceTextDir(selText);
  105. }
  106. return text;
  107. };
  108. /**
  109. * Return true if selected cell has any annotations
  110. * @return boolean
  111. */
  112. CognosViewerCellAnnotation.prototype.hasAnnotaionsOnSelectedCell = function(){
  113. var selections = this.getSelections();
  114. if (selections && selections.length == 1) {
  115. var cellRef = selections[0].getCellRef();
  116. var ctxId = this.getCognosViewer().findCtx(cellRef);
  117. var viewerWidget = this.getCognosViewer().getViewerWidget();
  118. if (viewerWidget) {
  119. var annotationStore = viewerWidget.getAnnotationStore();
  120. if (annotationStore) {
  121. var annotations = annotationStore.get(ctxId);
  122. if (annotations && annotations.length > 0) {
  123. return true;
  124. }
  125. }
  126. }
  127. }
  128. return false;
  129. };
  130. /**
  131. * Returns the changeable annotation for the current selection, or
  132. * null if there is no changeable annotation for the current selection.
  133. */
  134. CognosViewerCellAnnotation.prototype.getChangeableAnnotation = function(){
  135. var selections = this.getSelections();
  136. if (selections && selections.length == 1) {
  137. var cellRef = selections[0].getCellRef();
  138. var ctxId = this.getCognosViewer().findCtx(cellRef);
  139. var viewerWidget = this.getCognosViewer().getViewerWidget();
  140. if (viewerWidget) {
  141. var annotationStore = viewerWidget.getAnnotationStore();
  142. if (annotationStore) {
  143. return annotationStore.getChangeableAnnotation(ctxId);
  144. }
  145. }
  146. }
  147. return null;
  148. };
  149. CognosViewerCellAnnotation.prototype.hasValidContextOnSelectedCell = function() {
  150. var selections = this.getSelections();
  151. if (selections && selections.length == 1) {
  152. var cellRef = selections[0].getCellRef();
  153. var ctxId = this.getCognosViewer().findCtx(cellRef);
  154. if (ctxId) {
  155. var ids = AnnotationCTXLookup.generateIDArrayFromCellCtxValue(ctxId);
  156. for (var i = 0; i < ids.length; i++) {
  157. var id = ids[i];
  158. if(id !== "*" && !(/^\d+$/).test(id)) {
  159. return false;
  160. }
  161. }
  162. return true;
  163. }
  164. }
  165. return false;
  166. };
  167. /*
  168. * New Annotation - Adds a new annotation where none previously exists
  169. */
  170. function NewAnnotation() {}
  171. NewAnnotation.prototype = new CognosViewerCellAnnotation();
  172. /**
  173. * Return true if a cell is selected and the cell does not have new annotation already
  174. * @return boolean
  175. */
  176. NewAnnotation.prototype.isEnabled = function(placeType) {
  177. return this.areAnnotationsEnabled() && (placeType!=='widgetActions') && this.hasValidContextOnSelectedCell();
  178. };
  179. /**
  180. * Return 'Add comment'
  181. * @return String
  182. */
  183. NewAnnotation.prototype.getMenuItemBaseString = function(){
  184. return RV_RES.IDS_JS_ANNOTATION_NEW;
  185. };
  186. /**
  187. * Return 'NewAnnotation'
  188. * @return String
  189. */
  190. NewAnnotation.prototype.getMenuItemIconClass = function(){
  191. return 'NewAnnotation';
  192. };
  193. /*
  194. * Edit Annotation - Change the value of an annotation which previously existed
  195. */
  196. function EditAnnotation() {}
  197. EditAnnotation.prototype = new CognosViewerCellAnnotation();
  198. /**
  199. * Return true if selected cell has new annotation already
  200. * @return boolean
  201. */
  202. EditAnnotation.prototype.isEnabled = function(placeType) {
  203. return this.areAnnotationsEnabled() && (placeType!=='widgetActions') && this.getChangeableAnnotation() !== null;
  204. };
  205. /**
  206. * Return 'Edit comment*'
  207. * @return String
  208. */
  209. EditAnnotation.prototype.getMenuItemBaseString = function(){
  210. return RV_RES.IDS_JS_ANNOTATION_EDIT;
  211. };
  212. /**
  213. * Return 'EditAnnotation'
  214. * @return String
  215. */
  216. EditAnnotation.prototype.getMenuItemIconClass = function(){
  217. return 'EditAnnotation';
  218. };
  219. /*
  220. * Delete Annotation - Remove a previously existing annotation
  221. */
  222. function DeleteAnnotation() {}
  223. DeleteAnnotation.prototype = new CognosViewerCellAnnotation();
  224. DeleteAnnotation.prototype.isEnabled = function(placeType) {
  225. return this.areAnnotationsEnabled() && (placeType!=='widgetActions') && this.getChangeableAnnotation() !== null;
  226. };
  227. DeleteAnnotation.prototype.getMenuItemString = function(defaultText){
  228. return this.getMenuItemBaseString();
  229. };
  230. DeleteAnnotation.prototype.getMenuItemBaseString = function(){
  231. return RV_RES.IDS_JS_ANNOTATION_DELETE;
  232. };
  233. DeleteAnnotation.prototype.getMenuItemIconClass = function(){
  234. return 'DeleteAnnotation';
  235. };
  236. function CognosViewerWidgetAnnotation(){}
  237. CognosViewerWidgetAnnotation.prototype = new CognosViewerAnnotation();
  238. CognosViewerWidgetAnnotation.prototype.getMenuItemString = function(){
  239. var widgetText = this.getCognosViewer().getViewerWidget().getDisplayName();
  240. var text = this.getMenuItemBaseString();
  241. if (widgetText && widgetText.length > 0) {
  242. widgetText = enforceTextDir(widgetText);
  243. text += " - " + widgetText;
  244. }
  245. return text;
  246. };
  247. CognosViewerWidgetAnnotation.prototype.hasWidgetLevelAnnotations = function(){
  248. var hasAnnotations = false;
  249. var viewerWidget = this.getCognosViewer().getViewerWidget();
  250. if (viewerWidget) {
  251. var annotationStore = viewerWidget.getAnnotationStore();
  252. var widgetAnnotations = annotationStore.get(annotationStore.WIDGET_CONTEXT);
  253. if (widgetAnnotations && widgetAnnotations.length > 0) {
  254. hasAnnotations = true;
  255. }
  256. }
  257. return hasAnnotations;
  258. };
  259. CognosViewerWidgetAnnotation.prototype.getWidgetLevelChangeableAnnotation = function(){
  260. var viewerWidget = this.getCognosViewer().getViewerWidget();
  261. if (viewerWidget) {
  262. var annotationStore = viewerWidget.getAnnotationStore();
  263. if (annotationStore) {
  264. return annotationStore.getChangeableAnnotation(annotationStore.WIDGET_CONTEXT);
  265. }
  266. }
  267. return null;
  268. };
  269. /*
  270. * Currently we allow widget annotations of the selection count is not 1
  271. */
  272. CognosViewerWidgetAnnotation.prototype.hasValidSelection = function(placeType) {
  273. var selectionController = this.m_oCV.getSelectionController();
  274. var selections = selectionController.getSelections();
  275. var chartItemSelected = false;
  276. if(selectionController.hasSelectedChartNodes()) {
  277. chartItemSelected = (selectionController.getSelectedChartNodes()[0].m_contextIds.length > 0);
  278. }
  279. return (placeType==='widgetActions') || (selections.length != 1 && !chartItemSelected);
  280. };
  281. /*
  282. * New Widget Annotation - Adds a new annotation to the widget where none previously existed
  283. */
  284. function NewWidgetAnnotation() {}
  285. NewWidgetAnnotation.prototype = new CognosViewerWidgetAnnotation();
  286. /**
  287. * Return true if there is no new annotation on widget level and cell is not selected
  288. * @return boolean
  289. */
  290. NewWidgetAnnotation.prototype.isEnabled = function(placeType) {
  291. return this.areAnnotationsEnabled() && (placeType!=='contextMenu') && this.hasValidSelection(placeType);
  292. };
  293. /**
  294. * Return'Add comment'
  295. * @return String
  296. */
  297. NewWidgetAnnotation.prototype.getMenuItemBaseString = function(){
  298. return RV_RES.IDS_JS_WIDGET_ANNOTATION_NEW;
  299. };
  300. /**
  301. * Return 'NewWidgetAnnotation'
  302. * @return String
  303. */
  304. NewWidgetAnnotation.prototype.getMenuItemIconClass = function(){
  305. return 'NewWidgetAnnotation';
  306. };
  307. /*
  308. * Edit Widget Annotation - Change the value of an annotation which previously existed on the widget
  309. */
  310. function EditWidgetAnnotation() {}
  311. EditWidgetAnnotation.prototype = new CognosViewerWidgetAnnotation();
  312. /**
  313. * Return true if there is new annotation on widget level and cell is not selected
  314. * @return boolean
  315. */
  316. EditWidgetAnnotation.prototype.isEnabled = function(placeType) {
  317. return (this.areAnnotationsEnabled() &&(placeType!=='contextMenu') && this.hasValidSelection(placeType) && this.getWidgetLevelChangeableAnnotation()) ? true : false;
  318. };
  319. /**
  320. * Return 'Edit comment*'
  321. * @return String
  322. */
  323. EditWidgetAnnotation.prototype.getMenuItemBaseString = function(){
  324. return RV_RES.IDS_JS_WIDGET_ANNOTATION_EDIT;
  325. };
  326. EditWidgetAnnotation.prototype.getMenuItemIconClass = function(){
  327. return 'EditWidgetAnnotation';
  328. };
  329. /*
  330. * Delete Widget Annotation - Remove previously existing annotations from the widget
  331. */
  332. function DeleteWidgetAnnotation() {}
  333. DeleteWidgetAnnotation.prototype = new CognosViewerWidgetAnnotation();
  334. DeleteWidgetAnnotation.prototype.isEnabled = function(placeType) {
  335. return (this.areAnnotationsEnabled() &&(placeType!=='contextMenu') && this.hasValidSelection(placeType) && this.getWidgetLevelChangeableAnnotation()) ? true : false;
  336. }
  337. DeleteWidgetAnnotation.prototype.getMenuItemBaseString = function(){
  338. return RV_RES.IDS_JS_WIDGET_ANNOTATION_DELETE;
  339. };
  340. DeleteWidgetAnnotation.prototype.getMenuItemIconClass = function(){
  341. return 'DeleteWidgetAnnotation';
  342. };
  343. /**
  344. * AnnotationCTXLookup
  345. * @constructor
  346. */
  347. function AnnotationCTXLookup(ccdManager) {
  348. this.m_ccdManager = ccdManager;
  349. this.m_md = this.m_ccdManager.m_md;
  350. this.m_cd = this.m_ccdManager.m_cd;
  351. this.m_RDIVALUE_KEY = 'annotationHook';
  352. this.m_oContextDetailsMap = {};
  353. }
  354. /**
  355. * Populate a map which relates each individual context ID referenced in the annotation array to their backing details (like rdi, modelItem, usage)
  356. * @param annotationArray array
  357. * @public
  358. */
  359. AnnotationCTXLookup.prototype.populateCtxDetailsForAllAnnotations = function(annotationArray) {
  360. for (var i = 0, len = annotationArray.length; i < len; i++) {
  361. var anno = annotationArray[i];
  362. var ctx = anno.ctx;
  363. if (ctx) {
  364. this._populateCtxDetailsForOneCtxValue(ctx);
  365. }
  366. }
  367. };
  368. /**
  369. * Extracts Ids from ctxValue string, go through each id, and populate ctx detail
  370. * @param ctxValue string Examples: 1, *, 1:2:3, 4::5::6, *::2:3::5:8, and so on
  371. * @private
  372. */
  373. AnnotationCTXLookup.prototype._populateCtxDetailsForOneCtxValue = function(ctxValue) {
  374. if(ctxValue) {
  375. var ctxIDs = this.generateIDArrayFromCellCtxValue(ctxValue);
  376. for (var i = 0, len = ctxIDs.length; i < len; i++) {
  377. var id = ctxIDs[i];
  378. this._populateCtxDetailsForOneId(id);
  379. }
  380. }
  381. };
  382. /**
  383. * Generates string array of ctx Ids which appears in ctxValue string.
  384. * @param ctxValue string Examples: 1, *, 1:2:3, 4::5::6, *::2:3::5:8, and so on
  385. * @private
  386. */
  387. AnnotationCTXLookup.generateIDArrayFromCellCtxValue = function(ctxValue) {
  388. if (ctxValue) {
  389. return ctxValue.replace(/::/g, ':').split(':');
  390. }
  391. return null;
  392. };
  393. AnnotationCTXLookup.prototype.generateIDArrayFromCellCtxValue = AnnotationCTXLookup.generateIDArrayFromCellCtxValue;
  394. /**
  395. * Populates ctx detail of id passed if it is numeric value
  396. * @param id string - numeric value or '*'
  397. * @private
  398. */
  399. AnnotationCTXLookup.prototype._populateCtxDetailsForOneId = function(id) {
  400. if (id.match(/\*/)) {
  401. return;
  402. }
  403. //check if exists
  404. var detail = this.m_oContextDetailsMap[id];
  405. if(detail) {
  406. return; //already populated, just return.
  407. } else {
  408. detail = {};
  409. var contextData = this.m_cd[id];
  410. if(contextData) {
  411. if (contextData.u) { detail['u'] = contextData.u; }
  412. if (contextData.r) {
  413. detail['r'] = contextData.r;
  414. var metadata = this.m_md[contextData.r];
  415. if(metadata) {
  416. if (metadata.usage!== 'undefined') {
  417. detail['usage'] = metadata.usage;
  418. }
  419. if (metadata.dtype) {
  420. detail.dtype = metadata.dtype;
  421. }
  422. }
  423. }
  424. this._populateRdiValueInDetail(detail, id);
  425. this.m_oContextDetailsMap[id] = detail;
  426. }
  427. }
  428. };
  429. /*
  430. * Utility function to index into the metadata. Return null if key(s) do not exist.
  431. * key1 indexes into the provided context data to find the metadata entries,
  432. * and key2 indexes to pull out one of those entries.
  433. * key1 and key2 are often the same value, so if key2 is omitted, it is assumed to
  434. * be key1.
  435. * For examples of keys, see the context data and metadata in Viewer.
  436. */
  437. AnnotationCTXLookup.prototype._getMDValue = function(item, key1, key2) {
  438. if(typeof key2 == 'undefined') {
  439. //It is a common operation to use the same key twice
  440. key2 = key1;
  441. }
  442. if (typeof item[key1] != 'undefined' && typeof this.m_md[item[key1]][key2] != 'undefined') {
  443. return this.m_md[item[key1]][key2];
  444. }
  445. return null;
  446. };
  447. /*
  448. * Given a set of keys, where each key may provide a meaningful value in the
  449. * metadata, iterate through them until one does indeed provide a meaningful
  450. * value.
  451. */
  452. AnnotationCTXLookup.prototype._findMDValue = function(item, aKeys) {
  453. //Iterate over keys in order of descending precedence.
  454. for(var i = 0; i < aKeys.length; i++) {
  455. var value = this._getMDValue(item, aKeys[i]);
  456. if(value !== null) {
  457. return value;
  458. }
  459. }
  460. return null;
  461. };
  462. /**
  463. * Populates RdiValue value which annotation service would select for ctx id to detail object
  464. * @param id string - numeric value or '*'
  465. * @private
  466. */
  467. AnnotationCTXLookup.prototype._populateRdiValueInDetail = function(detail, id) {
  468. var item = this.m_cd[id];
  469. var aKeys = [];
  470. var oRdi = {};
  471. //Version 1 annotations don't differentiate between measures and non-measures
  472. oRdi[1] = this._findMDValue(item, ["l", "h", "i", "r"]);
  473. //Version 2 annotation differentiate depending on whether the value is a measure or not
  474. if (this._getMDValue(item, "r", "usage") == 2) {
  475. //Measure
  476. oRdi[2] = this._findMDValue(item, ["i", "m", "r"]);
  477. }
  478. detail[this.m_RDIVALUE_KEY] = oRdi;
  479. };
  480. /**
  481. * Returns ctx detail by id
  482. * @param id string
  483. * @private
  484. */
  485. AnnotationCTXLookup.prototype.getDetail = function(id) {
  486. if (!id) {
  487. return null;
  488. }
  489. return this.m_oContextDetailsMap[id];
  490. };
  491. /**
  492. * Returns true if id and annoFirstId is same numeric value.
  493. * Returns true if rdi-value of id's ctx detail is same as annoRDI when annoFirstId is '*'.
  494. * @param annoFirstId string - numeric value or '*'
  495. * @param annoRDI string
  496. * @param id string
  497. * @private
  498. */
  499. AnnotationCTXLookup.prototype.isAnnotatedId = function(annoFirstId, annotation, id) {
  500. if (!annoFirstId || !id) {
  501. return false;
  502. }
  503. if (annoFirstId.match(/\*/)) {
  504. var detail = this.getDetail(id);
  505. if (detail && detail[this.m_RDIVALUE_KEY]) {
  506. var rdi = detail[this.m_RDIVALUE_KEY][1];
  507. if(annotation.version >= 2 && detail[this.m_RDIVALUE_KEY][2]) {
  508. //Look for version 2 RDI value only if this annotation is
  509. //version 2 (as specified by CCS) AND the version 2 RDI value
  510. //is different than the version 1 RDI value.
  511. rdi = detail[this.m_RDIVALUE_KEY][2];
  512. }
  513. return this._compareWithoutNS(annotation.rdi, rdi);
  514. } else {
  515. return false;
  516. }
  517. } else {
  518. return annoFirstId === id;
  519. }
  520. };
  521. AnnotationCTXLookup.prototype._compareWithoutNS = function(rdi1, rdi2){
  522. if(!rdi1 || !rdi2){
  523. return false;
  524. }
  525. if(rdi1 !== rdi2){
  526. var iDotPos = rdi2.indexOf("].[");
  527. if(iDotPos > 0){
  528. return rdi1.lastIndexOf(rdi2.substr(iDotPos))>0;
  529. }
  530. return false;
  531. }
  532. return true;
  533. };
  534. /**
  535. * Checks if cellCtxValue matches with annoatation's ctx and rdi.
  536. * The following is detail logic of the decision
  537. * - extracts Ids from cellCtxValue and annotation.ctx
  538. * - calls isAnnotatedId with first id of ctx and first id of cellCtxValue
  539. * - if not, cellCtxValue is not for this annotation. returns false
  540. * - next, compares data (i.e: usage is 0 or 1) item Ids
  541. * - if annotation ctx has more data item than cellCtxValue's,
  542. * it means the cellCtxValue does not have enough data items.
  543. * returns false.
  544. * - Finally, checks all of annotation ctx's data item Ids is present as cellCtxValue's data item.
  545. * then returns true.
  546. * - or, returns false.
  547. *
  548. *
  549. * @param annotation object
  550. * @param cellCtxValue string
  551. * @private
  552. */
  553. AnnotationCTXLookup.prototype.isAnnotatedCell = function(annotation, cellCtxValue) {
  554. if (!annotation || !annotation.ctx || !cellCtxValue) {
  555. return false;
  556. }
  557. this._populateCtxDetailsForOneCtxValue(cellCtxValue);
  558. var annoIDArray = this.generateIDArrayFromCellCtxValue(annotation.ctx);
  559. var cellIDArray = this.generateIDArrayFromCellCtxValue(cellCtxValue);
  560. //Compare first IDs
  561. if( !this.isAnnotatedId(annoIDArray[0], annotation, cellIDArray[0]) ) {
  562. return false;
  563. }
  564. //Compare data (i.e: usage is 0 or 2. means not a measure/calculation) item IDs
  565. var annoDataItemIdArray = this._generateDataItemIDArrayFromAnnotationIDs(annoIDArray);
  566. var cellDataItemIdArray = this._generateDataItemIDArrayFromCellIDs(cellIDArray);
  567. if ( annoDataItemIdArray.length > cellDataItemIdArray.length) {
  568. return false;
  569. }
  570. for (var i=0, len=annoDataItemIdArray.length; i<len; i++) {
  571. for(var j=0, jLen=cellDataItemIdArray.length; j<jLen; j++) {
  572. if (annoDataItemIdArray[i] === cellDataItemIdArray[j] ) {
  573. annoDataItemIdArray[i] = true;
  574. cellDataItemIdArray[j] = true;
  575. break;
  576. }
  577. }
  578. }
  579. for (i = 0, len = annoDataItemIdArray.length; i < len; i++) {
  580. if (annoDataItemIdArray[i] !== true) {
  581. return false;
  582. }
  583. }
  584. for (i = 0, len = cellDataItemIdArray.length; i < len; i++) {
  585. if (cellDataItemIdArray[i] !== true) {
  586. return false;
  587. }
  588. }
  589. return true;
  590. };
  591. /**
  592. * Generates array of Ids where id is a data item (not a measure/calculation).
  593. * To be a data item, 'usage' in ctx detail of id must be 0 or 1
  594. *
  595. * @param cellIDArray Array
  596. * @private
  597. */
  598. AnnotationCTXLookup.prototype._generateDataItemIDArrayFromCellIDs = function(cellIDArray) {
  599. var dataItemIDs = [];
  600. for(var i=1, len=cellIDArray.length; i<len; i++){
  601. var id = cellIDArray[i];
  602. var detail = this.getDetail(id);
  603. if( this._isDataItem(detail) ) {
  604. dataItemIDs.splice(0,0, id);
  605. }
  606. }
  607. return dataItemIDs;
  608. };
  609. // The list of these dtypes came from CMS. Added for defect 12126
  610. AnnotationCTXLookup.dtypeLookup = {"1" : true,"25" : true,"26" : true,"27" : true,"28" : true,"29" : true,"30" : true,"31" : true,"32" : true,"34" : true,"35" : true,"36" : true,"43" : true,"45" : true,"55" : true,"56" : true};
  611. AnnotationCTXLookup.prototype._isDataItem = function(detail) {
  612. if (detail) {
  613. var usage = detail.usage;
  614. var dtype = detail.dtype;
  615. if (usage === 0 || usage === 1 || (usage === 3 && AnnotationCTXLookup.dtypeLookup[dtype] === true)) {
  616. return true;
  617. }
  618. }
  619. return false;
  620. };
  621. /**
  622. * Generates array of Ids where id is not '*'
  623. *
  624. * @param annoIDArray Array
  625. * @private
  626. */
  627. AnnotationCTXLookup.prototype._generateDataItemIDArrayFromAnnotationIDs = function(annoIDArray) {
  628. var dataItemIDs = [];
  629. for(var i=1, len=annoIDArray.length; i<len; i++){
  630. var id = annoIDArray[i];
  631. if (id.match(/\*/) === null) {
  632. dataItemIDs.splice(0,0, id);
  633. }
  634. }
  635. return dataItemIDs;
  636. };