From a731c35ad610652d0250298168e3744ece920d2e Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Thu, 14 Jul 2016 13:43:55 -0700 Subject: [PATCH] [Persistence] Refactor out transaction management --- platform/commonUI/edit/bundle.js | 13 +++- .../TransactionalPersistenceCapability.js | 57 +++----------- .../edit/src/services/TransactionManager.js | 74 +++++++++++++++++++ 3 files changed, 97 insertions(+), 47 deletions(-) create mode 100644 platform/commonUI/edit/src/services/TransactionManager.js diff --git a/platform/commonUI/edit/bundle.js b/platform/commonUI/edit/bundle.js index 6b1723c5d9..2141110409 100644 --- a/platform/commonUI/edit/bundle.js +++ b/platform/commonUI/edit/bundle.js @@ -42,6 +42,7 @@ define([ "./src/representers/EditToolbarRepresenter", "./src/capabilities/EditorCapability", "./src/capabilities/TransactionCapabilityDecorator", + "./src/services/TransactionManager", "./src/services/TransactionService", "./src/creation/CreateMenuController", "./src/creation/LocatorController", @@ -80,6 +81,7 @@ define([ EditToolbarRepresenter, EditorCapability, TransactionCapabilityDecorator, + TransactionManager, TransactionService, CreateMenuController, LocatorController, @@ -320,7 +322,7 @@ define([ "implementation": TransactionCapabilityDecorator, "depends": [ "$q", - "transactionService" + "transactionManager" ], "priority": "fallback" }, @@ -405,6 +407,15 @@ define([ "key": "locator", "template": locatorTemplate } + ], + "services": [ + { + "key": "transactionManager", + "implementation": TransactionManager, + "depends": [ + "transactionService" + ] + } ] } }); diff --git a/platform/commonUI/edit/src/capabilities/TransactionalPersistenceCapability.js b/platform/commonUI/edit/src/capabilities/TransactionalPersistenceCapability.js index 5071dc040a..f9cdc837a3 100644 --- a/platform/commonUI/edit/src/capabilities/TransactionalPersistenceCapability.js +++ b/platform/commonUI/edit/src/capabilities/TransactionalPersistenceCapability.js @@ -34,69 +34,37 @@ define( * called. * @memberof platform/commonUI/edit/capabilities * @param $q - * @param transactionService + * @param transactionManager * @param persistenceCapability * @param domainObject * @constructor */ function TransactionalPersistenceCapability( $q, - transactionService, + transactionManager, persistenceCapability, domainObject ) { - this.transactionService = transactionService; + this.transactionManager = transactionManager; this.persistenceCapability = persistenceCapability; this.domainObject = domainObject; this.$q = $q; } - TransactionalPersistenceCapability.prototype.transactionClearer = function (state) { - var id = this.domainObject.getId(); - if (arguments.length > 0) { - TRANSACTION_SET[id] = state; - } - return TRANSACTION_SET[id]; - }; - /** * The wrapped persist function. If a transaction is active, persist * will be queued until the transaction is committed or cancelled. * @returns {*} */ TransactionalPersistenceCapability.prototype.persist = function () { - var self = this; + var wrappedPersistence = this.persistenceCapability; - function onCommit() { - if (!self.transactionClearer()) { - return Promise.resolve(true); - } - return self.persistenceCapability.persist().then(function (result) { - self.transactionClearer(undefined); - return result; - }); - } - - function onCancel() { - if (self.domainObject.getModel().persisted !== undefined) { - //Fetch clean model from persistence - return self.persistenceCapability.refresh().then(function (result) { - self.transactionClearer(undefined); - return result; - }); - } else { - self.transactionClearer(undefined); - self.removeFromTransaction = undefined; - //Model is undefined in persistence, so return undefined. - return self.$q.when(undefined); - } - } - - if (this.transactionService.isActive()) { - if (!self.transactionClearer()) { - this.transactionClearer(this.transactionService - .addToTransaction(onCommit, onCancel)); - } + if (this.transactionManager.isActive()) { + this.transactionManager.addToTransaction( + this.domainObject, + wrappedPersistence.persist.bind(wrappedPersistence), + wrappedPersistence.refresh.bind(wrappedPersistence) + ); //Need to return a promise from this function return this.$q.when(true); } else { @@ -105,10 +73,7 @@ define( }; TransactionalPersistenceCapability.prototype.refresh = function () { - if (this.transactionClearer()) { - this.transactionClearer()(); - this.transactionClearer(undefined); - } + this.transactionManager.clearTransactionsFor(this.domainObject); return this.persistenceCapability.refresh(); }; diff --git a/platform/commonUI/edit/src/services/TransactionManager.js b/platform/commonUI/edit/src/services/TransactionManager.js new file mode 100644 index 0000000000..1855c438be --- /dev/null +++ b/platform/commonUI/edit/src/services/TransactionManager.js @@ -0,0 +1,74 @@ +/***************************************************************************** + * Open MCT, Copyright (c) 2014-2016, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT is licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Open MCT includes source code licensed under additional open source + * licenses. See the Open Source Licenses file (LICENSES.md) included with + * this source code distribution or the Licensing information page available + * at runtime from the About dialog for additional information. + *****************************************************************************/ + +define([], function () { + /** + * Manages transactions to support the TransactionalPersistenceCapability. + */ + function TransactionManager(transactionService) { + this.transactionService = transactionService; + this.clearTransactionFns = {}; + } + + TransactionManager.prototype.isActive = function () { + return this.transactionService.isActive(); + }; + + TransactionManager.prototype.isScheduled = function (domainObject) { + return !!this.clearTransactionFns[domainObject.getId()]; + }; + + TransactionManager.prototype.addToTransaction = function ( + domainObject, + onCommit, + onCancel + ) { + var release = this.releaseClearFn.bind(this, domainObject); + + function chain(promiseFn, nextFn) { + return function () { + return promiseFn().then(nextFn); + }; + } + + if (!this.isScheduled(domainObject)) { + this.clearTransactionFns[domainObject.getId()] = + this.transactionService.addToTransaction( + chain(onCommit, release), + chain(onCancel, release) + ); + } + }; + + TransactionManager.prototype.clearTransactionsFor = function (domainObject) { + if (this.isScheduled(domainObject)) { + this.clearTransactionFns[domainObject.getId()](); + this.releaseClearFn(domainObject); + } + }; + + TransactionManager.prototype.releaseClearFn = function (domainObject) { + delete this.clearTransactionFns[domainObject.getId()]; + }; + + return TransactionManager; +});