diff --git a/platform/core/src/capabilities/PersistenceCapability.js b/platform/core/src/capabilities/PersistenceCapability.js index d26426d82a..9a499d9b50 100644 --- a/platform/core/src/capabilities/PersistenceCapability.js +++ b/platform/core/src/capabilities/PersistenceCapability.js @@ -22,6 +22,13 @@ define( * @constructor */ function PersistenceCapability(persistenceService, SPACE, domainObject) { + // Update a domain object's model upon refresh + function updateModel(model) { + return domainObject.useCapability("mutation", function () { + return model; + }); + } + return { /** * Persist any changes which have been made to this @@ -37,6 +44,19 @@ define( domainObject.getModel() ); }, + /** + * Update this domain object to match the latest from + * persistence. + * @returns {Promise} a promise which will be resolved + * when the update is complete + */ + refresh: function () { + return persistenceService.readObject( + SPACE, + domainObject.getId(), + { cache: false } // Disallow cached reads + ).then(updateModel); + }, /** * Get the space in which this domain object is persisted; * this is useful when, for example, decided which space a diff --git a/platform/persistence/cache/src/CachingPersistenceDecorator.js b/platform/persistence/cache/src/CachingPersistenceDecorator.js index 06e784d928..bb0eff3e69 100644 --- a/platform/persistence/cache/src/CachingPersistenceDecorator.js +++ b/platform/persistence/cache/src/CachingPersistenceDecorator.js @@ -126,12 +126,14 @@ define( * @memberof CachingPersistenceDecorator# * @param {string} space the space in which to create the object * @param {string} key the key which identifies the object + * @param {*} options optional parameters * @returns {Promise.} a promise for the object; may * resolve to undefined (if the object does not exist * in this space) */ - readObject: function (space, key) { - return (cache[space] && cache[space][key]) ? + readObject: function (space, key, options) { + var force = (options || {}).cache === false; + return (cache[space] && cache[space][key] && !force) ? fastPromise(cache[space][key].value) : persistenceService.readObject(space, key) .then(putCache(space, key)); diff --git a/platform/persistence/overwrite/src/PersistenceFailureConstants.js b/platform/persistence/overwrite/src/PersistenceFailureConstants.js new file mode 100644 index 0000000000..b91286193d --- /dev/null +++ b/platform/persistence/overwrite/src/PersistenceFailureConstants.js @@ -0,0 +1,6 @@ +/*global define*/ + +define({ + REVISION_ERROR_KEY: "revision", + OVERWRITE_KEY: "overwrite" +}); \ No newline at end of file diff --git a/platform/persistence/overwrite/src/PersistenceFailureDialog.js b/platform/persistence/overwrite/src/PersistenceFailureDialog.js new file mode 100644 index 0000000000..fa1d0dbfdd --- /dev/null +++ b/platform/persistence/overwrite/src/PersistenceFailureDialog.js @@ -0,0 +1,54 @@ +/*global define*/ + +define( + ['./PersistenceFailureConstants'], + function (PersistenceFailureConstants) { + "use strict"; + + var OVERWRITE_CANCEL_OPTIONS = [ + { + name: "Overwrite", + key: PersistenceFailureConstants.OVERWRITE_KEY + }, + { + name: "Cancel", + key: "cancel" + } + ], + OK_OPTIONS = [ { name: "OK", key: "ok" } ]; + + /** + * Populates a `dialogModel` to pass to `dialogService.getUserChoise` + * in order to choose between Overwrite and Cancel. + */ + function PersistenceFailureDialog(failures) { + var revisionErrors = [], + otherErrors = []; + + // Place this failure into an appropriate group + function categorizeFailure(failure) { + // Check if the error is due to object revision + var isRevisionError = ((failure || {}).error || {}).key === + PersistenceFailureConstants.REVISION_ERROR_KEY; + // Push the failure into the appropriate group + (isRevisionError ? revisionErrors : otherErrors).push(failure); + } + + // Separate into revision errors, and other errors + failures.forEach(categorizeFailure); + + return { + title: "Save Error", + template: "persistence-failure-dialog", + model: { + revised: revisionErrors, + unrecoverable: otherErrors + }, + options: revisionErrors.length > 0 ? + OVERWRITE_CANCEL_OPTIONS : OK_OPTIONS + }; + } + + return PersistenceFailureDialog; + } +); \ No newline at end of file diff --git a/platform/persistence/overwrite/src/PersistenceFailureHandler.js b/platform/persistence/overwrite/src/PersistenceFailureHandler.js index 2c7b4fc75d..e15890fd63 100644 --- a/platform/persistence/overwrite/src/PersistenceFailureHandler.js +++ b/platform/persistence/overwrite/src/PersistenceFailureHandler.js @@ -1,15 +1,35 @@ /*global define*/ define( - [], - function () { + ['./PersistenceFailureDialog', './PersistenceFailureConstants'], + function (PersistenceFailureDialog, PersistenceFailureConstants) { "use strict"; - function PersistenceFailureHandler(dialogService) { - return { - handle: function (failures) { + function PersistenceFailureHandler($q, dialogService, persistenceService) { + function refresh(failure) { + } + + function retry(failures) { + + } + + function handleFailures(failures) { + var dialogModel = new PersistenceFailureDialog(failures), + revisionErrors = dialogModel.model.revised; + + function handleChoice(key) { + if (key === PersistenceFailureConstants.OVERWRITE_KEY) { + return retry(revisionErrors); + } } + + return dialogService.getUserChoice(dialogModel) + .then(handleChoice); + } + + return { + handle: handleFailures }; }