define([
'bop/js/EmptyCondition',
'bop/js/api/operation/CompositeCondition',
'bop/js/api/operation/RelationOperator',
'bop/js/api/operation/SimpleCondition',
'operation/js/api/Operator',
'operation/js/query/QueryParameterDescription'
], function (
EmptyCondition,
CompositeCondition,
RelationOperator,
SimpleCondition,
Operator,
QueryParameterDescription
) {
'use strict';
/**
* An API object providing methods used for building a certain {@link operation/js/api/Condition Condition}.
*
* @AbcsAPI stable
* @version 15.4.5
* @exports operation/js/api/Conditions
*
* @see {@link operation/js/api/Condition Condition}
* @see {@link module:operation/js/api/Operator Operator}
*/
var Conditions = function() {
AbcsLib.throwStaticClassError();
};
Conditions._PROPERTY_UNDEFINED = 'Simple condition can\'t be created without passing Property instance';
Conditions._NO_PARAMETER_PASSED_OR_METHOD = 'There is no parameter passed. Please call QueryBuilder.or() method with appropriate params';
Conditions._NO_PARAMETER_PASSED_ADD_METHOD = 'There is no parameter passed. Please call QueryBuilder.and() method with appropriate params';
/**
* Empty {@link operation/js/api/Condition Condition} without any restriction.
*
* @type {operation/js/api/Condition}
*
* @public
* @static
* @constant
* @example
* <caption>
* Creates an instance of {@link operation/js/api/Condition Condition} without any restriction.
* </caption>
*
* var condition = Conditions.EMPTY;
*/
Conditions.EMPTY = new EmptyCondition();
/**
* Creates a new instance of {@link operation/js/api/Condition Condition} with a single restriction.
*
* @AbcsAPI stable
* @version 15.4.5
* @param {entity/js/api/Property} property - property used by this condition
* @param {module:operation/js/api/Operator} operator - applied operator
* @param {String} value
* @returns {operation/js/api/Condition}
*
* @public
* @static
* @example
* <caption>
* Create an instance of {@link operation/js/api/Condition Condition} with a single restriction.
* </caption>
*
* var condition = Conditions.SIMPLE(firstName, Operator.EQUALS, 'Martin');
*/
Conditions.SIMPLE = function(property, operator, value) {
if (!property) {
throw Conditions._PROPERTY_UNDEFINED;
}
var queryOperator = operator ? operator : Operator.EQUALS;
var queryParamDesc = new QueryParameterDescription(property);
return new SimpleCondition(queryParamDesc, queryOperator, value ? value : '');
};
/**
* Creates new composite {@link operation/js/api/Condition Condition} which consist of multiple {@link operation/js/api/Condition Condition}s joining
* them using an AND operator.
*
* @AbcsAPI stable
* @version 15.4.5
* @param {operation/js/api/Condition[]} arguments - either array of Condition's or simply Condition's separated and passed one by one
* @returns {operation/js/api/Condition}
*
* @public
* @static
* @example
* <caption>
* Creates an instance of {@link operation/js/api/Condition Condition} with two sub-restrictions combining them using an AND operator.
* </caption>
*
* // Finds all employees with firstname = 'Martin' and lastname = 'Janicek'.
*
* var composite = Conditions.AND(
* Conditions.SIMPLE(firstName, Operator.EQUALS, 'Martin'),
* Conditions.SIMPLE(lastName, Operator.EQUALS, 'Janicek')
* );
*
* @example
* <caption>
* Creates an instance of {@link operation/js/api/Condition Condition} with two sub-restrictions combining them using an AND operator -
* this time using an array of {@link operation/js/api/Condition Condition}s.
* </caption>
*
* // Finds all employees with firstname = 'Martin' and lastname = 'Janicek'.
*
* var conditions = [];
* conditions.push(Conditions.SIMPLE(firstName, Operator.EQUALS, 'Martin'));
* conditions.push(Conditions.SIMPLE(lastName, Operator.EQUALS, 'Janicek'));
* var composite = Conditions.AND(conditions);
*
* @example
* <caption>
* Creates a more complex {@link operation/js/api/Condition Condition} combining multiple AND and OR operators.
* </caption>
*
* // Finds all employees whose name is either 'Martin Janicek' or 'Ondrej Brejla'
*
* var condition = Conditions.OR(
* Conditions.AND(
* Conditions.SIMPLE(firstName, Operator.EQUALS, 'Martin'),
* Conditions.SIMPLE(lastName, Operator.EQUALS, 'Janicek')
* ),
* Conditions.AND(
* Conditions.SIMPLE(firstName, Operator.EQUALS, 'Ondrej'),
* Conditions.SIMPLE(lastName, Operator.EQUALS, 'Brejla')
* )
* );
*/
Conditions.AND = function() {
if (arguments.length < 1) {
throw Conditions._NO_PARAMETER_PASSED_ADD_METHOD;
} else {
// If an array of elements was passed directly, simply behave as if it was number of individual parameters
if (AbcsLib.isArray(arguments[0])) {
return Conditions._createConditon(arguments[0], RelationOperator.AND);
}
return Conditions._createConditon(Array.prototype.slice.call(arguments, 0), RelationOperator.AND);
}
};
/**
* Creates new composite {@link operation/js/api/Condition Condition} which consists of multiple {@link operation/js/api/Condition Condition}s joining
* them using an OR operator.
*
* @AbcsAPI stable
* @version 15.4.5
* @param {operation/js/api/Condition[]} arguments - either array of Condition's or simply Condition's separated and passed one by one
* @returns {operation/js/api/Condition}
*
* @public
* @static
* @example
* <caption>
* Creates an instance of composite {@link operation/js/api/Condition Condition} with two sub-restrictions combining them using an OR operator.
* </caption>
*
* // Finds all employees with firstname = 'Martin' or firstname = 'Ondrej'.
*
* var composite = Conditions.OR(
* Conditions.SIMPLE(firstName, Operator.EQUALS, 'Martin'),
* Conditions.SIMPLE(firstName, Operator.EQUALS, 'Ondrej')
* );
*
* @example
* <caption>
* Creates an instance of composite {@link operation/js/api/Condition Condition} with two sub-restrictions combining them using an OR operator -
* this time using an array of {@link operation/js/api/Condition Condition}s.
* </caption>
*
* // Finds all employees with firstname = 'Martin' or firstname = 'Ondrej'.
*
* var conditions = [];
* conditions.push(Conditions.SIMPLE(firstName, Operator.EQUALS, 'Martin'));
* conditions.push(Conditions.SIMPLE(firstName, Operator.EQUALS, 'Ondrej'));
* var composite = Conditions.OR(conditions);
*
* @example
* <caption>
* Creates a more complex composite {@link operation/js/api/Condition Condition} combining AND and OR operators.
* </caption>
*
* // Finds all employees whose name is either 'Martin Janicek' or 'Ondrej Brejla'
*
* var condition = Conditions.OR(
* Conditions.AND(
* Conditions.SIMPLE(firstName, Operator.EQUALS, 'Martin'),
* Conditions.SIMPLE(lastName, Operator.EQUALS, 'Janicek')
* ),
* Conditions.AND(
* Conditions.SIMPLE(firstName, Operator.EQUALS, 'Ondrej'),
* Conditions.SIMPLE(lastName, Operator.EQUALS, 'Brejla')
* )
* );
*/
Conditions.OR = function() {
if (arguments.length < 1) {
throw Conditions._NO_PARAMETER_PASSED_OR_METHOD;
} else {
// If an array of elements was passed directly, simply behave as if it was number of individual parameters
if (AbcsLib.isArray(arguments[0])) {
return Conditions._createConditon(arguments[0], RelationOperator.OR);
}
return Conditions._createConditon(Array.prototype.slice.call(arguments, 0), RelationOperator.OR);
}
};
/**
* Creates a new {@link Condition} instance build using the given JSON definition.
*
* <p>
* This is revert operation to {@link Condition#getDefinition} method. If one invokes:
*
* <br/><br/>
* <code>
* var def = condition.getDefinition();<br/>
* var recreatedCondition = Conditions.createFromDefinition(def);
* </code>
* <br/><br/>
*
* It is guaranteed that the structure of 'recretedCondition' will stays the same as was
* in the original condition.
* </p>
*
* @static
*
* @param {Object[]} conditionsJSON - stored JSON definition
* @param {Object[]} queryDescription
* @returns {Condition}
*/
Conditions.createFromDefinition = function(conditionsJSON, queryDescription) {
// This is a composite condition and thus we need to proceed it recursively
if (conditionsJSON.relationOperator && conditionsJSON.conditions) {
var operator = RelationOperator.forName(conditionsJSON.relationOperator);
var conditions = [];
for (var i = 0; i < conditionsJSON.conditions.length; i++) {
var conditionJSON = conditionsJSON.conditions[i];
var condition = Conditions.createFromDefinition(conditionJSON, queryDescription);
if (condition) {
conditions.push(condition);
}
}
return new CompositeCondition(operator, conditions);
}
return SimpleCondition.createFromDefinition(conditionsJSON, queryDescription);
};
/**
* Creates a {@link Condition} based on the given parameter.
*
* <p>
* If just one {@link Condition} was passed to the function, it will return simple {@link SimpleCondition}.
* If more than one {@link Condition}s were passed to the function, it will build up a {@link CompositeCondition}
* </p>
*
* @static
*
* @param {Condition[]} conditions
* @param {RelationOperator} operator
* @returns {Condition}
*/
Conditions._createConditon = function(conditions, operator) {
if (conditions.length === 1) {
return conditions[0];
}
return new CompositeCondition(operator, conditions);
};
return Conditions;
});