/********************************************************************************************************************************
* Licensed Materials - Property of IBM *
* *
* IBM Cognos Products: AGS *
* *
* (C) Copyright IBM Corp. 2005, 2021 *
* *
* US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. *
*********************************************************************************************************************************/
/* ****************************************
TO DO - TO DO - TO DO - TO DO - TO DO - TO DO - TO DO
- getFolderChild() instead of _.ref+"_Child"
**************************************** */
var agentItemsTree = null;
var agentParameterTree = null;
function initDataItems()
{
if (agentItemsTree == null)
{
if (browserCheck.isNav6Up())
{
document.getElementById("agentItemsTreeContainer").addEventListener("mouseup", function(e) {if(e.target.toString().indexOf("XULElement") > -1){e.cancelBubble = true;return false;}}, true);
document.getElementById("agentItemsTreeContainer").addEventListener("dragover", function(e) {cancelBub(e);}, true);
document.getElementById("agentItemsTreeContainer").addEventListener("dragdrop", function(e) {cancelBub(e);}, true);
}
var agentItemsTreeNode = document.getElementById("agentItemsTreeContainer");
// at this point - this is the only node with this id
agentItemsTreeNode.setAttribute("container", "true");
agentItemsTreeNode.setAttribute("tabindex", "-1");
// now create and render the tree
agentItemsTree = new CTree (agentItemsTreeNode, "", false, true, "agentItemsTree");
agentItemsTree.setSelectionMode(CONTIGUOUS_TREE_SELECTION);
agentItemsTree.setSelectTreeUI(NORMAL_TREE);
agentItemsTree.setAllowDragDrop(true);
agentItemsTree.setOnDragStart(onDragStartF);
agentItemsTree.setOnDrag(onDragF);
agentItemsTree.setOnDragEnd(onDragEndF);
agentItemsTree.setContextMenu(showContextMenu);
agentItemsTree.setTrackSelectionOrder(true);
agentItemsTree.setDoubleClickFunc(processDoubleClick);
agentItemsTree.setSingleClickFunc(singleClickedDataItemsTree);
agentItemsTree.setHideOuterTable(true);
agentItemsTree.setAllowSelectionToggle(true);
// define the root of the tree
agentItemsTree.getRootNode().setName(agentItemsRoot_string);
agentItemsTree.getRootNode().setCanHaveChildren(true);
agentItemsTree.setRootNodeType(tntAgentRoot);
agentItemsTree.drawAll();
agentItemsTree.checkData();
}
}
function initParameterItems()
{
if (agentParameterTree == null)
{
if (browserCheck.isNav6Up())
{
document.getElementById("agentParameterTreeContainer").addEventListener("mouseup", function(e) {if(e.target.toString().indexOf("XULElement") > -1){e.cancelBubble = true;return false;}}, true);
document.getElementById("agentParameterTreeContainer").addEventListener("dragover", function(e) {e.preventBubble();}, true);
document.getElementById("agentParameterTreeContainer").addEventListener("dragdrop", function(e) {e.preventBubble();}, true);
}
var agentParameterTreeNode = document.getElementById("agentParameterTreeContainer");
// at this point - this is the only node with this id
agentParameterTreeNode.setAttribute("container", "true");
agentParameterTreeNode.setAttribute("tabindex", "-1");
// now create and render the tree
agentParameterTree = new CTree (agentParameterTreeNode, "", false, true, "agentParameterTree");
agentParameterTree.setSelectionMode(CONTIGUOUS_TREE_SELECTION);
agentParameterTree.setSelectTreeUI(NORMAL_TREE);
agentParameterTree.setAllowDragDrop(true);
agentParameterTree.setOnDragStart(onDragStartF);
agentParameterTree.setOnDrag(onDragF);
agentParameterTree.setOnDragEnd(onDragEndF);
agentParameterTree.setContextMenu(showContextMenu);
agentParameterTree.setTrackSelectionOrder(true);
agentParameterTree.setDoubleClickFunc(processDoubleClick);
agentParameterTree.setSingleClickFunc(singleClickedParametersTree);
agentParameterTree.setHideOuterTable(true);
agentParameterTree.setAllowSelectionToggle(true);
// define the root of the tree
agentParameterTree.getRootNode().setName(agentItemsParameters_string);
agentParameterTree.getRootNode().setCanHaveChildren(true);
agentParameterTree.setRootNodeType(tntAgentRoot);
agentParameterTree.drawAll();
agentParameterTree.checkData();
}
}
function processDoubleClick(){
addSelectedDblClick();
}
function singleClickedDataItemsTree() {
parent.deletionCandidateManager.setCandidate("deleteAgentItems()",K_sFunctionCandidate);
}
function singleClickedParametersTree(){
parent.deletionCandidateManager.setCandidate("deleteParameters()",K_sFunctionCandidate);
}
function resetAgentItems()
{
resetDataItems();
resetParameterItems();
}
function resetDataItems()
{
if (agentItemsTree != null) {
// we have to remove the tree
agentItemsTree = null;
// remove the rendering of the tree
removeTreeRendering("agentItemsTreeContainer");
}
// re-init the agent Items tree
initDataItems();
}
function resetParameterItems()
{
if (agentParameterTree != null) {
// we have to remove the tree
agentParameterTree = null;
// remove the rendering of the tree
removeTreeRendering("agentParameterTreeContainer");
}
// re-init the agent Items tree
initParameterItems();
}
/*
* Delete selected agent parameters from the tree
*/
function deleteParameters() {
if(confirm(parameterDeleteWarning)) {
deleteFromTree(getParametersTree());
}
}
/*
* Delete selected agent items from the tree
*/
function deleteAgentItems()
{
if(confirm(agentItemsDeleteWarning)) {
deleteFromTree(getDataItemsTree());
}
}
function deleteDataItem(dataItemDropValue,undo) {
var tree = getDataItemsTree();
var deleteNode = getNodeFromTreeWithValue(dataItemDropValue,'getDropValue()',getTreeChildNodes(tree));
return deleteDataItemNode(deleteNode,undo);
}
function deleteDataItemNode(deleteNode,undo) {
var tree = getDataItemsTree();
if (deleteNode) {
deleteNode.detach();
//redraw the parent
redrawTreeNode(tree.getRootNode(),false);
if(!undo){
//store the ref obj in case we need to undo the delete
getRedoUndoManager().getActionHistory().push(new DeleteItemEditAction(deleteNode));
}
parent.deletionCandidateManager.clearCandidate();
}
return deleteNode;
}
function redrawTreeNode(node,isSelected){
//UnSelect all.
node.getTree().deSelectAll();
//This doing it the ahrd way to update the name.
//redraw the whole caboudle
node.getTree().drawAll();
if (isSelected) {
//Now we set it to selected
node.setSelected(true);
node.updateParent();
//And need to redraw again
node.getTree().redraw();
}
//validate the result
node.getTree().checkData();
}
/*
takes a string and searches it for agent items
and returns the agent items that it found
*/
function findTopicsInContent(content, excludeCalculations){
var topic_map = new Object();
var topics = new Array();
var items = getTreeValues(getDataItemsTree());
for(var i = 0; i < items.length; i++){
if(!topic_map[items[i].getDropValue()] && content.indexOf(items[i].getDropValue()) != -1){
if(!excludeCalculations){
topic_map[items[i].getDropValue()];
topics.push(items[i].getDropValue());
}
}
}
return topics;
}
/*
* Create a ref obj agent item. Called when loading an agent from load_agent.xts
*/
function generateAgentItem(name, ref, aggregate, displayType)
{
var obj = null;
var newTreeNode = null;
var displayTypeCode = null;
if (displayType.match(/textItem/)) {
displayTypeCode = "0";
} else if (displayType.match(/image/)) {
displayTypeCode = "1";
} else if (displayType.match(/hyperlink/)) {
displayTypeCode = "2";
} else {
displayTypeCode = "0";
}
// we have an agent item
obj = new aiDataItem(name, ref, aggregate, displayType);
// add this to the tree - we can call addAgentItem - which will actually make a copy
// but the addAgentItem call will make sure that names are unique.
addAgentItem(obj);
return obj;
}
function updateParameter(obj, node) {
var itemNode = node;
if (!node || node == 'undefined') {
itemNode = getNodeFromTree(obj,"name",getParametersTree());
}
if (itemNode) {
var item = itemNode.getValue();
item.name = obj.name;
item.acceptRange = obj.acceptRange;
itemNode.setName(obj.name);
itemNode.setValue(item);
} else {
//Ok smarty. Item is not in the tree add it.
itemNode = addParameter(obj);
}
//UnSelect all.
//itemNode.getTree().deSelectAll();
//itemNode.setSelected(true);
redrawTreeNode(itemNode,true);
//update the agent changed state, we have added/updated a data item
cf.agentHasChanged(true);
return itemNode;
}
function updateDataItem(obj, node) {
var dataItemNode = node;
if (!node || node == 'undefined') {
dataItemNode = getNodeFromTree(obj,"name",getDataItemsTree());
}
if (dataItemNode) {
var dataItem = dataItemNode.getValue();
dataItem.name = obj.name;
dataItem.ref = obj.ref;
dataItemNode.setName(obj.name);
dataItemNode.setValue(dataItem);
if (obj.isIndicator()) {
dataItemNode.setIndicator(obj.getIndicator());
}
} else {
//Ok smarty. Item is not in the tree add it.
dataItemNode = addAgentItem(obj);
}
redrawTreeNode(dataItemNode,true);
//update the agent changed state, we have added/updated a data item
cf.agentHasChanged(true);
return dataItemNode;
}
/*
* Generate the name for the agentItem. Algorith is to see if the name is used -
* if it is - add a numeric onto the end - continue doing so until you get to a name which isn't used
*/
function generateName(obj)
{
var i = 1;
var currentName = obj.name;
//Check if Item is there with this name.
while (getNodeFromTreeWithValue(currentName,"name",getTreeChildNodes(getDataItemsTree()))) {
// generate a new name
currentName = obj.name + i;
// up the index
i++;
}
// return the generated name
return currentName;
}
function createDataItemObj(name,value,aggregate) {
if (!aggregate || aggregate == 'undefined') {
aggregate = 'automatic';
}
var obj = new aiDataItem(name, value, aggregate, '0');
return obj;
}
function createParameterObj(name,acceptRange)
{
// create the new object
var obj = new aiParameter(name, acceptRange);
return obj;
}
/*
* Add an agent item
* obj - the object that we want to add
*/
function addAgentItem(obj, undo)
{
//check if item already there, and get the Node.
var ret_value = getNodeFromTree(obj,"name",getDataItemsTree());
//We found it. Now check if the ref is the same
if (ret_value) {
//We have the node so use it. This is a bit faster and straight.
ret_value = getNodeFromTreeWithValue(obj.ref,"ref",new Array(ret_value));
}
// create the agentItem if the ref is not there
if (!ret_value || ret_value == "undefined") {
if (obj.usage && !obj.usage.match(/fact/i)) {
//This is to work around the problem where
//the usage is an 'attribute' and not a 'fact',
//hence you want to set aggregate as 'none'
//Because this is what ReportServer would
//expect it to be for an 'attribute' type usage.
//Bug
obj.regularAggregate = 'none';
}
// may have to rename them though
var itemName = generateName(obj);
// get the agentItemObject
var agentItemObj = new aiDataItem(itemName, obj.ref, obj.regularAggregate, obj.displayType);
// get the type for the tree
var agentItemTreeType = generateAgentItemTreeType(obj.regularAggregate);
// build a new tree node
var newTreeNode = new cf.CTreeNode(getDataItemsTree().getRootNode(), agentItemTreeType, false, itemName, agentItemObj, false);
//Set the tree location of this item. A bit nasty that we have to toString the integer value.
//CTree should deal with this and set the treeref to a string value always and not int in one case
//and strign in another especially if it is the top level of the tree.
agentItemObj.treeRef = newTreeNode.getTreeRef().toString();
// check to see what sort of node we're adding - folder nodes don't want toggles.
newTreeNode.setCanHaveChildren(false);
// update the tree
if(newTreeNode.getTree() != null)
newTreeNode.getTree().redraw();
// return the aiDataItem created
ret_value = newTreeNode;
if(!undo){
if(getRedoUndoManager().isEditActionBatching()){
getRedoUndoManager().getEditActionBatch().push(new AddItemEditAction(newTreeNode));
}else{
getRedoUndoManager().getActionHistory().push(new AddItemEditAction(newTreeNode));
}
//adding a new item, clears the redo cache
getRedoUndoManager().getUndoneHistory().clear();
}
}
return ret_value;
}
function addParameter(obj, undo)
{
var newTreeNode = getNodeFromTree(obj,"name",getParametersTree());
//guard clause to check if we can add this item
if (!newTreeNode) {
// build a new tree node
newTreeNode = new CTreeNode(getParametersTree().getRootNode(), tntParameter, false, obj.name, obj, false);
// update the tree
newTreeNode.getTree().redraw();
if(!undo){
getRedoUndoManager().getActionHistory().push(new AddItemEditAction(newTreeNode));
//adding a new item, clears the redo cache
getRedoUndoManager().getUndoneHistory().clear();
}
}
return newTreeNode;
}
/**
* This is used by agentItemListener.js to add items back to the tree
* during undo/redo.
*/
function addUnknownItem(obj, undo){
var added;
if (obj instanceof aiParameter){
added = addParameter(obj, undo);
}else if (obj instanceof aiDataItem){
added = addAgentItem(obj, undo);
}
return added;
}
function setIndicator(name) {
var node = getNodeFromTreeWithValue(name,"getDropValue()", getTreeChildNodes(getDataItemsTree()));
if (node && node != 'undefined') {
var obj = node.getValue();
node.setIndicator(obj.getIndicator());
redrawTreeNode(getDataItemsTree().getRootNode());
}
}
function removeIndicator(name) {
var node = getNodeFromTreeWithValue(name,"getDropValue()", getTreeChildNodes(getDataItemsTree()));
if (node && node != 'undefined') {
node.setIndicator(null);
redrawTreeNode(getDataItemsTree().getRootNode());
}
}
/**
* Get the values for a particular tree.
* optionally you can pass an object with a "match" function that
* takes a tree node as an argument
*/
function getTreeValues(tree, searcher) {
var items = new Array();
//Default to agentItems
var children = getTreeChildNodes(tree);
for(var i=0; i < children.length;i++) {
if((searcher && searcher.match(children[i].getValue())) || !searcher){
//only add the item if you dont have a searcher, or the searcher matches the item
items.push(children[i].getValue());
}
}
return items;
}
/**
* Get the values for a particular tree.
*/
function getTreeChildNodes(tree) {
return tree.getRootNode().getChildren();
}
/**
* For a given aiDataITem or aiPArameter get the correpsonding
* Node from the tree.
*/
function getNodeFromTree(obj,property, tree) {
return getItemFromTreeWithObject(obj,property,getTreeChildNodes(tree));
}
/**
* Get item from tree when you have an object such as aiDataItem or aiParameter.
*/
function getItemFromTreeWithObject(obj,property, children) {
return getNodeFromTreeWithValue(obj[property],property,children);
}
/**
* Get a Node from tree with a given value like name, ref etc...
*/
function getNodeFromTreeWithValue(value,property, children) {
for(var i=0; i < children.length;i++) {
var treeObj = children[i].getValue();
if (treeObj && eval("treeObj" + "." + property) == value) {
//We found the object in the tree so we
//return it.
return children[i];
}
}
return null;
}
function getDataItemsTree() {
return agentItemsTree;
}
function getParametersTree() {
return agentParameterTree;
}
function deleteFromTree(tree) {
var rootNode = tree.getRootNode();
var selectedNodes = tree.getSelectedLeafNodes(rootNode);
//remove the ui nodes
if(selectedNodes.length > 0) {
rootNode.removeChildren(selectedNodes);
var delete_stack = new Array();
var agentDef = parent.getAgentDefinition();
for(var i = 0; i < selectedNodes.length; i++){
delete_stack.push(new DeleteItemEditAction(selectedNodes[i]));
// delete any extra topic from summry event keys
if(agentDef!=null && agentDef.summaryEventKey!=null && agentDef.summaryEventKey.containsItem('['+selectedNodes[i].getName()+'];'))
{
agentDef.summaryEventKey.removeItem('['+selectedNodes[i].getName()+'];');
}
}
getRedoUndoManager().getActionHistory().push(new EditActionBundle(delete_stack));
//re write the tree... I dont know, I have to do everything round here
redrawTreeNode(rootNode,false);
// delete any extra topic from summry event keys
if(agentDef!=null){
agentDef.removeInvalidFilterTopics();
}
//getActionTopicFilterElementProcessor().updateList();
//update the agent changed state, we have added/updated a data item
cf.agentHasChanged(true);
}
}
// get the property from the given object
function getObjProp(obj, prop)
{
return obj[prop];
}
// get the name for the object - this is mutated to give a unique name
function getObjPropName(obj)
{
return getObjProp(obj, "name");
}
function generateAgentItemTreeType(aggregate)
{
// this is an integer value - have found the following values defined in FM -
// where all the other values are defined I don't know
// any = 10 --> "none"
// average = 5 --> "average"
// averageNonZero = 11 --> "none"
// automatic = 18 --> "none"
// calculated = 12 --> "none"
// count = 6 --> "count"
// countDistinct = 13 --> "none"
// countNonZero = 14 --> "none"
// external = 0 --> "none"
// maximum = 4 --> "maximum"
// median = 17 --> "none"
// minimum = 3 --> "minimum"
// standardDeviation= 15 --> "none"
// sum = 2 --> "total"
// variance = 16 --> "none"
var type = tntDataItem;
switch ( aggregate ) {
case "total":
type = tntDataItemTotal;
break;
case "count":
type = tntDataItemCount;
break;
case "average":
type = tntDataItemAverage;
break;
case "minimum":
type = tntDataItemMinimum;
break;
case "maximum":
type = tntDataItemMaximum;
break;
case "countDistinct":
type = tntDataItemCntDistinct;
break;
case "median":
type = tntDataItemMedian;
break;
case "standardDeviation":
type = tntDataItemStdDeviation;
break;
case "variance":
type = tntDataItemVariance;
break;
case "calculated":
type = tntDataItemCalc;
break;
case "automatic":
type = tntDataItemAutomatic;
break;
case "aggregate":
type = tntDataItemAggregate;
break;
case "none":
type = tntDataItemNone;
break;
case "notApplicable":
type = tntDataItemNotApplicable;
break;
default:
type = tntDataItem;
break;
}
// default case
return type;
}
function encode(text)
{
// seeing as this is destined for XML - and it could hold anything - escape
// any dodgy characters
var amp_re = /&/g;
var lt_re = //g;
var ap_re = /\'/g;
var qu_re = /\"/g;
text = text.replace(amp_re, "&");
text = text.replace(lt_re, "<");
text = text.replace(gt_re, ">");
text = text.replace(ap_re, "'");
text = text.replace(qu_re, """);
return text;
}
function stripSpaces(text)
{
return text.replace(/^\s+/,'').replace(/\s+$/,'');
}
function buildFilterExpressions(detailFilterValue,summaryFilterValue)
{
var detailFilter = generateFilter(new Array(detailFilterValue), "detail");
var summaryFilter = generateFilter(new Array(summaryFilterValue), "summary");
return detailFilter + summaryFilter;
}
function generateFilter(filters,filterType) {
var builtFilter = "";
var builtFilterFlag = false;
// add the filter condition if we have one
if (filters!= null && filters.length > 0) {
builtFilter += "<" + filterType + "Filters>";
// loop over the filters
for (var i = 0; i < filters.length; ++i) {
// get the filter
var filter = filters[i];
// add if we have a filter
if (filter != null && stripSpaces(filter).length > 0) {
if (filterType=="detail") {
builtFilter += "<" + filterType + "Filter use=\"required\" postAutoAggregation=\"false\">";
} else {
builtFilter += "<" + filterType + "Filter use=\"required\">";
}
builtFilter += "" + encode(filter) + "";
builtFilter += "" + filterType + "Filter>";
builtFilterFlag = true;
}
}
builtFilter += "" + filterType + "Filters>";
//If we have built at least one filter then we keep filter as is
//otherwise if flag is false then we should remove the wrapping tags
// or
if (!builtFilterFlag) {
builtFilter = "";
}
}
return builtFilter;
}
function buildFilterCondition()
{
//The AgentTask-condition holds an XML encoded blob of the summary and details
//filter. We have a hidden input in the defineCondtion.xts that is always updated
//when the summary and detail filter changes.
var filters = "";
var msgFrame = getMessageIFrame();
var msgDoc = getFrameDocument(msgFrame);
// get the task condition element
var conditionElement = msgDoc.pform.elements['AgentTask-condition'];
// if we have an element - get it's value
if (conditionElement != null && conditionElement.value != "") {
//ensure single quotes are encoded, these are generate when a value is inserted into the condition using the selectValues dialog
var filterValue = "";
var aposRegEx = /\'/g;
filterValue = conditionElement.value.replace(aposRegEx, "'");
// condition element MIGHT be 2 elements if we have both summary and detail filters, so create a dummy root node.
var filters_xml = new XMLParser(""+filterValue+"");
if (filters_xml != null && filters_xml.childNodes != null && filters_xml.childNodes.length > 0) {
//shouldnt have any attributes.. they are probably xts ones which cause report server validation death
filters_xml.attributes = new Array();
// handle the filters and combine as one string
for (var i = 0; i < filters_xml.childNodes.length; i++) {
filters_xml.childNodes[i].attributes = new Array();
filters = filters + filters_xml.childNodes[i].toString();
}
}
}
// return the filters
return filters;
}
function noDataItems()
{
var dataItemsTree = getTreeValues(getDataItemsTree());
if (dataItemsTree.length < 1) {
return true;
}
else return false;
}