/*
* @file Implementation of the filter interface
* @namespace sap.bc.ina.api.sina.impl.inav2.filter
* @copyright Copyright (c) 2013 SAP AG. All rights reserved.
* @ignore
*/
(function(global, isXS) {
"use strict";
var executeFilter = function($) {
if (!$)
{
$ = global.$;
}
// =========================================================================
// create packages
// =========================================================================
if (!isXS) {
global.sap.bc.ina.api.sina.expandPackage(global, 'sap.bc.ina.api.sina.impl.inav2.filter');
}
var filter = global.sap.bc.ina.api.sina.impl.inav2.filter;
var module = filter;
module.DataSource = function(){this.init.apply(this,arguments);};
module.DataSourceMetaData = function(){this.init.apply(this,arguments);};
module.Filter = function(){this.init.apply(this,arguments);};
module.Condition = function(){this.init.apply(this,arguments);};
module.ConditionGroup = function(){this.init.apply(this,arguments);};
// =========================================================================
// class datasource metadata
// =========================================================================
module.DataSourceMetaData.prototype = $.extend({}, global.sap.bc.ina.api.sina.filter.DataSourceMetaData.prototype, {
/**
* Meta data for a data source object.
* @ignore
* @constructs sap.bc.ina.api.sina.impl.inav2.filter.DataSourceMetaData
* @param {Object} properties Configuration object.
*/
init : function(properties) {
properties = properties || {};
this.datasource = properties.datasource || {};
this.description = properties.description || "";
this.dimensions = {};
},
_getMetaDataRequest : function() {
var request = global.sap.bc.ina.api.sina.impl.inav2.jsontemplates.dataSourceMetaDataRequest;
request.DataSource = this.datasource.toInAJson();
return request;
},
_getMetaData : function(isAsync,callback) {
var self = this;
var request = {
async : isAsync,
url : global.sap.bc.ina.api.sina.sinaSystem().inaUrl,
processData : false,
contentType : 'application/json',
dataType : 'json',
data : this._getMetaDataRequest()
};
var jqXHR = global.sap.bc.ina.api.sina.sinaSystem().proxy.ajax(request);
jqXHR.done(function(data){
if(!self.rawMetadata){
self._parseServerMetaData(data);
}
if(callback){
callback(self);
}
});
return this;
},
_parseServerMetaData : function(json){
this.rawMetadata = json;
this.description = this.rawMetadata.Cube.Description;
this.datasource.setLabel(this.description);
for (var i = 0; i < this.rawMetadata.Cube.Dimensions.length; i++) {
var dimension = {};
dimension.name = this.rawMetadata.Cube.Dimensions[i].Name;
dimension.description = this.rawMetadata.Cube.Dimensions[i].Description;
dimension.attributes = {};
for (var j = 0; j < this.rawMetadata.Cube.Dimensions[i].Attributes.length; j++) {
dimension.attributes[this.rawMetadata.Cube.Dimensions[i].Attributes[j].Name] = {
name : this.rawMetadata.Cube.Dimensions[i].Attributes[j].Name,
description : this.rawMetadata.Cube.Dimensions[i].Attributes[j].Description
};
}
this.dimensions[dimension.name] = dimension;
}
}
});
// =========================================================================
// class datasource
// =========================================================================
module.DataSource.prototype = $.extend({}, global.sap.bc.ina.api.sina.filter.DataSource.prototype, {
/**
* The data source of a query that is a view in SAP HANA.
* Use {@link sap.bc.ina.api.sina.sinabase.Sina} createDataSource() factory instead of this constructor.
* @constructs sap.bc.ina.api.sina.impl.inav2.filter.DataSource
* @augments {sap.bc.ina.api.sina.filter.DataSource}
* @param {Object} properties
* @param {String} [properties.schemaName=_SYS_BIC] The schema of the view to be used.
* @param {String} properties.packageName The package name of the view to be used.
* @param {String} properties.objectName The object name if the view to be used.
* @example <caption>Properties object for a view which resides in the 'SYSTEM' schema
* and has the name 'J_EPM_PRODUCT'</caption>
* { schemaName : 'SYSTEM',
* objectName : 'J_EPM_PRODUCT' }
* @example <caption>Properties object for a view which resides in the repository
* in package 'sap.bc.ina.demos.epm.views'</caption>
* { packageName : 'sap.bc.ina.demos.epm.views',
* objectName : 'V_EPM_PRODUCT' }
* @private
*/
init : function(properties){
properties = properties||{};
properties.schemaName = properties.schemaName||properties.SchemaName||{};
this.setSchemaName(properties.schemaName);
properties.packageName = properties.packageName||properties.PackageName||{};
this.setPackageName(properties.packageName);
properties.objectName = properties.objectName||properties.ObjectName||{};
this.setObjectName(properties.objectName);
properties.type = properties.type||properties.Type||{};
this.setType(properties.type);
this.label = properties.label||properties.Label||properties.Description||'';
if (properties.metaData) {
this.setMetaData(properties.metaData);
}
},
/**
* Compares this datasource with another datasource.
* @memberOf sap.bc.ina.api.sina.impl.inav2.filter.DataSource
* @instance
* @param {sap.bc.ina.api.sina.impl.inav2.filter.DataSource} the other datasource to be
* compared against this datasource.
* @return {boolean} true if they are equal, false otherwise
*/
equals : function(otherDS){
if(otherDS instanceof module.DataSource){
if(this.getSchemaName().label!==otherDS.getSchemaName().label||this.getSchemaName().value!==otherDS.getSchemaName().value){
return false;
}
if(this.getPackageName().label!==otherDS.getPackageName().label||this.getPackageName().value!==otherDS.getPackageName().value){
return false;
}
if(this.getObjectName().label!==otherDS.getObjectName().label||this.getObjectName().value!==otherDS.getObjectName().value){
return false;
}
if(this.getType().label!==otherDS.getType().label||this.getType().value!==otherDS.getType().value){
return false;
}
return true;
}
return false;
},
/**
* Returns the metadata for this data source asynchronously from the server.
* @ignore
* @memberOf sap.bc.ina.api.sina.impl.inav2.filter.DataSource
* @instance
* @param {Function} callback Function will be called after the meta data arrives
* from the server. This function must have one argument through which it will
* receive the metadata object.
*/
getMetaData : function(callback){
var self = this;
if(!self.metaData){
self.metaData = new module.DataSourceMetaData({datasource:this});
}
self.metaData._getMetaData(true,callback);
},
/**
* Returns the metadata for this data source synchronously from the server.
* @ignore
* @memberOf sap.bc.ina.api.sina.impl.inav2.filter.DataSource
* @instance
* Warning: Calling the function will block the javascript thread until
* a result has been received.
* @return {sap.bc.ina.api.sina.impl.inav2.filter.DataSourceMetaData} The metadata for this datasource.
*/
getMetaDataSync : function(){
var self = this;
if(!self.metaData){
self.metaData = new module.DataSourceMetaData({datasource:this});
self.metaData._getMetaData(false);
}
return self.metaData;
},
setMetaData : function(dataSourceMetaData){
this.metaData = dataSourceMetaData;
},
/**
* Returns the schema name for this data source.
* @memberOf sap.bc.ina.api.sina.impl.inav2.filter.DataSource
* @instance
* @since SAP HANA SPS 06
* @return {String} The schema name for this data source.
*/
getSchemaName : function(){
return this.schemaName;
},
/**
* Sets the schema name for this data source.
* @memberOf sap.bc.ina.api.sina.impl.inav2.filter.DataSource
* @instance
* @since SAP HANA SPS 06
* @param {String} schemaName The new schemaName.
*/
setSchemaName : function(schemaName){
if(!this.schemaName){
this.schemaName = {};
}
if($.type(schemaName)==='object'){
this.schemaName.label = schemaName.label||schemaName.value||'';
this.schemaName.value = schemaName.value||'';
}
if($.type(schemaName)==='string'){
this.schemaName.label = schemaName;
this.schemaName.value = schemaName;
}
},
/**
* Returns the package name for this data source.
* @memberOf sap.bc.ina.api.sina.impl.inav2.filter.DataSource
* @instance
* @since SAP HANA SPS 06
* @return {String} The package name for this data source.
*/
getPackageName : function(){
return this.packageName;
},
/**
* Sets the package name for this data source.
* @memberOf sap.bc.ina.api.sina.impl.inav2.filter.DataSource
* @instance
* @since SAP HANA SPS 06
* @param {String} packageName The new package name.
*/
setPackageName : function(packageName){
if(!this.packageName){
this.packageName = {};
}
if($.type(packageName)==='object'){
this.packageName.label = packageName.label||packageName.value||'';
this.packageName.value = packageName.value||'';
}
if($.type(packageName)==='string'){
this.packageName.label = packageName;
this.packageName.value = packageName;
}
},
/**
* Returns the object name for this data source.
* @memberOf sap.bc.ina.api.sina.impl.inav2.filter.DataSource
* @instance
* @since SAP HANA SPS 06
* @return {String} The object name for this data source.
*/
getObjectName : function(){
return this.objectName;
},
/**
* Sets the object name for this data source.
* @memberOf sap.bc.ina.api.sina.impl.inav2.filter.DataSource
* @instance
* @since SAP HANA SPS 06
* @param {String} objectName The new object name.
*/
setObjectName : function(objectName){
if(!this.objectName){
this.objectName = {};
}
if($.type(objectName)==='object'){
this.objectName.label = objectName.label||objectName.value||'';
this.objectName.value = objectName.value||'';
}
if($.type(objectName)==='string'){
this.objectName.label = objectName;
this.objectName.value = objectName;
}
},
setObjectNameValue : function(value){
if(!this.objectName){
this.objectName = {};
}
this.objectName.value = value||'';
},
setObjectNameLabel : function(label){
if(!this.objectName){
this.objectName = {};
}
this.objectName.label = label||'';
},
getType : function(){
return this.type;
},
setType : function(type){
if(!this.type){
this.type = {};
}
if($.type(type)==='object'){
this.type.label = type.label||type.value||'';
this.type.value = type.value||'';
}
if($.type(type)==='string'){
this.type.label = type;
this.type.value = type;
}
},
getLabel : function(){
if (typeof this.label !=="undefined" && this.label !=="") {
return this.label;
}
if (typeof this.getObjectName().label !=="undefined" && this.getObjectName().label!=="") {
return this.getObjectName().label;
}
if (typeof this.getObjectName().value !=="undefined" && this.getObjectName().value!=="") {
return this.getObjectName().value;
}
return "";
},
setLabel : function(label){
this.label = label||'';
},
fromInAJson : function(inaJson){
this.setSchemaName({ value: inaJson.SchemaName, label: inaJson.SchemaLabel });
this.setPackageName({ value: inaJson.PackageName, label: inaJson.PackageLabel });
this.setObjectName({ value: inaJson.ObjectName, label: inaJson.ObjectLabel });
this.setType({ value: inaJson.Type, label: '' });
},
toInAJson : function(){
var json = { "SchemaName" : this.getSchemaName().value,
"PackageName" : this.getPackageName().value,
"ObjectName" : this.getObjectName().value
};
if(this.getType().value){
json.Type = this.getType().value;
}
return json;
},
toURL : function(){
var json = { "sn" : this.getSchemaName().value,
"pn" : this.getPackageName().value,
"on" : this.getObjectName().value
// "sl" : this.getSchemaName().label,
// "pl" : this.getPackageName().label,
// "ol" : this.getObjectName().label,
// "l": this.label
};
if(this.getType().value){
json.tn = this.getType().value;
// json.tl = this.getType().label;
}
return json;
},
fromURL : function(inaJson){
this.setSchemaName(inaJson.sn);
this.setPackageName(inaJson.pn);
this.setObjectName(inaJson.on);
// this.setLabel(inaJson.l);
this.setType(inaJson.tn);
}
});
// =========================================================================
// class filter
// =========================================================================
module.Filter.prototype = $.extend({}, global.sap.bc.ina.api.sina.filter.Filter.prototype, {
/**
* A simple filter for SINA queries.
* Use sina.createFilter() method instead of this private constructor.
* @constructs sap.bc.ina.api.sina.impl.inav2.filter.Filter
* @augments {sap.bc.ina.api.sina.filter.Filter}
* @param {Object} properties Configuration object.
* @private
* @since SAP HANA SPS 06
* @ignore
*/
init: function(properties){
global.sap.bc.ina.api.sina.filter.Filter.prototype.init.apply(this,[properties]);
this.defaultConditionGroup = new module.ConditionGroup({ operator : 'And' });
},
addFilterCondition : function(attribute, operator, value) {
var local_attribute = attribute;
var local_operator = operator;
var local_value = value;
if ($.type(attribute)==='object') {
var props = attribute;
local_attribute = props.attribute;
local_operator = props.operator;
local_value = props.value;
}
if(local_attribute===undefined||local_operator===undefined||local_value===undefined){
return this;
}
if(this.conditionGroupsByAttribute[local_attribute]===undefined){
this.conditionGroupsByAttribute[local_attribute] = new module.ConditionGroup({ operator: "OR" });
this.defaultConditionGroup.addCondition(this.conditionGroupsByAttribute[local_attribute]);
}
this.conditionGroupsByAttribute[local_attribute].addCondition(new module.Condition(attribute,operator,value));
return this;
},
removeFilterCondition : function(attribute, operator, value){
this.defaultConditionGroup.removeCondition(new module.Condition(attribute,operator,value));
return this;
},
resetFilterConditions : function(){
this.root = null;
this.conditionGroupsByAttribute = {};
this.defaultConditionGroup = new module.ConditionGroup({ operator : 'And' });
return this;
},
empty : function() {
this.root = null;
this.conditionGroupsByAttribute = {};
this.defaultConditionGroup = new module.ConditionGroup({ operator : 'And' });
this.searchTerms = "";
return this;
},
getJson : function() {
var root = [];
this.defaultConditionGroup.getJson(root);
var result = {
Selection : root[0]
};
return result;
},
setJson : function(json){
if(json.Selection===undefined){
return;
}
var group = new module.ConditionGroup();
group.setJson(json);
this.defaultConditionGroup.addCondition(group);
}
});
// =========================================================================
// class condition
// =========================================================================
module.Condition.prototype = $.extend({}, global.sap.bc.ina.api.sina.filter.Condition.prototype, {
/**
* Creates a new filter condition.
* @ignore
* @constructs sap.bc.ina.api.sina.impl.inav2.filter.Condition
* @param {String|Object} attribute Technical identifier of the attribute, as defined in the database.
* If the type is Object, this object can have properties with the name and value of the arguments.
* @param {String} operator Operator of the filter condition. The default value is "=".
* @param {String} value Value that should be filtered in the attribute.
*/
init : function(attribute,operator,value) {
global.sap.bc.ina.api.sina.filter.Condition.prototype.init.apply(this,[attribute,operator,value]);
if ($.type(attribute)==='object') {
this.inaV2_extended_properties = attribute;
delete this.inaV2_extended_properties.attribute;
delete this.inaV2_extended_properties.operator;
delete this.inaV2_extended_properties.value;
}
},
getJson : function(parent) {
var operand;
var json = {};
if(this.operator.toLowerCase()==='contains'){
operand = 'SearchOperand';
}
else{
operand = 'MemberOperand';
}
json[operand] = {
"AttributeName" : this.attribute,
"Comparison" : this.operator,
"Value" : this.value
};
if(operand === 'SearchOperand'){
delete json[operand].Comparison;
}
json[operand] = $.extend({}, json[operand], this.inaV2_extended_properties);
if(this.operator==='='&&this.value===null){
json.MemberOperand.Comparison = 'IS NULL';
json.MemberOperand.Value = '';
}
parent.push(json);
},
setJson : function(json){
this.attribute = json.MemberOperand.AttributeName;
this.operator = json.MemberOperand.Comparison;
this.value = json.MemberOperand.Value;
if(json.MemberOperand.Comparison === 'IS NULL'&&json.MemberOperand.Value === ''){
this.operator = '=';
this.value = null;
}
}
});
// =========================================================================
// class condition group
// =========================================================================
module.ConditionGroup.prototype = $.extend({}, global.sap.bc.ina.api.sina.filter.ConditionGroup.prototype, {
init : function(properties) {
global.sap.bc.ina.api.sina.filter.ConditionGroup.prototype.init.apply(this,[properties]);
},
getJson : function(parent) {
if(this.conditions.length===0){
return {};
}
var children = [];
for (var i = 0; i < this.conditions.length; ++i) {
this.conditions[i].getJson(children);
}
var json = {
"Operator" : {
"Code" : this.operator,
"SubSelections" : children
}
};
if (parent) {
parent.push(json);
}
else {
var result = {
Selection : json
};
return result;
}
return {};
},
setJson : function(json) {
if (json.Selection === undefined && json.Operator) {
json.Selection = {};
json.Selection.Operator = json.Operator;
}
this.setOperator(json.Selection.Operator.Code);
var conditions = json.Selection.Operator.SubSelections;
for (var i = 0; i < conditions.length; i++) {
var condition;
if (conditions[i].Operator) {
condition = new module.ConditionGroup();
}
else {
condition = new module.Condition();
}
condition.setJson(conditions[i]);
this.addCondition(condition);
}
}
});
};
if (isXS) {
executeFilter($.sap.bc.ina.api.sina.sinaxsjq.jq);
}
else if (typeof define === "function" && define.amd && !global.sap.ushell) { // only concatenated sina is in ushell repo!
define( ["jquery", './jsontemplates'], function($){
executeFilter($);
});
}
else {
executeFilter();
}
}(typeof window === 'undefined' ? $ : window, typeof window === 'undefined'));