/** * 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); } } }; }