/* eslint-disable no-use-before-define */
define([
'core/js/api/utils/StringUtils',
'operation/js/api/PaginationCursor'
], function(
StringUtils,
PaginationCursor
) {
'use strict';
/**
* Represents result returned from particular {@link operation/js/api/Operation#perform Operation.perform(..)} method call.
*
* <p>
* Each {@link operation/js/api/Operation#perform Operation.perform(..)} method call returns an instance of {@link operation/js/api/OperationResult OperationResult}.
* It either:
* <ul>
* <li>
* Provides returned data in case {@link operation/js/api/Operation Operation} performed correctly. <br/>
* It also can contain any other metadata which Business Object Provider decides to return. For example {@link operation/js/api/PaginationCursor PaginationCursor} can be available if the perfomed
* {@link operation/js/api/Operation Operation} has type {@link operation/js/api/Operation.Type.READ_MANY Operation.Type.READ_MANY} set and provider implemented capability to paginate through
* the records.
* </li>
* <li>
* Provides error code, message and possibly any other additional error information in case {@link operation/js/api/Operation Operation} performed incorrectly.
* </li>
* </ul>
*
* To check the result of {@link operation/js/api/Operation#perform Operation.perform(..)} call, you can use:
* <ul>
* <li>
* {@link operation/js/api/OperationResult#isSuccess OperationResult.isSuccess()} to check if the call was performed correctly and resulted in a {@link operation/js/api/OperationResult.Success OperationResult.Success}.
* </li>
* <li>
* {@link operation/js/api/OperationResult#isFailure OperationResult.isFailure()} to check if the call was performed incorrectly and resulted in a {@link operation/js/api/OperationResult.Failure OperationResult.Failure}.
* </li>
* </ul>
* </p>
*
* @AbcsAPI stable
* @version 17.1.1
* @exports operation/js/api/OperationResult
*
* @constructor
* @private
*
* @see {@link operation/js/api/Operation Operation}
* @see {@link operation/js/api/Operation#perform Operation.perform(..)}
*/
var OperationResult = function() {
AbcsLib.throwStaticClassError();
};
/**
* Creates new instance of {@link operation/js/api/OperationResult.Success OperationResult.Success} result.
*
* @AbcsExtension stable
* @version 17.1.1
* @public
* @static
*
* @param {Object} [data] - REST data response.
* @param {operation/js/api/PaginationCursor} [paginationCursor] - Metadata describing data pagination if it was requested.
* @param {Object} [additionalInfo] - Additional information about the successful operation.
* @returns {operation/js/api/OperationResult.Success}
*/
/*
* @param {String} [etag] - the etag for the http response
*/
OperationResult.success = function(data, paginationCursor, additionalInfo, etag) {
AbcsLib.checkThis(this);
if (paginationCursor) {
AbcsLib.checkDataType(paginationCursor, PaginationCursor);
}
AbcsLib.checkParameterCount(arguments, 0, 4);
return new Success(data, paginationCursor, additionalInfo, etag);
};
/**
* Creates new instance of {@link operation/js/api/OperationResult.Failure OperationResult.Failure} result.
*
* @AbcsExtension stable
* @version 17.1.1
* @public
* @static
*
* @param {String} message - Message describing in detail why {@link operation/js/api/Operation#perform Operation.perform(..)} method failed.
* @param {Number} [code] - Error code for better identification of what type of error caused {@link operation/js/api/Operation#perform Operation.perform(..)} method to fail.
* @param {Object} [additionalInfo] - Additional information about the failure.
* @returns {operation/js/api/OperationResult.Failure}
*
* @example
* <caption>
* Creates an instance of {@link operation/js/api/OperationResult.Failure OperationResult.Failure} result with only message text set.
* </caption>
*
* var error = OperationResult.failure('This is an example of error message.');
*
* @example
* <caption>
* Creates an instance of {@link operation/js/api/OperationResult.Failure OperationResult.Failure} result with message text and error code set.
* </caption>
*
* var error = OperationResult.failure('Not Found.', 404);
*
* @example
* <caption>
* Creates an instance of {@link operation/js/api/OperationResult.Failure OperationResult.Failure} result with message text, error code and additional information set.
* </caption>
*
* var error = OperationResult.failure('Not Found.', 404, {
* foo: 'You can include anything you want here',
* bar: {
* barbar: 'You can even structure additional information any way you need'
* }
* });
*/
OperationResult.failure = function(message, code, additionalInfo) {
AbcsLib.checkThis(this);
AbcsLib.checkDefined(message, 'message');
AbcsLib.checkDataType(message, AbcsLib.Type.STRING);
if (code) {
AbcsLib.checkDataType(code, AbcsLib.Type.NUMBER);
}
AbcsLib.checkParameterCount(arguments, 1, 2);
return new Failure(message, code, additionalInfo);
};
/**
* Check whether the given object is an <code>OperationResult.Success</code> instance or not.
*
* @param {Object} obj - An arbitrary object to check.
* @returns {Boolean}
*/
OperationResult.isSuccessResult = function(obj) {
return obj instanceof OperationResult && obj.isSuccess();
};
/**
* Check whether the given object is an <code>OperationResult.Failure</code> instance or not.
*
* @param {Object} obj - An arbitrary object to check.
* @returns {Boolean}
*/
OperationResult.isFailureResult = function(obj) {
return obj instanceof OperationResult && obj.isFailure();
};
/**
* Checks whether this {@link operation/js/api/OperationResult OperationResult} is {@link operation/js/api/OperationResult.Success OperationResult.Success} or not.
*
* @AbcsAPI stable
* @version 17.1.1
*
* @returns {Boolean} true if this {@link operation/js/api/OperationResult OperationResult} is {@link operation/js/api/OperationResult.Success OperationResult.Success}, false otherwise
*
* @example
* <caption>
* Performs an existing {@link operation/js/api/Operation Operation} and check the result using {@link operation/js/api/OperationResult#isSuccess OperationResult.isSuccess()} method.
* </caption>
*
* var employee = Abcs.Entities().findById('my.custom.bop.Employee');
* var operation = Abcs.Operations().create({
* entity: employee,
* record: {
* firstName: 'Martin',
* lastName: 'Janicek',
* age: 28
* }
* });
*
* operation.perform().then(function(operationResult) {
* if (operationResult.isSuccess()) {
* // Insert code you want to perform after record being created
* }
* });
*/
OperationResult.prototype.isSuccess = function() {
return this instanceof Success;
};
/**
* Checks whether this {@link operation/js/api/OperationResult OperationResult} is {@link operation/js/api/OperationResult.Failure OperationResult.Failure} or not.
*
* @AbcsAPI stable
* @version 17.1.1
*
* @returns {Boolean} true if this {@link operation/js/api/OperationResult OperationResult} is {@link operation/js/api/OperationResult.Failure OperationResult.Failure}, false otherwise
*
* @example
* <caption>
* Performs an existing {@link operation/js/api/Operation Operation} and check the result using {@link operation/js/api/OperationResult#isFailure OperationResult.isFailure()} method.
* </caption>
*
* var employee = Abcs.Entities().findById('my.custom.bop.Employee');
* var operation = Abcs.Operations().create({
* entity: employee,
* record: {
* firstName: 'Martin',
* lastName: 'Janicek',
* age: 28
* }
* });
*
* operation.perform().then(function(operationResult) {
* // Do something when your operation succeed
* }).catch(function(operationResult) {
* if (operationResult.isFailure()) {
* // Insert code you want to perform if record creation failed
* }
* });
*/
OperationResult.prototype.isFailure = function() {
return this instanceof Failure;
};
OperationResult._ENTITY_NOT_FOUND = 'Not Found';
OperationResult._INSUFFICIENT_PRIVILEGES_EXCEPTION = 'InsufficientPrivilegeException';
/**
* Checks whether this <code>OperationResult</code> instance represents failure caused by insufficient privileges or not.
*
* @returns {Boolean}
*/
OperationResult.prototype.isInsufficientPrivileges = function() {
if (this.isFailure()) {
var errorMessage = this.getMessage();
var errorCode = this.getCode();
if (errorCode === 403 && StringUtils.contains(errorMessage, OperationResult._INSUFFICIENT_PRIVILEGES_EXCEPTION)) {
return true;
}
}
return false;
};
/**
* Checks whether this <code>OperationResult</code> instance represents failure caused by missing entity.
*
* @returns {Boolean}
*/
OperationResult.prototype.isNotFoundEntity = function() {
if (this.isFailure()) {
var errorMessage = this.getMessage();
var errorCode = this.getCode();
if (errorCode === 404 && StringUtils.contains(errorMessage, OperationResult._ENTITY_NOT_FOUND)) {
return true;
}
}
return false;
};
/**
* Represents error result coming from {@link operation/js/api/Operation#perform Operation.perform(..)} method.
*
* @AbcsAPI stable
* @version 17.1.1
* @memberof operation/js/api/OperationResult
* @constructor
* @private
*
* @param {String} message
* @param {Number} [code]
* @param {Object} [additionalInfo]
*/
var Failure = function (message, code, additionalInfo) {
this._code = code;
this._message = message;
this._additionalInfo = additionalInfo;
};
AbcsLib.extend(Failure, OperationResult);
/**
* Gets the message describing why {@link operation/js/api/Operation#perform Operation.perform(..)} method failed.
*
* @AbcsAPI stable
* @version 17.1.1
* @memberof operation/js/api/OperationResult.Failure
*
* @returns {String}
*/
Failure.prototype.getMessage = function() {
return this._message;
};
/**
* Gets the {@link operation/js/api/OperationResult.Failure OperationResult.Failure} code for identification of what type of error caused {@link operation/js/api/Operation#perform Operation.perform(..)} method to fail.
*
* @AbcsAPI stable
* @version 17.1.1
* @memberof operation/js/api/OperationResult.Failure
*
* @returns {Number}
*/
Failure.prototype.getCode = function() {
return this._code;
};
/**
* Gets additional information which can be used to pass any other proprietary information into client's {@link operation/js/api/OperationResult OperationResult} handler.
*
* @AbcsAPI stable
* @version 17.1.1
* @memberof operation/js/api/OperationResult.Failure
*
* @returns {Object}
*
* @example
* <caption>
* Performs an existing {@link operation/js/api/Operation Operation} and use additional information to behave appropriately in {@link operation/js/api/OperationResult OperationResult} handler.
* </caption>
*
* var employee = Abcs.Entities().findById('my.custom.bop.Employee');
* var operation = Abcs.Operations().create({
* entity: employee,
* record: {
* firstName: 'Martin',
* lastName: 'Janicek',
* age: 28
* }
* });
*
* operation.perform().then(function(operationResult) {
* // Do something when your operation succeed
* }).catch(function(operationResult) {
* if (operationResult.isFailure()) {
* // Let's assume that Operation implementor included Object literal with 'log' field for better error tracing
* var additionalInfo = operationResult.getAdditionalInfo();
* var log = additionalInfo.log;
* if (log) {
* // Insert code you want to perform if record creation failed and 'log' info is available
* }
* }
* });
*/
Failure.prototype.getAdditionalInfo = function() {
return this._additionalInfo;
};
/**
* Represents success result coming from {@link operation/js/api/Operation#perform Operation.perform(..)} method.
*
* @AbcsAPI stable
* @version 17.1.1
* @memberof operation/js/api/OperationResult
* @constructor
* @private
*
* @param {Object} data
* @param {PaginationCursor} [paginationCursor]
* @param {Object} [additionalInfo]
* @param {String} [etag]
*/
var Success = function (data, paginationCursor, additionalInfo, etag) {
this._data = data;
this._paginationCursor = paginationCursor;
this._additionalInfo = additionalInfo;
this._etag = etag;
};
AbcsLib.extend(Success, OperationResult);
/**
* Returns data coming from {@link operation/js/api/Operation#perform Operation.perform(..)} method.
*
* <p>
* This can be anything and it depends on the {@link operation/js/api/Operation Operation} author to decide how the resulted data are structured.
* Usually in case of {@link operation/js/api/Operation.Type.READ_MANY Operation.Type.READ_MANY}, the {@link operation/js/api/Operation#perform Operation.perform(..)}
* returns array of {@link module:api/js/Operations~Record Record}s in it's data field, but it's not a rule and different Business Object Provider's can vary in how they
* process and return their results.
* </p>
*
* @AbcsAPI stable
* @version 17.1.1
* @memberof operation/js/api/OperationResult.Success
*
* @returns {module:api/js/Operations~Record | module:api/js/Operations~Record[]}
*/
Success.prototype.getData = function() {
return this._data;
};
/**
* Sets data records for this result.
*
* <p>
* This should never become public API, it's only required insternally by OperationBuilder doing data mash-ups.
* </p>
*
* @param {Object<String, Object>} data
*/
Success.prototype.setData = function(data) {
this._data = data;
};
/**
* Gets the {@link operation/js/api/PaginationCursor PaginationCursor} returned by the performed {@link operation/js/api/Operation Operation}.
*
* @AbcsAPI stable
* @version 17.1.1
* @memberof operation/js/api/OperationResult.Success
*
* @returns {operation/js/api/PaginationCursor}
*/
Success.prototype.getPaginationCursor = function() {
return this._paginationCursor;
};
/**
* Gets additional information returned by the performed {@link operation/js/api/Operation Operation}.
*
* <p>
* Additional info has no formal structure defined. It's up to the {@link operation/js/api/Operation Operation} author whether s(he) needs or wants to pass some custom
* values as part of the {@link operation/js/api/OperationResult OperationResult} and as such, the format is completely up to the author. It can be complex Object
* literal, plain String value or any other valid JS construct.
* </p>
*
* <p>
* Consult with BOP author to learn what an {@link operation/js/api/Operation Operation} may return as custom results.
* </p>
*
* @AbcsAPI stable
* @version 17.1.1
* @memberof operation/js/api/OperationResult.Success
*
* @returns {Object}
*/
Success.prototype.getAdditionalInfo = function() {
return this._additionalInfo;
};
Success.prototype.getETag = function() {
return this._etag;
};
return OperationResult;
});