/* eslint-disable no-use-before-define */
define([
'entity/js/api/Entity',
'entity/js/api/Property'
], function(
Entity,
Property
) {
'use strict';
/**
* An API object representing expandable reference of an {@link entity/js/api/Entity Entity}.
*
* <p>
* <code>ExpandableReference</code> gives client of {@link module:api/js/Operations.read Operations.read(..)} an opportunity to automatically expand some of the references from the fetched
* {@link entity/js/api/Entity Entity}.
* </p>
*
* @AbcsAPI stable
* @version 17.1.3
* @exports operation/js/api/ExpandableReference
*
* @constructor
* @private
*
* @param {operation/js/api/ExpandableReference[]} childExpandables
*
* @see {@link operation/js/api/ExpandableReference.create ExpandableReference.create(..)} to see how to create instances of <code>ExpandableReference</code>s
* @see {@link module:api/js/Operations.read Operations.read(..)} to see where and how to use <code>ExpandableReference</code>
*/
var ExpandableReference = function(childExpandables) {
this._childExpandables = childExpandables;
};
/**
* Creates an instance of <code>ExpandableReference</code> that could be passed into {@link module:api/js/Operations.read Operations.read(..)} so that except for main data, it fetch
* also embeded reference {@link entity/js/api/Entity Entity} record (otherwise there would be just the reference ID).
*
* You have two options how to create an instance of <code>ExpandableReference</code>:
* <ul>
* <li>
* Pass an instance of {@link entity/js/api/Entity Entity} in which case all references between the main and the given {@link entity/js/api/Entity Entity} will be expanded.
* </li>
* <li>
* Pass an instance of {@link entity/js/api/Property Property} which represents one particular mapping property between two entities.
* </li>
* </ul>
*
* @AbcsAPI stable
* @version 17.1.3
*
* @param {entity/js/api/Entity | entity/js/api/Property} value - Either an {@link entity/js/api/Entity Entity} that should be embedded or exact mapping {@link entity/js/api/Property Property} that refers to the {@link entity/js/api/Entity Entity} that should be embedded.
* @param {Object} [optionalParams] - Object literal with following possible parameters.
* @param {operation/js/api/ExpandableReference | operation/js/api/ExpandableReference[]} [optionalParams.expand] - Either a single instance of {@link operation/js/api/ExpandableReference ExpandableReference} or an array of {@link operation/js/api/ExpandableReference ExpandableReference}s for deeper children expansion.
*
* @returns {operation/js/api/ExpandableReference}
*
* @see {@link module:api/js/Operations.read Operations.read(..)} to see where and how to use <code>ExpandableReference</code>
*
* @example
* <caption>
* Creates an expandable reference that will expand all relations between Employee and Department entities.
* </caption>
*
* require([
* 'operation/js/api/ExpandableReference'
* ], function(
* ExpandableReference
* ) {
* var department = Abcs.Entities().findById('my.custom.bop.Department');
* var departmentRef = ExpandableReference.create(department);
* });
*
* @example
* <caption>
* Creates an expandable reference for just the specific mapping property.
* </caption>
*
* require([
* 'operation/js/api/ExpandableReference'
* ], function(
* ExpandableReference
* ) {
* var employee = Abcs.Entities().findById('my.custom.bop.Employee');
* var ref2Department = employee.getProperty('ref2Department');
* var emp2DeptRef = ExpandableReference.create(ref2Department);
* });
*
* @example
* <caption>
* Creates an <code>ExpandableReference</code> object to get an Employee data together with an embedded Department record that recursively contains embedded DepartmentType record.
* </caption>
*
* require([
* 'operation/js/api/ExpandableReference'
* ], function(
* ExpandableReference
* ) {
* var employee = Abcs.Entities().findById('my.custom.bop.Employee');
* var department = Abcs.Entities().findById('my.custom.bop.Department');
* var departmentType = Abcs.Entities().findById('my.custom.bop.DepartmentType');
*
* var expandableReference = ExpandableReference.create(department, {
* expand: ExpandableReference.create(departmentType)
* });
* });
*/
ExpandableReference.create = function (value, optionalParams) {
AbcsLib.checkParameterCount(arguments, 1, 1);
AbcsLib.checkDataType(value, [Entity, Property]);
var childExpandables = optionalParams ? optionalParams.expand : undefined;
if (optionalParams || AbcsLib.isDefined(optionalParams)) {
AbcsLib.checkDataType(optionalParams, AbcsLib.Type.OBJECT);
AbcsLib.checkObjectLiteral(optionalParams, ['expand']);
if (childExpandables || AbcsLib.isDefined(childExpandables)) {
AbcsLib.checkDataType(childExpandables, [ExpandableReference, AbcsLib.Type.ARRAY]);
if (AbcsLib.isArray(childExpandables)) {
// If this is an array of expandable references, check typ of each of the given items
for (var i = 0; i < childExpandables.length; i++) {
AbcsLib.checkDataType(childExpandables[i], ExpandableReference);
}
} else {
// Otherwise turn the single instance into an array with one item to to simplify processing
childExpandables = [childExpandables];
}
}
}
if (value instanceof Entity) {
return new ExpandableEntity(value, childExpandables);
} else if (value instanceof Property) {
return new ExpandableProperty(value, childExpandables);
} else {
throw new Error('ExpandableReference should never be created using different Object than either Entity or Property. The given Object is: ' + JSON.stringify(value));
}
};
/**
* Gets an array of {@link entity/js/api/Relation Relation}s associated with this <code>ExpandableReference</code> instance.
*
* <p>
* Return value depends on how this <code>ExpandableReference</code> was constructed:
*
* <ul>
* <li>
* If using an instance of {@link entity/js/api/Property Property} representing one particular mapping property, {@link entity/js/api/Relation Relation} associated with that mapping property will be returned.
* </li>
* <li>
* If using an instance of {@link entity/js/api/Entity Entity}, all {@link entity/js/api/Relation Relation}s between the main and the given {@link entity/js/api/Entity Entity} will be returned.
* </li>
* </ul>
* </p>
*
* @param {entity/js/api/Entity} entity - The main BO for which this <code>ExpandableReference</code> instance were created.
* @returns {entity/js/api/Relation[]}
*/
ExpandableReference.prototype.getRelations = function(entity) { // eslint-disable-line no-unused-vars
};
/**
* Gets an array of {@link operation/js/api/ExpandableReference ExpandableReference}s for all requested child expansions of this one.
*
* @returns {operation/js/api/ExpandableReference[]}
*/
ExpandableReference.prototype.getChildExpandables = function() {
return this._childExpandables;
};
var ExpandableProperty = function(mappingProperty, childExpandables) {
ExpandableReference.apply(this, [childExpandables]);
this._mappingProperty = mappingProperty;
};
AbcsLib.extend(ExpandableProperty, ExpandableReference);
ExpandableProperty.prototype.getRelations = function(entity) {
return [entity.getRelation(this._mappingProperty)];
};
var ExpandableEntity = function(embeddedEntity, childExpandables) {
ExpandableReference.apply(this, [childExpandables]);
this._embeddedEntity = embeddedEntity;
};
AbcsLib.extend(ExpandableEntity, ExpandableReference);
ExpandableEntity.prototype.getRelations = function(entity) {
return entity.getRelationsForEntity(this._embeddedEntity);
};
return ExpandableReference;
});