// Licensed Materials - Property of IBM // // IBM Cognos Products: pps // // (C) Copyright IBM Corp. 2005, 2017 // // US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. /***********************************/ /* Dim cache */ function dimensionCache() { var dimensions = new Array(); var topCategories = new Array(); var requestQueue = new Array(); var outstandingRequest = false; var numEnqueueRequests = 0; //Public methods this.addDimension = function(code, categoryName, fullCategoryName, ppdsId, nonselectable) { var dimIdx = dimensions.length; dimensions[dimIdx] = new Array(); topCategories[dimIdx] = new catNode(code, categoryName, fullCategoryName, dimIdx, ppdsId, false, false, false, nonselectable, false); dimensions[dimIdx][code] = topCategories[dimIdx]; } this.getDimTopNode = function(dim) { return topCategories[dim]; } this.addCategory = function(dim, catNode) { if (dimensions[dim] && !dimensions[dim][catNode.getCode()]) dimensions[dim][catNode.getCode()] = catNode; } this.removeCategory = function(dim, catNode) { if (dimensions[dim] && dimensions[dim][catNode.getCode()]) { //remove the reference from each parent var parents = catNode.getParents(); for (var i = 0; i < parents.length; i++) { dimensions[dim][parents[i]].removeChild(catNode.getCode()); } var children = catNode.getChildren(); for (var i = 0; i < children.length; i++) { dimensions[dim][children[i]].removeParent(catNode.getCode()); } dimensions[dim][catNode.getCode()] = null; } } this.getCategory = function(dim, catCode) { if (!dimensions[dim] && (topCategories[dim].getCode() != catCode)) { return null; } return dimensions[dim][catCode]; } this.createCategory = function(dim, catCode, catName, fullCatName, ppdsId, alternate, isLeaf, calculated, nonselectable, customSubset) { if (dimensions[dim] && !dimensions[dim][catCode]) { dimensions[dim][catCode] = new catNode(catCode, catName, fullCatName, dim, ppdsId, alternate, isLeaf, calculated, nonselectable, customSubset); } return dimensions[dim][catCode]; } //Request handling routines //since the requests are recieved in a browser frame, and a frame will only allow //1 request to be recieved at a time, we have to maintain a queue of requests to //ensure that we send any subsequent requests that were (requested) during the //processing of a request, when the frame becomes available. this.sendRequest = function(request) { pushRequest(request); if (!outstandingRequest) { sendNextRequest(); outstandingRequest = true; } } this.requestFinished = function() { if (numEnqueueRequests) { sendNextRequest(); } else { outstandingRequest = false; } } function pushRequest(request) { requestQueue[numEnqueueRequests] = request; numEnqueueRequests++; } function popRequest() { var request = requestQueue[numEnqueueRequests - 1]; numEnqueueRequests--; return request; } function sendNextRequest(request) { var hf = getXtabFrame().document.getElementById("fhidden"); var target = hf.target; var cnct = hf.CNCT.value; hf.CNCT.value = 16; hf.RA.value = 999; hf.CO.value = popRequest(); hf.target = getDimCacheFrame().name; hf.submit(); hf.target = target; hf.CO.value = ""; hf.CNCT.value = cnct; } this.isLoading = function() { return outstandingRequest; } } function catNode(code, categoryName, fullCategoryName, dimIdx, ppdsId, alternate, isLeaf, calculated, nonselectable, customSubset, measurePlaceholder) { //Constructor var _code = code; var _categoryName = categoryName; var _fullName = fullCategoryName; var _dimIdx = dimIdx; var _ppdsId = ppdsId; var children = new Array(); var allChildrenLoaded = false; var allNonCustomSubsetsLoaded = false; var _alternate = alternate; var _customSubset = customSubset; var _isLeaf = isLeaf; var parents = new Array(); var allParentsLoaded = false; var loading = false; var _calculated = calculated; var _nonselectable = nonselectable; var _measurePlaceholder = measurePlaceholder; //Public Methods this.getCode = function() { return _code; } this.getLabel = function() { return _categoryName; } this.setLabel = function(label) { _categoryName = label; } this.getFullName = function() { return _fullName; } this.getDimension = function() { return _dimIdx; } this.getPPDSID = function() { return _ppdsId; } this.isLeaf = function() { return _isLeaf; } this.setIsLeaf = function(isLeaf) { _isLeaf = isLeaf; } this.isCalculated = function() { return _calculated; } this.isNonSelectable = function() { return _nonselectable; } this.isTopNode = isTopNode; this.isAlternateParent = function() { return _alternate; } this.isCustomSubset = function() { return _customSubset; } this.isMeasurePlaceholder = function() { return _measurePlaceholder; } this.childrenLoaded = function(firstItem) { return childrenLoaded(firstItem); } this.getNumChildrenLoaded = function() { return children.length; } this.allChildrenLoaded = function() { return allChildrenLoaded; } this.allNonCustomSubsetsLoaded = function() { return allNonCustomSubsetsLoaded; } this.ancestorsLoaded = ancestorsLoaded; this.isLoading = function() { return loading; } this.allLoaded = function() { return (!loading && childrenLoaded() && siblingsLoaded() && ancestorsLoaded()); } this.loadChildren = function() { if (!loading && !childrenLoaded(children.length)) loadData(true,false,false); } this.clearChildren = function() { children = new Array(); allChildrenLoaded = false; allNonCustomSubsetsLoaded = false; } this.getChildren = function() { return children; } this.removeChild = function(childCode) { var idx = 0; while (idx < children.length && children[idx] != childCode) idx++; if (idx < children.length) children.splice(idx,1); } this.loadAllRelated = function() { if (!loading) loadData(!childrenLoaded(),!siblingsLoaded(),!ancestorsLoaded()); } this.loadParents = function() { if (!parentsLoaded() && !loading) loadData(false,false,true); } this.getParents = function() { return parents; } this.getParent = function() { return parents[0]; } this.removeParent = function(parentCode) { var idx = 0; while (idx < parents.length && parents[idx] != parentCode) idx++; if (idx < parents.length) parents.splice(idx,1); } this.getSiblings = function() { if (isTopNode()) { //If we are the top node, we are the only sibling. var siblings = new Array(); siblings[0] = this; return siblings; } else if (siblingsLoaded()) { return dimCache.getCategory(_dimIdx, parents[0]).getChildren(); } else { return null; } } this.setDirectParent = function(parent) { parents[0] = parent; } this.storeParents = storeParents; this.storeFirstChildren = function(nodeChildren) { if (nodeChildren.length > children.length) { nodeChildren = nodeChildren.splice(children.length,nodeChildren.length - children.length); storeChildren(nodeChildren); } } this.setMoreChildren = function() { if (allChildrenLoaded) { allChildrenLoaded = false; } } this.findHierarchyRoot = function() { var catNode = dimCache.getCategory(_dimIdx, _code); //Get this node while (!catNode.isAlternateParent() && !catNode.isTopNode()) catNode = dimCache.getCategory(_dimIdx, catNode.getParent()); return catNode.getCode(); } //Private Methods //These methods try and determine (To the best of their knowledge) properties //about the node. function isTopNode() { return (dimCache.getDimTopNode(_dimIdx).getPPDSID() == _ppdsId); } function parentsLoaded() { return (isTopNode() || allParentsLoaded); } function ancestorsLoaded() { return (isTopNode() || (parentsLoaded() && dimCache.getCategory(_dimIdx, parents[0]).ancestorsLoaded())); } function childrenLoaded(firstChild) { if (!firstChild) firstChild = 0; if (_isLeaf) return true; else { return (allChildrenLoaded || (firstChild + parseInt(getGlobal("childLimit"))) <= children.length); } } function siblingsLoaded() { return (isTopNode() || (parentsLoaded() && dimCache.getCategory(_dimIdx, parents[0]).childrenLoaded(0))); } function loadData(getChildren, getSiblings, getParents) { if (!getChildren && !getSiblings && !getParents) { return; } loading = true; var nextToLoad = 0; if (!getSiblings) nextToLoad = children.length; submitRequest(_ppdsId, _dimIdx, _code, nextToLoad, getChildren, getSiblings, getParents); } this.storeData = function() { var results = getDimCacheFrame(); var children = results.children; var siblings = results.siblings; var parents = results.parents1; //Store children first if (children) storeChildren(children); //Store Parents next if (parents) storeParents("parents", 1); //Store Siblings last if (siblings) storeSiblings(siblings); loading = false; } function storeChildren(nodeChildren) { var limitHit = false; var i = 0; var customSubset = false; for (var i = 0; i < nodeChildren.length; i++) { var limitHit; if(typeof nodeChildren[i]["limit"] != "undefined") limitHit = nodeChildren[i]["limit"]; allNonCustomSubsetsLoaded = (nodeChildren[i]["all_non_cs_loaded"] != null); if (!limitHit) { var child = dimCache.getCategory(_dimIdx, nodeChildren[i]["code"]); if (!child) { var alternate = (nodeChildren[i]["alternate"] != null); var leaf = (nodeChildren[i]["src"] == null); var calculated = (nodeChildren[i]["calculated"] != null); var nonselectable = (nodeChildren[i]["nonselectable"] != null); customSubset = (nodeChildren[i]["custom_subset"] != null); var measurePlaceholder = (nodeChildren[i]["measure_placeholder"] != null); child = new catNode(nodeChildren[i]["code"], nodeChildren[i]["name"], nodeChildren[i]["tag"], _dimIdx, nodeChildren[i]["id"], alternate, leaf, calculated, nonselectable, customSubset, measurePlaceholder); dimCache.addCategory(_dimIdx, child); } var parent = dimCache.getCategory(_dimIdx, child.getParent()); if (!parent || parent.isAlternateParent()) child.setDirectParent(_code); children[children.length] = child.getCode(); } else { setGlobal("childLimit",limitHit); } } if (customSubset) allNonCustomSubsetsLoaded = true; if (!limitHit) { //We reached the end allChildrenLoaded = true; allNonCustomSubsetsLoaded = true; } } function storeParents(sParents, level) { var nodeParents = eval("getDimCacheFrame()." + sParents + level); for (var i = 0; i < nodeParents.length; i++) { var parent = dimCache.getCategory(_dimIdx, nodeParents[i]["code"]); if (!parent) { var alternate = (nodeParents[i]["alternate"] != null); var nonselectable = (nodeParents[i]["nonselectable"] != null); var customSubset = (nodeParents[i]["custom_subset"] != null); var measurePlaceholder = (nodeParents[i]["measure_placeholder"] != null); parent = new catNode(nodeParents[i]["code"], nodeParents[i]["name"], nodeParents[i]["tag"], _dimIdx, nodeParents[i]["id"], alternate, false, false, nonselectable, customSubset, measurePlaceholder); dimCache.addCategory(_dimIdx, parent); } parents[i] = parent.getCode(); var nextLevel = eval("getDimCacheFrame()." + sParents + (level+1)); if (nextLevel) parent.storeParents(sParents, level+1); allParentsLoaded = true; } } function storeSiblings(nodeSiblings) { dimCache.getCategory(_dimIdx, parents[0]).storeFirstChildren(nodeSiblings); } function submitRequest(ppdsId, dimIdx, code, startIndex, getchildren, getSiblings, getParents) { if (!startIndex) startIndex = 0; var cmd = 'N:' + ppdsId; cmd += "," + dimIdx + "," + code + "\t" + (getchildren? "1" : "0") + "\t" + (getSiblings? "1" : "0") + "\t" + (getParents? "1" : "0") + "\t" + startIndex; dimCache.sendRequest(cmd); } }