Source: sinabase.js

/*
 * @file The Simple Information Access (SINA) Interface
 * @namespace sap.bc.ina.api.sina.sinabase
 * @requires jQuery
 * @copyright Copyright (c) 2014 SAP AG. All rights reserved.
 */


(function(global, isXS) {

    "use strict";

    var executeSinaBase = function($) {
        if (!$) {
            $ = global.$;
        }

        // =========================================================================
        // package structure
        // =========================================================================
        if (!isXS) {
            global.sap.bc.ina.api.sina.expandPackage(global, 'sap.bc.ina.api.sina.sinabase');
        }

        var sinabase = global.sap.bc.ina.api.sina.sinabase;
        var filter = global.sap.bc.ina.api.sina.filter;
        var module = sinabase;
        var emptyFunction = function() {};

        // =========================================================================
        // provider registry
        // =========================================================================
        $.extend(module, {

            provider: {},

            registerProvider: function(provider) {
                this.provider[provider.impl_type] = provider;
            }

        });

        // =========================================================================
        // sina base class
        // =========================================================================
        module.Sina = function() {
            this.init.apply(this, arguments);
        };

        module.Sina.prototype = {

            /**
             * Sina base class. Use the getSina() factory in {@link sap.bc.ina.api.sina} instead
             * of using this private constructor directly.
             * @constructs sap.bc.ina.api.sina.sinabase.Sina
             * @since SAP HANA SPS 08
             * @private
             */
            init: function() {

            },

            _initQueryProperties: function(properties){
                properties = properties || {};
                properties.system = properties.system || this.sinaSystem();
                if (properties.dataSource) {
                    properties.dataSource = new this._provider.DataSource(properties.dataSource);
                }
                return properties;
            },

            /**
             * Creates and returns a chart query for simple analytics.
             * @memberOf sap.bc.ina.api.sina.sinabase.Sina
             * @instance
             * @since SAP HANA SPS 06
             * @param  {Object} properties Configuration object.
             * @return {sap.bc.ina.api.sina.sinabase.ChartQuery} The instance of a chart query.
             * See {@link sap.bc.ina.api.sina.sinabase.ChartResultSet} for the result set format.
             * @example
             * <caption>Create a query that returns a result set suitable for a bar or pie chart:</caption>
             * var query = sap.bc.ina.api.sina.createChartQuery()
             * .dataSource({ schemaName : "SYSTEM",
             *               objectName : "J_EPM_PRODUCT"
             *  })
             * .addDimension("CATEGORY")
             * .addMeasure({ name : "CATEGORY",
             *               aggregationFunction : "COUNT"
             * }); //end of query
             * var resultSet = query.getResultSetSync();
             * var elements = resultSet.getElements();
             * // contents of elements:
             * [
                {
                  "label": "Others",
                  "labelRaw": "Others",
                  "value": "13",
                  "valueRaw": 13
                },
                {
                  "label": "Notebooks",
                  "labelRaw": "Notebooks",
                  "value": "10",
                  "valueRaw": 10
                },
                {
                  "label": "Flat screens",
                  "labelRaw": "Flat screens",
                  "value": "9",
                  "valueRaw": 9
                },
                {
                  "label": "Software",
                  "labelRaw": "Software",
                  "value": "8",
                  "valueRaw": 8
                },
                {
                  "label": "Electronics",
                  "labelRaw": "Electronics",
                  "value": "5",
                  "valueRaw": 5
                }
              ]
             */
            createChartQuery: function(properties) {
                properties = this._initQueryProperties(properties);
                return new this._provider.chartQuery(properties);
            },

            /**
             * Creates and returns a search query for text queries.
             * @memberOf sap.bc.ina.api.sina.sinabase.Sina
             * @instance
             * @since SAP HANA SPS 06
             * @param  {Object} properties Configuration object.
             * @return {sap.bc.ina.api.sina.sinabase.SearchQuery} The instance of a search query.
             * See {@link sap.bc.ina.api.sina.sinabase.SearchResultSet} for the result set format.
             * @example
             * <caption>Simple search for the term "basic" in view J_EPM_PRODUCT. If the term is
             * found in a column marked in the view as freestyle search relevant, the content of columns
             * in the attributes array is returned, in this case PRODUCT_ID, TEXT, CATEGORY, PRICE,
             * and CURRENCY_CODE. The return attributes do not have to be marked as freestyle search relevant though.
			 * Note that the suggestion query does not make use of the freestyle search relevant property.
			 * So if you set this property to false in the view, you will not get a search result using a suggestion as search term.</caption>
             * var query = sap.bc.ina.api.sina.createSearchQuery({
                dataSource          : { schemaName  : "SYSTEM",
                                        objectName  : "J_EPM_PRODUCT" },
                attributes          : [ "PRODUCT_ID",
                                        "TEXT",
                                        "CATEGORY",
                                        "PRICE",
                                        "CURRENCY_CODE"],
                searchTerms         : "basic",
                skip                : 0,
                top                 : 5
               });
             * var resultSet = query.getResultSetSync();
             * var elements = resultSet.getElements();
             * // contents of elements:
             * [{ "PRODUCT_ID":{"label":"PRODUCT_ID","valueRaw":"HT-1000","value":"HT-1000"},
             *     "TEXT":{"label":"TEXT","valueRaw":"Notebook Basic 15 with 1,7GHz - 15","value":"Notebook Basic 15 with 1,7GHz - 15"},
             *     "CATEGORY":{"label":"CATEGORY","valueRaw":"Notebooks","value":"Notebooks"},
             *     "PRICE":{"label":"PRICE","valueRaw":"956.00","value":"956.00"},
             *     "CURRENCY_CODE":{"label":"CURRENCY_CODE","valueRaw":"EUR","value":"EUR"}},
             *     // second result item:
             *     {"PRODUCT_ID":{"label":"PRODUCT_ID","valueRaw":"HT-1001","value":"HT-1001"},
             *     "TEXT":{"label":"TEXT","valueRaw":"Notebook Basic 17 with 1,7GHz - 17","value":"Notebook Basic 17 with 1,7GHz - 17"},
             *     "CATEGORY":{"label":"CATEGORY","valueRaw":"Notebooks","value":"Notebooks"},
             *     "PRICE":{"label":"PRICE","valueRaw":"1249.00","value":"1249.00"},
             *     "CURRENCY_CODE":{"label":"CURRENCY_CODE","valueRaw":"EUR","value":"EUR"}},
             *     // third result item:
             *     {"PRODUCT_ID":{"label":"PRODUCT_ID","valueRaw":"HT-1002","value":"HT-1002"},
             *     "TEXT":{"label":"TEXT","valueRaw":"Notebook Basic 18 with 1,7GHz - 18","value":"Notebook Basic 18 with 1,7GHz - 18"},
             *     "CATEGORY":{"label":"CATEGORY","valueRaw":"Notebooks","value":"Notebooks"},
             *     "PRICE":{"label":"PRICE","valueRaw":"1570.00","value":"1570.00"},
             *     "CURRENCY_CODE":{"label":"CURRENCY_CODE","valueRaw":"USD","value":"USD"}},
             *     // fourth result item:
             *     {"PRODUCT_ID":{"label":"PRODUCT_ID","valueRaw":"HT-1003","value":"HT-1003"},
             *     "TEXT":{"label":"TEXT","valueRaw":"Notebook Basic 19 with 1,7GHz - 19","value":"Notebook Basic 19 with 1,7GHz - 19"},
             *     "CATEGORY":{"label":"CATEGORY","valueRaw":"Notebooks","value":"Notebooks"},
             *     "PRICE":{"label":"PRICE","valueRaw":"1650.00","value":"1650.00"},
             *     "CURRENCY_CODE":{"label":"CURRENCY_CODE","valueRaw":"EUR","value":"EUR"}},
             *     // fifth result item:
             *     {"PRODUCT_ID":{"label":"PRODUCT_ID","valueRaw":"HT-8000","value":"HT-8000"},
             *     "TEXT":{"label":"TEXT","valueRaw":"1,5 Ghz, single core, 40 GB HDD, Windows Vista Home Basic, 512 MB RAM","value":"1,5 Ghz, single core, 40 GB HDD, Windows Vista Home Basic, 512 MB RAM"},
             *     "CATEGORY":{"label":"CATEGORY","valueRaw":"Notebooks","value":"Notebooks"},
             *     "PRICE":{"label":"PRICE","valueRaw":"799.00","value":"799.00"},
             *     "CURRENCY_CODE":{"label":"CURRENCY_CODE","valueRaw":"EUR","value":"EUR"}}
             *  ]
             * @example
             * <caption>The same search as in the previous example but now with term highlighting. If the term
             * "basic" is found in the TEXT attribute, it will be returned as <b>basic</b>.
             * The parameter maxLength defines the length of chars to be returned.
             * The parameter startPosition defines start position of chars to be returned.
             * The maxLength and startPosition parameters can be omitted. In this case, the default values
             * shown in the example below are used.</caption>
             * var searchQuery = sap.bc.ina.api.sina.createSearchQuery({
             *  dataSource          : { "schemaName"  :  "SYSTEM" ,
             *                          "objectName"  :  "J_EPM_PRODUCT" },
             *  attributes          : [ "PRODUCT_ID",
             *                          { attributeName: "TEXT", highlighted:true,
             *                            maxLength:30000, startPosition:1 } ],
             *  searchTerms         : "basic",
             *  skip                : 0,
             *  top                 : 5
             * });
             *  var resultSet = searchQuery.getResultSetSync();
             *  var searchResults = resultSet.getElements();
             * @example
             * <caption>The same search as in the previous example, but now with the snippet function. If the term
             * "basic" is found in the TEXT attribute
             * the content is shortened and will begin and end with three dots (...)
             * In addition to the snippet, the search term is highlighted the same way as in the highlighted function (see previous example).
             * It is therefore not necessary to use highlighted and snippet for the same attribute.
             * </caption>
             * var searchQuery = sap.bc.ina.api.sina.createSearchQuery({
             *  dataSource          : { "schemaName"  :  "SYSTEM" ,
             *                          "objectName"  :  "J_EPM_PRODUCT" },
             *  attributes          : [ "PRODUCT_ID",
             *                          { attributeName: "TEXT", snippet:true } ],
             *  searchTerms         : "basic",
             *  skip                : 0,
             *  top                 : 5
             * });
             *  var resultSet = searchQuery.getResultSetSync();
             *  var searchResults = resultSet.getElements();
             */
            createSearchQuery: function(properties) {
                properties = this._initQueryProperties(properties);
                return new this._provider.searchQuery(properties);
            },



            /**
             * Creates a chart query that delivers a result set suitable for a group bar chart.
             * @memberOf sap.bc.ina.api.sina.sinabase.Sina
             * @instance
             * @since SAP HANA SPS 06
             * @param  {Object} properties Configuration object.
             * @return {sap.bc.ina.api.sina.sinabase.GroupBarChartQuery} The instance of a chart query.
             * See {@link sap.bc.ina.api.sina.sinabase.GroupBarChartResultSet} for the result set format.
             * @example
             * <caption>Grouped bar chart query with two dimensions and one measure:</caption>
             * var query = sap.bc.ina.api.sina.sina.createGroupBarChartQuery({
             *      dataSource : { "schemaName"  :  "SYSTEM" ,
             *                     "objectName"  :  "J_EPM_PRODUCT" },
             *      dimensions : ['YEAR', 'COUNTRY'],
             *      measures   : [{ name: 'PROFIT', aggregationFunction: 'SUM' }]
             *  });
             *  var resultSet = query.getResultSetSync();
             *  var elements = resultSet.getElements();
             * @example
             *  <caption>Grouped bar chart query with two dimensions and one measure:</caption>
             * var query = sap.bc.ina.api.sina.sina.createGroupBarChartQuery();
             * query.dataSource({ schemaName : "SYSTEM",
             *                    objectName : "J_EPM_PRODUCT"
             * });
             * query.addDimension('CURRENCY_CODE');
             * query.addDimension('CATEGORY');
             * query.count('PRODUCT_ID');
             * var resultSet = query.getResultSetSync();
             * var elements = resultSet.getELements();
             * // contents of elements:
             * [
                {
                  "label": "EUR",
                  "value": [
                    {
                      "label": "Notebooks",
                      "value": [
                        {
                          "label": "COUNT",
                          "value": {
                            "value": "6",
                            "valueRaw": 6
                          }
                        }
                      ]
                    },
                    {
                      "label": "Others",
                      "value": [
                        {
                          "label": "COUNT",
                          "value": {
                            "value": "5",
                            "valueRaw": 5
                          }
                        }
                      ]
                    },
                    {
                      "label": "Software",
                      "value": [
                        {
                          "label": "COUNT",
                          "value": {
                            "value": "3",
                            "valueRaw": 3
                          }
                        }
                      ]
                    }
                  ]
                }
                ]
             */
            createGroupBarChartQuery: function(properties) {
                properties = this._initQueryProperties(properties);
                return new this._provider.groupBarChartQuery(properties);
            },


            /**
             * Creates a chart query that delivers a result set suitable for a line chart.
             * @memberOf sap.bc.ina.api.sina.sinabase.Sina
             * @instance
             * @since SAP HANA SPS 06
             * @param  {Object} properties Configuration object.
             * @return {sap.bc.ina.api.sina.sinabase.LineChartQuery} Instance of a chart query.
             * See {@link sap.bc.ina.api.sina.sinabase.LineChartResultSet} for the result set format.
             * @example
             *  <caption>Line chart with two dimensions and one measure:</caption>
             * var queryProperties = {
             *     dataSource      : { schemaName  : "SYSTEM",
                                       objectName  : "J_EPM_PRODUCT"
                                     },
                   dimensionX      : {name: 'CATEGORY'},
                   dimensionLine   : {name: 'CURRENCY_CODE'},
                   measureY        : {name: 'PRODUCT_ID', aggregationFunction: 'COUNT'}
               };
               query = sap.bc.ina.api.sina.sina.createLineChartQuery(queryProperties);
             * var resultSet = query.getResultSetSync();
             * var elements = resultSet.getEements();
             * // contents of elements (shortened):
             * [
                 {
                   "label": "EUR",
                   "value": [
                     {
                       "x": "Notebooks",
                       "y": 6
                     },
                     {
                       "x": "Others",
                       "y": 5
                     },
                     {
                       "x": "Software",
                       "y": 3
                     },
                     {
                       "x": "Speakers",
                       "y": 3
                     },
                     {
                       "x": "Electronics",
                       "y": 2
                     },
                     {
                       "x": "Flat screens",
                       "y": 2
                     },
                     {
                       "x": "Laser printers",
                       "y": 2
                     },
                     {
                       "x": "Mice",
                       "y": 2
                     },
                     {
                       "x": "PC",
                       "y": 2
                     },
                     {
                       "x": "Workstation ensemble",
                       "y": 2
                     }
                   ]
                 },
                 {
                   "label": "USD",
                   "value": [
                     {
                       "x": "Others",
                       "y": 4
                     },
                     {
                       "x": "Flat screens",
                       "y": 2
                     },
                     {
                       "x": "Handhelds",
                       "y": 2
                     },
                     {
                       "x": "High Tech",
                       "y": 2
                     },
                     {
                       "x": "Notebooks",
                       "y": 2
                     },
                     {
                       "x": "Software",
                       "y": 2
                     },
                     {
                       "x": "Electronics",
                       "y": 1
                     },
                     {
                       "x": "Graphic cards",
                       "y": 1
                     },
                     {
                       "x": "Handheld",
                       "y": 1
                     },
                     {
                       "x": "Headset",
                       "y": 1
                     }
                   ]
                 }
              ]
             */
            createLineChartQuery: function(properties) {
                properties = this._initQueryProperties(properties);
                properties.dimensions = [properties.dimensionLine, properties.dimensionX];
                properties.measures = [{
                    name: properties.measureY.name,
                    aggregationFunction: properties.measureY.aggregationFunction
                }];
                return new this._provider.lineChartQuery(properties);
            },

            /**
             * Creates and returns a suggestion for text queries.
             * @memberOf sap.bc.ina.api.sina.sinabase.Sina
             * @instance
             * @since SAP HANA SPS 06
             * @param  {Object} properties Configuration object.
             * @return {sap.bc.ina.api.sina.sinabase.SuggestionQuery} The instance of a suggestion query.
             * @example
             * <caption>Getting suggestions asynchronously for attributes CATEGORY and PRODUCT_ID.
			 * Note that, other than the search query, the suggestion query does not make use of the freestyle search relevant property set in the view.
			 * So if you set this property to false in the view, you will get a suggestion but a search using the suggestion as a search term will show no results.</caption>
             *  var properties = {
             *      dataSource : { "schemaName"  : "SYSTEM",
             *                    "objectName"  : "J_EPM_PRODUCT"
             *                   },
             *      searchTerms : "s*",
             *      top   : 10,
             *      skip  : 0,
             *      onSuccess : function(resultset) {
             *                        var suggestions = resultset.getElements();
             *                        console.dir(suggestions);
             *      },
             *      onError :   function(error){
             *                        console.error(error);
             *      },
             *      attributes : ["CATEGORY","PRODUCT_ID"]
             *  };
             *  var suggestion_query = sap.bc.ina.api.sina.sina.createSuggestionQuery(properties);
             *  suggestion_query.getResultSet(); //returns immediately, see onSuccess on how to go on
             */
            createSuggestionQuery: function(properties) {
                properties = this._initQueryProperties(properties);
                return new this._provider.suggestionQuery(properties);
            },


            /**
             * Creates and returns a perspective query.
             * @ignore
             * @since SAP HANA SPS 06
             * @memberOf sap.bc.ina.api.sina.sinabase.Sina
             * @instance
             * @private
             * @param  {Object} properties Configuration object.
             * @return {sap.bc.ina.api.sina.sinabase.PerspectiveQuery} The instance of a perspective query.
             */
            createPerspectiveQuery: function(properties) {
                properties = this._initQueryProperties(properties);
                return new this._provider.perspectiveQuery(properties);
            },

            /**
             * Creates and returns a perspective search query.
             * @ignore
             * @since SAP HANA SPS 07
             * @memberOf sap.bc.ina.api.sina.sinabase.Sina
             * @instance
             * @private
             * @param  {Object} properties Configuration object.
             * @return {sap.bc.ina.api.sina.sinabase.PerspectiveSearchQuery} The instance of a perspective search query.
             */
            createPerspectiveSearchQuery: function(properties) {
                properties = this._initQueryProperties(properties);
                return new this._provider.perspectiveSearchQuery(properties);
            },

            /**
             * Creates and returns a perspective query.
             * @ignore
             * @since SAP HANA SPS 07
             * @memberOf sap.bc.ina.api.sina.sinabase.Sina
             * @instance
             * @private
             * @param  {Object} properties Configuration object.
             * @return {sap.bc.ina.api.sina.sinabase.PerspectiveQuery} The instance of a perspective query.
             */
            createPerspectiveGetQuery: function(properties) {
                properties = this._initQueryProperties(properties);
                return new this._provider.perspectiveGetQuery(properties);
            },

            /**
             * Gets or sets a system that will be used for data access. The system must have the
             * INA V2 service up and running.
             * @ignore
             * @since SAP HANA SPS 06
             * @memberOf sap.bc.ina.api.sina.sinabase.Sina
             * @instance
             * @param  {sap.bc.ina.api.sina.system.System|sap.bc.ina.api.sina.system.System} sys The system representation.
             * @return {sap.bc.ina.api.sina.system.System|sap.bc.ina.api.sina.system.System} The system currently set,
             * but only if no parameter has been set.
             */
            sinaSystem: function(sys) {
                // must not be named system or it would overwrite sap.bc.ina.api.sina.system module!
                if (sys) {
                    this.sys = sys;
                } else {
                    return this.sys;
                }
                return {};
            },

            createFacet : function(properties) {
                return new this._provider.Facet(properties);
            },

            FacetType : {
                ATTRIBUTE : "attribute",
                DATASOURCE : "datasource",
                SEARCH : "searchresult"
            },

            createFilter : function(properties){
                return new this._provider.Filter(properties);  
            },

            createFilterCondition : function(properties){
                return new this._provider.FilterCondition(properties);  
            },

            createFilterConditionGroup : function(properties){
                return new this._provider.FilterConditionGroup(properties);  
            },

            createDataSource : function(properties){
                return new this._provider.DataSource(properties);
            }

        };

        // =========================================================================
        // query
        // =========================================================================
        module.Query = function() {
            this.init.apply(this, arguments);
        };
        module.Query.prototype = {

            /**
             *  The base query for chart, search, and suggestions queries.
             *  Use the sina.create*Query factory methods instead of this class.
             *  @constructs sap.bc.ina.api.sina.sinabase.Query
             *  @private
             */
            init: function(properties) {
                properties = properties || {};
                this.system = properties.system;
                this.onSuccess = properties.onSuccess;
                this.onError = properties.onError;
                this._responseJson = null;
                this.setTop(properties.top || 10);
                this.setSkip(properties.skip || 0);
                // this.resultSet = properties.resultSet || null;
                this.resultSetProperties = properties;
                this.filter = this.filter || properties.filter || new filter.Filter({
                    dataSource: properties.dataSource
                });
                if(properties.filterConditions && properties.filterConditions.length>0){
                    for (var i = 0, len = properties.filterConditions.length; i < len; i++) {
                        var item = properties.filterConditions[i];
                        if(item&&item instanceof Array&&item.length>0){
                            this.addFilterCondition(item[0],item[1],item[2]);
                        }
                        else if(item&&typeof item === "string"){
                            this.addFilterCondition(properties.filterConditions[0],properties.filterConditions[1],properties.filterConditions[2]);   
                            break;
                        }
                    }
                }
                this.setSearchTerms(properties.searchTerms || '');
            },


            /**
             * Returns or sets a new data source for this query. If no
             * parameters are given, the current data source is returned.
             * Otherwise, the data source is set.
             * @instance
             * @memberOf sap.bc.ina.api.sina.sinabase.Query
             * @param {sap.bc.ina.api.sina.sinabase.filter.DataSource|Object} newDataSource The current data source of this query.
             * This can be an instance of sap.bc.ina.api.sina.sinabase.filter.DataSource or it can be a plain object, like
             * { "schemaName"  : "SYSTEM",
             *   "objectName"  : "J_EPM_PRODUCT" };
             * that the system uses to create an instance of sap.bc.ina.api.sina.sinabase.filter.DataSource.
             * @return {sap.bc.ina.api.sina.sinabase.filter.DataSource|sap.bc.ina.api.sina.sinabase.Query} The current
             * data source of this query if no parameter is supplied, sap.bc.ina.api.sina.sinabase.Query otherwise to allow method chaining.
             */
            dataSource: function(newDataSource) {
              if (newDataSource) {
                this.setDataSource(newDataSource);
                return this;
              } else {
                return this.getDataSource();
              }
            },

            /**
             * Gets the data source object for this query.
             * @memberOf sap.bc.ina.api.sina.sinabase.Query
             * @instance
             * @return {sap.bc.ina.api.sina.sinabase.filter.DataSource} The data source for this query.
             */
            getDataSource: function() {
                return this.filter.getDataSource();
            },

            /**
             * Sets the data source for this query object. Results already retrieved by this query are deleted.
             * @memberOf sap.bc.ina.api.sina.sinabase.Query
             * @instance
             * @param {sap.bc.ina.api.sina.sinabase.filter.DataSource|Object} dataSource The current data source of this query.
             * This can be an instance of sap.bc.ina.api.sina.sinabase.filter.DataSource or it can be a plain object, like
             * { "schemaName"  : "SYSTEM",
             *   "objectName"  : "J_EPM_PRODUCT" };
             * that the system uses to create an instance of sap.bc.ina.api.sina.sinabase.filter.DataSource
             */
            setDataSource: function(dataSource) {
                if (dataSource === undefined) {
                    return this;
                }
                if (this.filter.getDataSource() === undefined) {
                    this.filter.setDataSource(dataSource);
                    this._resetResultSet();
                    return this;
                }
                if (!this.filter.getDataSource().equals(dataSource)) {
                    this.filter.setDataSource(dataSource);
                    this._resetResultSet();
                }
                return this;
            },

            /**
             * Returns the filter instance for this query.
             * @memberOf sap.bc.ina.api.sina.sinabase.Query
             * @instance
             * @return {sap.bc.api.sina.sinabase.filter.Filter} The filter instance for this query object.
             */
            getFilter: function() {
                return this.filter;
            },

            /**
             * Sets the new filter instance for this query. Results already retrieved by this query are deleted.
             * @memberOf sap.bc.ina.api.sina.sinabase.Query
             * @instance
             * @param {sap.bc.api.sina.sinabase.filter.Filter} filterInstance The filter instance to be used by this query.
             */
            setFilter: function(filterInstance) {
                this.filter = filterInstance;
                this._resetResultSet();
                return this;
            },

            /**
             * Sets the search terms for this query. Results already retrieved by this query are deleted.
             * @memberOf sap.bc.ina.api.sina.sinabase.Query
             * @instance
             * @param {String} terms The search terms to searched for by this query.
             */
            setSearchTerms: function(terms) {
                if (this.filter.getSearchTerms() !== terms) {
                    this.filter.setSearchTerms(terms);
                    this._resetResultSet();
                }
                return this;
            },

            /**
             * Returns the search terms currently set.
             * @memberOf sap.bc.ina.api.sina.sinabase.Query
             * @instance
             * @return {String} The search terms.
             */
            getSearchTerms: function() {
                return this.filter.getSearchTerms();
            },

            /**
             * Returns or sets a new skip value for this query. If no
             * parameter is given, the current skip value is returned.
             * Otherwise, the skip value is set.
             * @instance
             * @memberOf sap.bc.ina.api.sina.sinabase.Query
             * @param  {int} newSkip The new skip value for this query.
             * @return {int|sap.bc.ina.api.sina.sinabase.Query} The current skip value of this query if no parameter
             * was supplied, sap.bc.ina.api.sina.sinabase.Query otherwise to allow method chaining.
             */
            skip: function(newSkip) {
              if (newSkip !== undefined) {
                this.setSkip(newSkip);
              } else {
                return this._skip;
              }
              return this;
            },

            /**
             * Returns the skip value of this query.
             * @memberOf sap.bc.ina.api.sina.sinabase.Query
             * @instance
             * @return {int} The current skip value of this query.
             */
            getSkip: function() {
                //underscore is needed because of the skip function in Query
                return this._skip;
            },

            /**
             * Sets the skip value for this query.
             * To use the new skip value, call getResultSet again.
             * @memberOf sap.bc.ina.api.sina.sinabase.Query
             * @instance
             * @param {int} skip The skip value for this query.
             */
            setSkip: function(skip) {
                if (typeof skip !== "number") {
                    return false;
                }
                this._skip = this._skip || undefined;
                if (this._skip !== skip) {
                    this._skip = skip;
                    this._resetResultSet();
                }
                return this;
            },

            /**
             * Returns or sets a new top value for this query. If no
             * parameter is given, the current top value is returned.
             * Otherwise, the top value is set.
             * @instance
             * @memberOf sap.bc.ina.api.sina.sinabase.Query
             * @param  {int} newTop The new top value for this query.
             * @return {int|sap.bc.ina.api.sina.sinabase.Query} The current top value of this query if no parameter
             * was supplied, sap.bc.ina.api.sina.sinabase.Query otherwise to allow method chaining.
             */
            top: function(newTop) {
              if (newTop !== undefined) {
                this.setTop(newTop);
              } else {
                return this._top;
              }
              return this;
            },

            /**
             * Returns the top value of this query.
             * @memberOf sap.bc.ina.api.sina.sinabase.Query
             * @instance
             * @return {int} The current top value of this query.
             */
            getTop: function() {
                //underscore is needed because of the top function in Query
                return this._top;
            },

            /**
             * Sets the top value for this query.
             * To use the new top value, call getResultSet of this query again.
             * @memberOf sap.bc.ina.api.sina.sinabase.Query
             * @instance
             * @param {int} top The new top value of this query.
             */
            setTop: function(top) {
                if (typeof top !== "number") {
                    return false;
                }
                this._top = this._top || undefined;
                if (this._top !== top) {
                    this._top = top;
                    this._resetResultSet();
                }
                return this;
            },

            /**
             * Adds a filter condition for this query.
             * In the standard setting, the filter uses the AND operator for filter conditions on different
             * attributes and the OR operator for filter conditions on the same attribute.
             * @memberOf sap.bc.ina.api.sina.sinabase.Query
             * @instance
             * @param {String} attribute The attribute that the filter condition is applied to.
             * @param {String} operator  The operator used to filter the value.
             * @param {String} value     The value of the attribute to be filtered in conjunction with the operator.
             * @return {sap.bc.ina.api.sina.sinabase.Query} this
             * @example
             *  var query = sap.bc.ina.api.sina.createChartQuery();
             *  query.addFilterCondition("CATEGORY", "=", "Notebooks")
             *  .addFilterCondition("PRICE","<","1000")
             *  .addFilterCondition("CURRENCY_CODE", "=", "EUR");
             */
            addFilterCondition: function(attribute, operator, value) {
                // if (!(this.filter instanceof filter.Filter)) {
                //     this.filter = new filter.Filter();
                // }
                if(this.filter.hasFilterCondition(attribute, operator, value)===false){
                    this.filter.addFilterCondition(attribute, operator, value);
                    this._resetResultSet();
                }
                return this;
            },

            /**
             * Removes a previously added filter condition.
             * @memberOf sap.bc.ina.api.sina.sinabase.Query
             * @instance
             * @param {String} attribute The attribute that the filter condition was applied to.
             * @param {String} operator  The operator that was used to filter the value.
             * @param {String} value     The value of the attribute that was filtered in conjunction with the operator.
             * @return {sap.bc.ina.api.sina.sinabase.Query} this
             * @example
             *  query.removeFilterCondition("CATEGORY", "=", "Notebooks")
             *  .removeFilterCondition("PRICE","<","1000")
             *  .removeFilterCondition("CURRENCY_CODE", "=", "EUR");
             */
            removeFilterCondition: function(attribute, operator, value) {
                // if (!(this.filter instanceof filter.Filter)) {
                //     this.filter = new filter.Filter();
                // }
                this.filter.removeFilterCondition(attribute, operator, value);
                this._resetResultSet();
                return this;
            },

            resetFilterConditions : function(){
                this.filter.resetFilterConditions();
                this._resetResultSet();
                return this;
            },

            /**
             * Returns the result set of the query synchronously. This function blocks the JS
             * thread until the server call is made. Use getResultSet() for an asynchronous version
             * of this function that does not block the thread.
             * @memberOf sap.bc.ina.api.sina.sinabase.Query
             * @instance
             * @return {Object} The result set of this query. Call getElements() on this object to
             * get the result set elements.
             */
            getResultSetSync: function() {
                this.resultSet = this.executeSync();
                return this.resultSet;
            },

            /**
             * Returns the result set of the query asynchronously.
             * @memberOf sap.bc.ina.api.sina.sinabase.Query
             * @instance
             * @param  {function} onSuccess This function is called once  the result has been
             * retrieved from the server. The first parameter of this function is the result set.
             * The result set has the function getElements() . This contains  all result set elements.
             * @param  {function} onError This function is called if the result set of the query could
             * not be retrieved from the server. The first argument is an error object.
             * @return {Object} returns a jQuery Promise Object, see {@link http://api.jquery.com/Types/#Promise}
             * for more informations.
             */
            getResultSet: function(onSuccess, onError) {
                var self = this;
                onSuccess = onSuccess || this.onSuccess || emptyFunction;
                onError = onError || this.onError || emptyFunction;
                var resultSetDeferred = this.execute();
                resultSetDeferred.done(function(resultSet) {
                    self.resultSet = resultSet;
                    onSuccess(resultSet);
                });
                resultSetDeferred.fail(function(err){
                    onError(err);
                });
                return resultSetDeferred.promise();
            },

            // =========================================================================
            // methods to be implemented by data providers
            // =========================================================================

            _resetResultSet: function(){

            },

            execute: function() {

            },

            executeSync: function() {

            },


        };

        // =========================================================================
        // chart query
        // =========================================================================
        module.ChartQuery = function() {
            this.init.apply(this, arguments);
        };
        module.ChartQuery.prototype = $.extend({}, module.Query.prototype, {
            
            /**
             * A query that yields results suitable for simple chart controls, like
             * pie or bar charts.
             * @since SAP HANA SPS 08
             * @constructs sap.bc.ina.api.sina.sinabase.ChartQuery
             * @augments {sap.bc.ina.api.sina.sinabase.Query}
             * @private
             */
            init: function() {
                module.Query.prototype.init.apply(this, arguments);
            }

        });

        // =========================================================================
        // class facet
        // =========================================================================
        module.FacetType = module.Sina.prototype.FacetType;
        module.Facet = function() {
            this.init.apply(this, arguments);
        };
        module.Facet.prototype = {

          /**
           * A facet that is contained in a perspective.
           * @ignore
           * @constructs sap.bc.ina.api.sina.sinabase.Facet
           */
          init: function(properties) {
            properties = properties || {};
            this.title = properties.title || "";
            this.query = properties.query || null ;
            properties.facetType = properties.facetType || "";
            this.facetType = properties.facetType.toLowerCase();
            if(properties.query){
                this.setQuery(properties.query);
            }
          },

          getChartType: function() {},

          getTitle: function() {
            return this.title;
          },

          getDimension: function() {
            return this.dimension;
          },

          getQuery: function() {
            return this.query;
          },

          getLayout: function() {},

          getLayoutBinding: function() {},

          getColorPalette: function() {},

          setQuery: function(query) {
            this.query = query;
          }

        };

        // =========================================================================
        // perspective query
        // =========================================================================
        module.PerspectiveQuery = function() {
            this.init.apply(this, arguments);
        };
        module.PerspectiveQuery.prototype = $.extend({}, module.Query.prototype, {
            init: function() {
                module.Query.prototype.init.apply(this, arguments);
                this.facets = [];
            },

            addFacet : function(facet){
                this.facets.push(facet);
                return this;
            },

            getFacets : function(){
                return this.facets;
            },

            /**
             * Sets how the result will be ordered.
             * @memberOf sap.bc.ina.api.sina.sinabase.PerspectiveQuery
             * @instance
             * @param {Object|Array} orderBy If orderBy is an object, it must have the
             * properties 'orderBy' (string) and 'sortOrder' (string).
             * The orderBy property can either be the name of a database attribute that
             * the result will be sorted alphabetically for, or it can be the special
             * '$$score$$' string. The result will then be ordered according to the SAP HANA
             * Score function.
             * This function can also receive an array of these objects for multiple
             * order-by values, for example to order by $$score$$ and then alphabetically
             * for an attribute. The result will then be ordered after the first entry.
             * If two results have the same rank however, they will be ordered after the
             * second order-by value, and so on.
             * @default {orderBy:'$$score$$', sortOrder:'DESC'}
             * See {@link sap.bc.ina.api.sina.sinabase.Sina#createSearchQuery} for examples.
             */
            setOrderBy: function(orderBy) {
              this._resetResultSet();
              this.orderBy = orderBy || {
                orderBy: '$$score$$',
                sortOrder: 'DESC'
              };
              return this;
            }
        });

        // =========================================================================
        // search query
        // =========================================================================
        module.SearchQuery = function() {
            this.init.apply(this, arguments);
        };
        module.SearchQuery.prototype = $.extend({}, module.Query.prototype, {
            
            /**
             * A query that yields results suitable for a simple result list.
             * @constructs sap.bc.ina.api.sina.sinabase.SearchQuery
             * @augments {sap.bc.ina.api.sina.sinabase.Query}
             * @private
             */
            init: function() {
                module.Query.prototype.init.apply(this, arguments);
            }
        });

        // =========================================================================
        // suggestion query
        // =========================================================================
        module.SuggestionQuery = function() {
            this.init.apply(this, arguments);
        };
        module.SuggestionQuery.prototype = $.extend({}, module.Query.prototype, {
            
            /**
             * A SINA suggestion query.
             * Use {@link sap.bc.ina.api.sina.sinabase.Sina.createSuggestionQuery} instead
             * of this private constructor.
             * @constructs sap.bc.ina.api.sina.sinabase.SuggestionQuery
             * @augments {sap.bc.ina.api.sina.sinabase.Query}
             * @param  {Object} properties Configuration object.
             * @since SAP HANA SPS 08
             * @private
             */
            init: function() {
                module.Query.prototype.init.apply(this, arguments);
            }
        });

        // =========================================================================
        // class Sina Error
        // =========================================================================
        module.SinaError = function(){this.init.apply(this,arguments);};

        module.SinaError.SEVERITY_ERROR = 3;
        module.SinaError.SEVERITY_WARNING = 2;
        module.SinaError.SEVERITY_INFO = 1;
        module.SinaError.prototype = {

          /**
           * A sina error that is contained in a perspective.
           * @ignore
           * @constructs sap.bc.ina.api.sina.sinabase.SinaError
           */
          init: function(properties) {
            this.SEVERITY_ERROR = 3;
            this.SEVERITY_WARNING = 2;
            this.SEVERITY_INFO = 1;
            this.message = properties.message || "";
            this.errorCode = properties.errorCode || null;
            this.severity = properties.severity || module.SinaError.ERROR;
          },

          getErrorCode: function() {
            return this.errorCode;
          },

          getMessage: function() {
            return this.message;
          },

          getSeverity : function(){
            return this.severity;
          },
          setSeverity : function(severity){
            this.severity = severity;
          }

        };

    };

    if (isXS) {
        executeSinaBase($.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"], function($) {
            executeSinaBase($);
        });
    } else {
        executeSinaBase();
    }

}(typeof window === 'undefined' ? $ : window, typeof window === 'undefined'));