aboutsummaryrefslogtreecommitdiff
path: root/node_modules/montage/data/change-context.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/montage/data/change-context.js')
-rwxr-xr-xnode_modules/montage/data/change-context.js374
1 files changed, 374 insertions, 0 deletions
diff --git a/node_modules/montage/data/change-context.js b/node_modules/montage/data/change-context.js
new file mode 100755
index 00000000..c693e59e
--- /dev/null
+++ b/node_modules/montage/data/change-context.js
@@ -0,0 +1,374 @@
1/* <copyright>
2 This file contains proprietary software owned by Motorola Mobility, Inc.<br/>
3 No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.<br/>
4 (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved.
5 </copyright> */
6/**
7 @module montage/data/context
8 @requires montage/core/core
9 @requires montage/data/store
10 @requires montage/data/blueprint
11 @requires montage/data/object-property
12 @requires montage/core/shim/weak-map
13 @requires montage/core/shim/structures
14 @requires montage/core/exception
15 @requires montage/core/promise
16 @requires montage/core/logger
17 */
18var Montage = require("montage").Montage;
19var Store = require("data/store").Store;
20var Blueprint = require("data/blueprint").Blueprint;
21var ObjectProperty = require("data/object-property").ObjectProperty;
22// TODO [June 5 2011 PJYF] This is temporary implementation of WeakMap to let the browser catch up.
23var WeakMap = require("core/shim/weak-map").WeakMap;
24var Set = require("core/shim/structures").Set;
25var Exception = require("core/exception").Exception;
26var Promise = require("core/promise").Promise;
27var logger = require("core/logger").logger("change-context");
28/**
29 @class module:montage/data/change-context.ChangeContext
30 @extends module:montage/data/store.Store
31 */
32var ChangeContext = exports.ChangeContext = Montage.create(Store, /** @lends module:montage/data/change-context.ChangeContext# */ {
33 /**
34 Collection of object inserted in this context since the last save.
35 @private
36 */
37 _inserted: {
38 value: new Set(50),
39 serializable: true,
40 distinct: true,
41 enumerable: false,
42 writable: false
43 },
44 /**
45 Collection of object deleted in this context since the last save.
46 @private
47 */
48 _deleted: {
49 value: new Set(50),
50 serializable: true,
51 distinct: true,
52 enumerable: false,
53 writable: false
54 },
55 /**
56 Collection of object modified in this context since the last save.
57 @private
58 */
59 _modified: {
60 value: new Set(50),
61 serializable: true,
62 distinct: true,
63 enumerable: false,
64 writable: false
65 },
66
67 /**
68 Table of fetched objects for uniquing. The key is the object ID the value the actual object or the pledge representing it.<br/>
69 <b>Note:<b/> This is a weak map so that the context does not hold on the objects and they can be garbage collected if no one else hold on them.
70 @private
71 */
72 _objectMap: {
73 value: new WeakMap(),
74 serializable: true,
75 enumerable: false,
76 writable: false
77 },
78
79 /**
80 Collection of object inserted in this context since the last save.
81 @function
82 @returns this._inserted
83 @default empty set
84 */
85 inserted: {
86 get: function() {
87 return this._inserted;
88 }
89 },
90
91 /**
92 Collection of object deleted in this context since the last save.
93 @function
94 @returns this._deleted
95 @default empty set
96 */
97 deleted: {
98 get: function() {
99 return this._deleted;
100 }
101 },
102
103 /**
104 Collection of object modified in this context since the last save.
105 @function
106 @returns this._modified
107 @default empty set
108 */
109 modified: {
110 get: function() {
111 return this._modified;
112 }
113 },
114
115 /**
116 Description TODO
117 @function
118 @param {String} id objectmap
119 @returns this._objectMap.get(id) | null
120 */
121 objectForId: {
122 value: function(id) {
123 if (this._objectMap.has(id)) {
124 return this._objectMap.get(id);
125 }
126 return null;
127 }
128 },
129
130 /**
131 Inserts a newly created object in the context.
132 @function
133 @param {Object} instance TODO
134 @returns initialized object
135 */
136 insert: {
137 value: function(instance) {
138 if (instance !== null) {
139 if (typeof instance.context === "undefined") {
140 var metadata = Montage.getInfoForObject(instance);
141 var blueprint = this.blueprintForPrototype(metadata.objectName, metadata.moduleId);
142 if (blueprint !== null) {
143 ObjectProperty.manager.apply(Object.getPrototypeOf(instance), blueprint);
144 } else {
145 throw Exception.create().initWithMessageTargetAndMethod("Cannot find blueprint for: " + metadata.objectName + " " + metadata.moduleId, this, "insert");
146 }
147 }
148 if (instance.context === null) {
149 instance.context = this;
150 this._inserted.add(instance);
151 return this.initializeObject(instance, this).then(function(instance) {
152 instance.context._objectMap.set(instance.objectId, instance);
153 return Promise.ref(instance);
154 });
155 } else if (instance.context !== this) {
156 throw Exception.initWithMessageTargetAndMethod("This instance is already inserted in another context.", this, "insert");
157 }
158 } else {
159 throw Exception.initWithMessageTargetAndMethod("Cannot insert a null object.", this, "insert");
160 }
161 }
162 },
163
164 /**
165 Delete an object.<br>
166 A deleted object will be deleted from the backing store on the next save.
167 @function
168 @param {Object} instance TODO
169 @returns Promise.ref(instance)
170 */
171 'delete': {
172 value: function(instance) {
173 if (instance !== null) {
174 if ((typeof instance.context === "undefined") || (instance.context === null)) {
175 return Promise.ref(instance);
176 }
177 if (instance.context !== this) {
178 throw Exception.initWithMessageTargetAndMethod("This instance is belongs to another context.", this, "delete");
179 }
180 if (this._inserted.has(instance)) {
181 // We are forgetting a newly inserted object
182 this._inserted.delete(instance);
183 if (typeof instance.context !== "undefined") {
184 instance.context = null;
185 }
186 } else {
187 if (this._modified.has(instance)) {
188 // the object was modified before teh delete forget those.
189 this._modified.delete(instance);
190 instance = this._revertValues(instance);
191 }
192 this._deleted.add(instance);
193 }
194 this._objectMap.delete(instance.objectId);
195 } else {
196 throw Exception.initWithMessageTargetAndMethod("Cannot delete a null object.", this, "delete");
197 }
198 return Promise.ref(instance);
199 }
200 },
201
202 /**
203 Revert an object to its saved values.
204 @function
205 @param {Object} instance TODO
206 @returns Promise.ref(instance)
207 */
208 revert: {
209 value: function(instance) {
210 if (instance !== null) {
211 if (typeof instance.context === "undefined") {
212 return Promise.ref(instance);
213 }
214 if (instance.context !== null) {
215 if (instance.context !== this) {
216 throw Exception.initWithMessageTargetAndMethod("This instance is belongs to another context.", this, "revert");
217 }
218 if (this._inserted.has(instance)) {
219 // This is a newly inserted object, there is no value to revert to, so do nothing.
220 } else if (this._modified.has(instance)) {
221 this._modified.delete(instance);
222 instance = this._revertValues(instance);
223 }
224 } else {
225 // Maybe that object was deleted let retrieve it?
226 if (this._deleted.has(instance)) {
227 this._deleted.delete(instance);