/**
* Copyright© 2016, Oracle and/or its affiliates. All rights reserved.
*/
/**
* Class that holds the StorageCollection resource. StorageCollections contain Storage objects
* which can be used to persist data in Oracle Mobile Cloud Service.
* @constructor
* @global
*/
function StorageCollection(name, userId, userIsolated, backend, utils, logger, platform) {
var HEADERS = utils.HEADERS;
var APPLICATION_JSON = utils.ACCEPT_TYPES.APPLICATION_JSON;
var HTTP_METHODS = utils.HTTP_METHODS;
var _backend = backend;
var _storage = backend.storage;
var _userId = utils.validateConfiguration(userId);
var _data;
var storageCollection = this;
this._getBackend = function(){
return _backend;
};
this.getUserIsolated = function(){
return _data ? _data.userIsolated : userIsolated;
};
/**
* Returns storage object for current storage collection.
*
* @return storage object data for current storage collection.
*/
this.getStorage = function(){
return _storage;
};
/**
* Returns user ID for current storage collection.
*
* @return user ID for current storage collection.
*/
this.getUserId = function(){
return _userId ;
};
/**
* Returns data for current storage collection.
*
* @return storage object data for current storage collection.
*/
this.getData = function(){
return _data;
};
/**
* The ID of the StorageCollection.
* @type {String}
*/
this.id = utils.validateConfiguration(name);
/**
* The description of the StorageCollection.
* @type {String}
* @deprecated Will be deleted in next version. Use {@link StorageCollection#getDescription} instead.
*/
this.description = _data ? _data.description : undefined;
/**
* The description of the StorageCollection.
* @type {String}
* @deprecated Will be deleted in next version. Use {@link StorageCollection#getDescription} instead.
*/
this.getDescription = function(){
if(_data){
return _data.description;
} else {
logger.warn('Collection metadata was not loaded yet, please use StorageCollection.loadMetadata to load metadata.');
}
};
/**
* Load collection metadata
* @returns {Promise<StorageCollection|NetworkResponse>}
*/
this.loadMetadata = function(){
var _this = this;
var headers = _backend.getHttpHeaders(utils.MODULE_NAMES.STORAGE);
headers[utils.HEADERS.ACCEPT] = utils.ACCEPT_TYPES.APPLICATION_JSON;
return platform.invokeService({
method: utils.HTTP_METHODS.GET,
url: _backend.getPlatformUrl("storage/collections/" + _this.id),
headers: headers
}).then(invokeServiceSuccess);
function invokeServiceSuccess(response) {
_data = response.data;
_this.description = response.data.description;
return _this;
}
};
/**
* Callback invoked after successfully fetching a StorageCollection.
* @callback StorageCollection~getObjectsSuccessCallback
* @param objects {Array} An array of StorageObjects downloaded from the service.
* @deprecated Use promises instead
*/
/**
* Callback invoked on error.
* @callback StorageCollection~errorCallback
* @param statusCode {Number} Any HTTP status code returned from the server, if available.
* @param message {String} The HTTP payload from the server, if available, or an error message.
* @deprecated Use promises instead
*/
/**
* Returns a list of StorageObjects from the collection starting from the offset and up to the limit. The service may return fewer objects.
* 1. If the collection is a shared collection, then it returns all the objects.
* 2. If the collection is a user-isolated collection and allObjects is false, then it returns the objects which belong to the current user.
* 3. If the collection is user-isolated collection, and allObjects is true, then it returns all the objects in the collection.
* The objects might belong to other users. And the current user MUST have READ_ALL or READ_WRITE_ALL permission.
* @param offset {Number} The offset at which to start. Must be greater than 0.
* @example offset: "3"
* @param limit {Number} The max number of StorageObjects to return. Must be non-negative.
* @example limit: "2"
* @param allObjects {Boolean} whether to return all the objects in the list.
* @param [successCallback] {StorageCollection~getObjectsSuccessCallback} Callback invoked on success (deprecated use promises instead).
* @param [errorCallback] {StorageCollection~errorCallback} Callback invoked on error (deprecated use promises instead).
* @return {Promise.<Array.<StorageObject>|NetworkResponse>}
*/
this.getObjects = function(offset, limit, allObjects, successCallback, errorCallback) {
var headers = _backend.getHttpHeaders(utils.MODULE_NAMES.STORAGE);
headers[HEADERS.ACCEPT] = APPLICATION_JSON;
// TODO: remove the if in next version
if(typeof allObjects === 'function'){
logger.warn('getObjects method without allObjects parameter is deprecated in next version, please add allObjects parameter.');
errorCallback = successCallback;
successCallback = allObjects;
allObjects = false;
}
var url = "storage/collections/" + storageCollection.id + "/objects";
if(!!offset) {
url += url.indexOf("?") === -1 ? "?" : "&";
url += "offset=" + offset;
}
if(!!limit) {
url += url.indexOf("?") === -1 ? "?" : "&";
url += "limit=" + limit;
}
if (storageCollection.getUserIsolated() && allObjects) {
url += url.indexOf("?") === -1 ? "?" : "&";
url += "user=*";
} else if(!!storageCollection.getUserIsolated() && !!storageCollection.getUserId()){
url += url.indexOf("?") === -1 ? "?" : "&";
url += "user=" + storageCollection.getUserId();
}
return platform.invokeService({
method: HTTP_METHODS.GET,
url: _backend.getPlatformUrl(url),
headers: headers
}).then(invokeServiceSuccess, invokeServiceError);
function invokeServiceSuccess(response) {
var objects = [];
var objectsJson = response.data;
for(var i = 0; i < objectsJson.items.length; i++) {
objects[objects.length] = new StorageObject(storageCollection, objectsJson.items[i], utils, platform);
}
if (successCallback) {
successCallback(objects);
}
return objects;
}
function invokeServiceError(response) {
if(errorCallback) {
errorCallback(response.statusCode, response.data);
} else {
return Promise.reject(response);
}
}
};
/**
* Callback invoked after successfully fetching a StorageObject.
* @callback StorageCollection~storageObjectSuccessCallback
* @param object {StorageObject} The StorageObject downloaded from the service.
* @deprecated Use promises instead
*/
/**
* Returns a StorageObject given its ID. The contents of the object will be downloaded lazily.
* @example StorageCollection.getObject(id,successCallback,errorCallback,objectType);
* @param id {String} The ID of the Storage Object to return.
* @example id: "00e39862-9652-458b-9a82-d1a66cf1a0c7"
* @param [successCallback] {StorageCollection~storageObjectSuccessCallback} Callback invoked on success (deprecated use promises instead).
* @param [errorCallback] {StorageCollection~errorCallback} Callback invoked on error (deprecated use promises instead).
* @param objectType {object} responseType for the XMLHttpRequest Object. Default response type if not defined is json.
* @return {Promise.<StorageObject|NetworkResponse>}
*
*
* @example <caption>Example usage of StorageCollection.getObject("00e39862-9652-458b-9a82-d1a66cf1a0c7","blob")</caption>
*
* @example StorageCollection.getObject("00e39862-9652-458b-9a82-d1a66cf1a0c7","blob");
* StorageCollection.getObject("00e39862-9652-458b-9a82-d1a66cf1a0c7", "blob").then(
* function(StorageObject){
* },
* function(NetworkResponse){
* });
*
* @example StorageCollection.getObject("00e39862-9652-458b-9a82-d1a66cf1a0c7","arraybuffer");
* StorageCollection.getObject("00e39862-9652-458b-9a82-d1a66cf1a0c7","arraybuffer").then(
* function(StorageObject){
* },
* function(NetworkResponse){
* });
*
* @example StorageCollection.getObject("00e39862-9652-458b-9a82-d1a66cf1a0c7","document");
* StorageCollection.getObject("00e39862-9652-458b-9a82-d1a66cf1a0c7", "document").then(
* function(StorageObject){
* },
* function(NetworkResponse){
* });
*
* @example StorageCollection.getObject("00e39862-9652-458b-9a82-d1a66cf1a0c7","text");
* StorageCollection.getObject("00e39862-9652-458b-9a82-d1a66cf1a0c7","text").then(
* function(StorageObject){
* },
* function(NetworkResponse){
* });
*/
this.getObject = function(id, successCallback, errorCallback, objectType) {
// TODO: remove assign when callbacks is replaced with promises
if(typeof successCallback !== 'function'){
objectType = successCallback;
}
var storageObject = new StorageObject(this, _backend, utils, platform);
storageObject.id = id;
return storageObject
.readPayload(objectType)
.then(readPayloadSuccess, readPayloadError);
function readPayloadSuccess() {
if (successCallback && typeof successCallback === 'function') {
successCallback(storageObject);
}
return storageObject;
}
function readPayloadError(response) {
if(errorCallback) {
errorCallback(response.statusCode, response.data);
} else {
return Promise.reject(response);
}
}
};
/**
* Creates a new StorageObject in the collection.
* @param storageObject {StorageObject} The StorageObject to create.
* @example storageObject:
* {
* "id": " 213ddbac-ccb2-4a53-ad48-b4588244tc4c", // A service generated ID for the StorageObject. The ID is unique in the StorageCollection.
* "name" : "JSText.txt", // A user provided name for the StorageObject. A StorageCollection may have multiple StorageObjects with the same name.
* "contentLength": 798", // The length of data content in bytes stored in the StorageObject.
* "contentType" : "text/plain ", // The media-type associated with the StorageObject.
* "createdBy" : "DwainDRob", // The name of the user who created the StorageObject
* "createdOn": "Sat, 17 Oct 2015 10:33:12", // Server generated timestamp when the StorageObject was created.
* "modifiedBy": "DwainDRob", // The name of the user who last updated the StorageObject.
* "modifiedOn": "Sat, 17 Oct 2015 10:33:12" // Server generated timestamp when the StorageObject was last updated.
* }
* @param [successCallback] {StorageCollection~storageObjectSuccessCallback} Callback invoked on success (deprecated use promises instead).
* @param [errorCallback] {StorageCollection~errorCallback} Callback invoked on error (deprecated use promises instead).
* @return {Promise.<NetworkResponse|NetworkResponse>}
*/
this.postObject = function(storageObject, successCallback, errorCallback) {
return this._postOrPutStorageObject(storageObject, true, successCallback, errorCallback);
};
/**
* Updates an existing StorageObject in the collection.
* @param storageObject {StorageObject} The StorageObject to update.
* @param [successCallback] {StorageCollection~storageObjectSuccessCallback} Callback invoked on success (deprecated use promises instead).
* @param [errorCallback] {StorageCollection~errorCallback} Callback invoked on error (deprecated use promises instead).
* @return {Promise.<NetworkStorageObject|NetworkResponse>}
*/
this.putObject = function(storageObject, successCallback, errorCallback) {
return this._postOrPutStorageObject(storageObject, false, successCallback, errorCallback);
};
this._postOrPutStorageObject = function(storageObject, isPost, successCallback, errorCallback) {
var headers = _backend.getHttpHeaders(utils.MODULE_NAMES.STORAGE);
headers[HEADERS.ORACLE_MOBILE_NAME] = encodeURI(storageObject.getDisplayName());
headers[HEADERS.CONTENT_TYPE] = storageObject.contentType;
var url = "storage/collections/" + storageCollection.id + "/objects";
if(!isPost) {
url += "/" + storageObject.id;
if(!!storageObject._eTag) {
headers[HEADERS.IF_MATCH] = storageObject._eTag;
}
}
if(!!storageCollection.getUserIsolated() && !!storageCollection.getUserId()) {
url += "?user=" + storageCollection.getUserId();
}
return platform.invokeService({
method: isPost? HTTP_METHODS.POST : HTTP_METHODS.PUT,
url: _backend.getPlatformUrl(url),
headers: headers,
data: storageObject.getPayload()
}).then(invokeServiceSuccess,invokeServiceError);
function invokeServiceSuccess(response) {
var object = new StorageObject(storageCollection, response.data, utils, platform);
if (successCallback) {
successCallback(response.statusCode, object);
}
return new NetworkStorageObject(response.statusCode, object);
}
function invokeServiceError(response) {
if(errorCallback) {
errorCallback(response.statusCode, response.data);
} else {
return Promise.reject(response);
}
}
};
/**
* Callback invoked after a successful operation.
* @callback StorageCollection~storageCollectionSuccessCallback
* @deprecated Use promises instead
*/
/**
* Checks the service if a StorageObject with the given ID exists in the collection.
* @param id {String} The ID of the StorageObject to check.
* @example id: "00e394532-9652-458b-9a82-d1a47cf1a0c7"
* @param [successCallback] {StorageCollection~storageCollectionSuccessCallback} Callback invoked on success (deprecated use promises instead).
* @param [errorCallback] {StorageCollection~errorCallback} Callback invoked on error (deprecated use promises instead).
* @return {Promise.<NetworkResponse|NetworkResponse>}
*/
this.contains = function(id, successCallback, errorCallback) {
var headers = _backend.getHttpHeaders(utils.MODULE_NAMES.STORAGE);
var url = "storage/collections/" + storageCollection.id + "/objects/" + id;
if(!!storageCollection.getUserIsolated() && !!storageCollection.getUserId()) {
url += "?user=" + storageCollection.getUserId();
}
return platform.invokeService({
method: HTTP_METHODS.HEAD,
url: _backend.getPlatformUrl(url),
headers: headers
}).then(invokeServiceSuccess,invokeServiceError);
function invokeServiceSuccess(response) {
if (successCallback) {
successCallback(response.statusCode, response.data);
}
return response;
}
function invokeServiceError(response) {
if(errorCallback) {
errorCallback(response.statusCode, response.data);
} else {
return Promise.reject(response);
}
}
};
/**
* Deletes a StorageObject from a collection.
* @param id {String} The ID of the StorageObject to delete.
* @example id: "00e394532-9652-458b-9a82-d1a47cf1a0c7"
* @param [successCallback] {StorageCollection~storageCollectionSuccessCallback} Callback invoked on success (deprecated use promises instead).
* @param [errorCallback] {StorageCollection~errorCallback} Callback invoked on error (deprecated use promises instead).
* @return {Promise.<NetworkResponse|NetworkResponse>}
*/
this.deleteObject = function(id, successCallback, errorCallback) {
var headers = _backend.getHttpHeaders(utils.MODULE_NAMES.STORAGE);
headers[HEADERS.IF_MATCH] = "*";
var url = "storage/collections/" + storageCollection.id + "/objects/" + id;
if(!!storageCollection.getUserIsolated() && !!storageCollection.getUserId()) {
url += "?user=" + storageCollection.getUserId();
}
return platform.invokeService({
method: HTTP_METHODS.DELETE,
url: _backend.getPlatformUrl(url),
headers: headers
}).then(invokeServiceSuccess,invokeServiceError);
function invokeServiceSuccess(response) {
if (successCallback) {
successCallback(response.statusCode, response.data);
}
return response;
}
function invokeServiceError(response) {
if(errorCallback) {
errorCallback(response.statusCode, response.data);
} else {
return Promise.reject(response);
}
}
};
}