Daniel@0
|
1 "use strict";
|
Daniel@0
|
2
|
Daniel@0
|
3 App.module("ContextModule", function(ContextModule, App, Backbone, Marionette, $, _, Logger) {
|
Daniel@0
|
4
|
Daniel@0
|
5 // Define private variables
|
Daniel@0
|
6 var logger = null;
|
Daniel@0
|
7
|
Daniel@0
|
8 ContextModule.addInitializer(function(options){
|
Daniel@0
|
9
|
Daniel@0
|
10 logger = Logger.get("ContextModule.Config");
|
Daniel@0
|
11 logger.setLevel(Logger.WARN);
|
Daniel@0
|
12
|
Daniel@0
|
13 /**
|
Daniel@0
|
14 * Config embraces common behaviour patterns of an object that can have pending changes –
|
Daniel@0
|
15 * it consists of two attributes: parameters and plannedParameterUpdates. Both are simple
|
Daniel@0
|
16 * Backbone objects (Models) with a list of scalar attributes.
|
Daniel@0
|
17 *
|
Daniel@0
|
18 * The ConfigObject itself is identified by its non-changeable clientId (getClientId())
|
Daniel@0
|
19 * and can be serialized (dumped) and unserialized (restored).
|
Daniel@0
|
20 *
|
Daniel@0
|
21 * It is advised to listen to changes in the Config using "change", "change:parameters"
|
Daniel@0
|
22 * and "change:plannedParameterUpdates" listener.
|
Daniel@0
|
23 * It will be triggered each time when "parameters or "plannedParameterUpdates" attributes have been changed.
|
Daniel@0
|
24 */
|
Daniel@0
|
25 ContextModule.Config = Backbone.Model.extend({
|
Daniel@0
|
26
|
Daniel@0
|
27 // Client id prefix (cf123 instead of standard c123)
|
Daniel@0
|
28 cidPrefix: "cf",
|
Daniel@0
|
29
|
Daniel@0
|
30 /**
|
Daniel@0
|
31 * @memberOf App.ContextModule.Config
|
Daniel@0
|
32 */
|
Daniel@0
|
33 constructor: function(attributes, options) {
|
Daniel@0
|
34 this._modificationPropagationEnabled = true;
|
Daniel@0
|
35 this._parametersWereModified = false;
|
Daniel@0
|
36 this._plannedParameterUpdatesWereModified = false;
|
Daniel@0
|
37 this._cachedHashForTrimmedParameters = null;
|
Daniel@0
|
38 this._cachedHashForParameters = null;
|
Daniel@0
|
39 this._cachedHashForPlannedParameterUpdates = null;
|
Daniel@0
|
40 this._cachedHashForPermanent = null;
|
Daniel@0
|
41 this._cachedHashForTemp = null;
|
Daniel@0
|
42 this._cachedHash = null;
|
Daniel@0
|
43
|
Daniel@0
|
44 var defaultParameters = (_.isSimpleObject(attributes) && _.isSimpleObject(attributes.parameters)) ? attributes.parameters : undefined;
|
Daniel@0
|
45 var defaultPlannedParameterUpdates = (_.isSimpleObject(attributes) && _.isSimpleObject(attributes.plannedParameterUpdates)) ? attributes.plannedParameterUpdates : undefined;
|
Daniel@0
|
46
|
Daniel@0
|
47 var realAttributes = {};
|
Daniel@0
|
48 realAttributes.parameters = new Backbone.Model(defaultParameters);
|
Daniel@0
|
49 realAttributes.plannedParameterUpdates = new Backbone.Model(defaultPlannedParameterUpdates);
|
Daniel@0
|
50
|
Daniel@0
|
51 this.listenTo(realAttributes.parameters, "change", this._registerModificationOfParameters);
|
Daniel@0
|
52 this.listenTo(realAttributes.plannedParameterUpdates, "change", this._registerModificationOfPlannedParameterUpdates);
|
Daniel@0
|
53
|
Daniel@0
|
54 Backbone.Model.apply(this, [realAttributes, options]);
|
Daniel@0
|
55
|
Daniel@0
|
56 if (attributes && attributes.clientId) {
|
Daniel@0
|
57 this.cid = attributes.clientId;
|
Daniel@0
|
58 _.markUniqueIdAsAlreadyUsed(attributes.clientId);
|
Daniel@0
|
59 }
|
Daniel@0
|
60 },
|
Daniel@0
|
61
|
Daniel@0
|
62 getClientId: function() {
|
Daniel@0
|
63 return this.cid;
|
Daniel@0
|
64 },
|
Daniel@0
|
65
|
Daniel@0
|
66 getDimension: function() {
|
Daniel@0
|
67 return this.collection ? this.collection.dimension : undefined;
|
Daniel@0
|
68 },
|
Daniel@0
|
69 getConfigGridType: function() {
|
Daniel@0
|
70 return this.collection ? this.collection.configGridType : undefined;
|
Daniel@0
|
71 },
|
Daniel@0
|
72
|
Daniel@0
|
73 /**
|
Daniel@0
|
74 * @memberOf App.ContextModule.Config
|
Daniel@0
|
75 */
|
Daniel@0
|
76 getParameterValue: function(parameterName) {
|
Daniel@0
|
77 return this.attributes.parameters.attributes[parameterName];
|
Daniel@0
|
78 },
|
Daniel@0
|
79
|
Daniel@0
|
80 /**
|
Daniel@0
|
81 * @memberOf App.ContextModule.Config
|
Daniel@0
|
82 */
|
Daniel@0
|
83 getPlannedParameterValue: function(parameterName) {
|
Daniel@0
|
84 var plannedParameterUpdatesAttributes = this.attributes.plannedParameterUpdates.attributes;
|
Daniel@0
|
85 if (plannedParameterUpdatesAttributes.hasOwnProperty(parameterName)) {
|
Daniel@0
|
86 return plannedParameterUpdatesAttributes[parameterName];
|
Daniel@0
|
87 } else {
|
Daniel@0
|
88 return this.attributes.parameters.attributes[parameterName];
|
Daniel@0
|
89 }
|
Daniel@0
|
90 },
|
Daniel@0
|
91
|
Daniel@0
|
92 /**
|
Daniel@0
|
93 * @memberOf App.ContextModule.Config
|
Daniel@0
|
94 *
|
Daniel@0
|
95 * XXX clone parameter values?
|
Daniel@0
|
96 */
|
Daniel@0
|
97 getPlannedParameterValues: function(parameterName) {
|
Daniel@0
|
98 var result = _.clone(this.attributes.parameters.attributes);
|
Daniel@0
|
99 var plannedParameterUpdatesAttributes = this.attributes.plannedParameterUpdates.attributes;
|
Daniel@0
|
100 for (var key in plannedParameterUpdatesAttributes) {
|
Daniel@0
|
101 if (plannedParameterUpdatesAttributes.hasOwnProperty(key)) {
|
Daniel@0
|
102 if (plannedParameterUpdatesAttributes[key] === undefined) {
|
Daniel@0
|
103 if (result.hasOwnProperty(key)) {
|
Daniel@0
|
104 delete result[key];
|
Daniel@0
|
105 }
|
Daniel@0
|
106 } else {
|
Daniel@0
|
107 result[key] = plannedParameterUpdatesAttributes[key];
|
Daniel@0
|
108 }
|
Daniel@0
|
109 }
|
Daniel@0
|
110 }
|
Daniel@0
|
111 return result;
|
Daniel@0
|
112 },
|
Daniel@0
|
113
|
Daniel@0
|
114 /**
|
Daniel@0
|
115 * @memberOf App.ContextModule.Config
|
Daniel@0
|
116 */
|
Daniel@0
|
117 isPlannedToUpdate: function(parameterName) {
|
Daniel@0
|
118 return this.attributes.plannedParameterUpdates.attributes.hasOwnProperty(parameterName);
|
Daniel@0
|
119 // var parameterValue = this.getParameterValue(parameterName);
|
Daniel@0
|
120 // var plannedParameterValue = this.getPlannedParameterValue(parameterName);
|
Daniel@0
|
121 // return (parameterValue !== plannedParameterValue);
|
Daniel@0
|
122 },
|
Daniel@0
|
123
|
Daniel@0
|
124 /**
|
Daniel@0
|
125 * @memberOf App.ContextModule.Config
|
Daniel@0
|
126 */
|
Daniel@0
|
127 hasPlannedParameterUpdates: function() {
|
Daniel@0
|
128 return _.size(this.attributes.plannedParameterUpdates.attributes) > 0;
|
Daniel@0
|
129 },
|
Daniel@0
|
130
|
Daniel@0
|
131 /**
|
Daniel@0
|
132 * @memberOf App.ContextModule.Config
|
Daniel@0
|
133 */
|
Daniel@0
|
134 updateParameter: function(parameterName, parameterValue) {
|
Daniel@0
|
135 if (!_.isString(parameterName)) {
|
Daniel@0
|
136 throw _.str.sprintf("Config::updateParameter called a non-string parameterName: %s", parameterName);
|
Daniel@0
|
137 }
|
Daniel@0
|
138 var prevModificationPropagationEnabled = this._modificationPropagationEnabled;
|
Daniel@0
|
139 this._modificationPropagationEnabled = false;
|
Daniel@0
|
140 this.attributes.plannedParameterUpdates.unset(parameterName);
|
Daniel@0
|
141 if (typeof parameterValue !== "undefined") {
|
Daniel@0
|
142 this.attributes.parameters.set(parameterName, parameterValue);
|
Daniel@0
|
143 } else {
|
Daniel@0
|
144 this.attributes.parameters.unset(parameterName);
|
Daniel@0
|
145 }
|
Daniel@0
|
146 if (prevModificationPropagationEnabled) {
|
Daniel@0
|
147 this._triggerModificationEventsIfNeeded();
|
Daniel@0
|
148 this._modificationPropagationEnabled = true;
|
Daniel@0
|
149 }
|
Daniel@0
|
150 },
|
Daniel@0
|
151
|
Daniel@0
|
152 /**
|
Daniel@0
|
153 * @memberOf App.ContextModule.Config
|
Daniel@0
|
154 */
|
Daniel@0
|
155 planParameterUpdate: function(parameterName, parameterValue) {
|
Daniel@0
|
156 if (!_.isString(parameterName)) {
|
Daniel@0
|
157 throw _.str.sprintf("Config::planParameterUpdate called a non-string parameterName: %s", parameterName);
|
Daniel@0
|
158 }
|
Daniel@0
|
159 var prevModificationPropagationEnabled = this._modificationPropagationEnabled;
|
Daniel@0
|
160
|
Daniel@0
|
161 this._modificationPropagationEnabled = false;
|
Daniel@0
|
162 var plannedParameterUpdatesAttributes = this.attributes.plannedParameterUpdates.attributes;
|
Daniel@0
|
163 var parametersAttributes = this.attributes.parameters.attributes;
|
Daniel@0
|
164 if (parameterValue === parametersAttributes[parameterName]) {
|
Daniel@0
|
165 // special case: backbone won't fire a change event without this hack (due to how _.isEqual works)
|
Daniel@0
|
166 if (this.attributes.plannedParameterUpdates.attributes.hasOwnProperty(parameterName) && this.attributes.plannedParameterUpdates.attributes[parameterName] === undefined) {
|
Daniel@0
|
167 this.attributes.plannedParameterUpdates.set(parameterName, 42, {silent: true});
|
Daniel@0
|
168 }
|
Daniel@0
|
169 this.attributes.plannedParameterUpdates.unset(parameterName);
|
Daniel@0
|
170 } else {
|
Daniel@0
|
171 // special case: backbone won't fire a change event without this hack (due to how _.isEqual works)
|
Daniel@0
|
172 if (parameterValue === undefined && this.attributes.parameters.attributes.hasOwnProperty(parameterName) && !this.attributes.plannedParameterUpdates.attributes.hasOwnProperty(parameterName)) {
|
Daniel@0
|
173 this.attributes.plannedParameterUpdates.set(parameterName, 42, {silent: true});
|
Daniel@0
|
174 }
|
Daniel@0
|
175 this.attributes.plannedParameterUpdates.set(parameterName, parameterValue);
|
Daniel@0
|
176 }
|
Daniel@0
|
177
|
Daniel@0
|
178 if (prevModificationPropagationEnabled) {
|
Daniel@0
|
179 this._triggerModificationEventsIfNeeded();
|
Daniel@0
|
180 this._modificationPropagationEnabled = true;
|
Daniel@0
|
181 }
|
Daniel@0
|
182 },
|
Daniel@0
|
183
|
Daniel@0
|
184 /**
|
Daniel@0
|
185 * @memberOf App.ContextModule.Config
|
Daniel@0
|
186 */
|
Daniel@0
|
187 cancelPlannedParameterUpdate: function(parameterName) {
|
Daniel@0
|
188 if (!_.isString(parameterName)) {
|
Daniel@0
|
189 throw _.str.sprintf("Config::cancelPlannedParameterUpdate called a non-string parameterName: %s", parameterName);
|
Daniel@0
|
190 }
|
Daniel@0
|
191 var prevModificationPropagationEnabled = this._modificationPropagationEnabled;
|
Daniel@0
|
192 this._modificationPropagationEnabled = false;
|
Daniel@0
|
193
|
Daniel@0
|
194 this.attributes.plannedParameterUpdates.unset(parameterName);
|
Daniel@0
|
195 if (prevModificationPropagationEnabled) {
|
Daniel@0
|
196 this._triggerModificationEventsIfNeeded();
|
Daniel@0
|
197 this._modificationPropagationEnabled = true;
|
Daniel@0
|
198 }
|
Daniel@0
|
199 },
|
Daniel@0
|
200
|
Daniel@0
|
201 /**
|
Daniel@0
|
202 * @memberOf App.ContextModule.Config
|
Daniel@0
|
203 */
|
Daniel@0
|
204 updateParameters: function(parameters) {
|
Daniel@0
|
205 if (!_.isSimpleObject(parameters)) {
|
Daniel@0
|
206 throw _.str.sprintf("Config::updateParameters called a wrong argument: %s", parameters);
|
Daniel@0
|
207 }
|
Daniel@0
|
208 this._modificationPropagationEnabled = false;
|
Daniel@0
|
209
|
Daniel@0
|
210 for (var parameterName in parameters) {
|
Daniel@0
|
211 if (parameters.hasOwnProperty(parameterName)) {
|
Daniel@0
|
212 this.updateParameter(parameterName, parameters[parameterName]);
|
Daniel@0
|
213 }
|
Daniel@0
|
214 }
|
Daniel@0
|
215
|
Daniel@0
|
216 this._triggerModificationEventsIfNeeded();
|
Daniel@0
|
217 this._modificationPropagationEnabled = true;
|
Daniel@0
|
218 },
|
Daniel@0
|
219
|
Daniel@0
|
220 /**
|
Daniel@0
|
221 * @memberOf App.ContextModule.Config
|
Daniel@0
|
222 */
|
Daniel@0
|
223 planParameterUpdates: function(parameters) {
|
Daniel@0
|
224 if (!_.isSimpleObject(parameters)) {
|
Daniel@0
|
225 throw _.str.sprintf("Config::planParameterUpdates called with a wrong argument: %s", parameters);
|
Daniel@0
|
226 }
|
Daniel@0
|
227 this._modificationPropagationEnabled = false;
|
Daniel@0
|
228
|
Daniel@0
|
229 for (var parameterName in parameters) {
|
Daniel@0
|
230 if (parameters.hasOwnProperty(parameterName)) {
|
Daniel@0
|
231 this.planParameterUpdate(parameterName, parameters[parameterName]);
|
Daniel@0
|
232 }
|
Daniel@0
|
233 }
|
Daniel@0
|
234
|
Daniel@0
|
235 this._triggerModificationEventsIfNeeded();
|
Daniel@0
|
236 this._modificationPropagationEnabled = true;
|
Daniel@0
|
237 },
|
Daniel@0
|
238
|
Daniel@0
|
239 /**
|
Daniel@0
|
240 * @memberOf App.ContextModule.Config
|
Daniel@0
|
241 */
|
Daniel@0
|
242 cancelPlannedParameterUpdates: function(parameterNames) {
|
Daniel@0
|
243 if (_.isArray(parameterNames)) {
|
Daniel@0
|
244 this._modificationPropagationEnabled = false;
|
Daniel@0
|
245
|
Daniel@0
|
246 for (var i = 0; i < parameterNames.length; i++) {
|
Daniel@0
|
247 this.cancelPlannedParameterUpdate(parameterNames[i]);
|
Daniel@0
|
248 }
|
Daniel@0
|
249
|
Daniel@0
|
250 this._triggerModificationEventsIfNeeded();
|
Daniel@0
|
251 this._modificationPropagationEnabled = true;
|
Daniel@0
|
252 } else if (!_.isUndefined(parameterNames)) {
|
Daniel@0
|
253 throw _.str.sprintf("Config::planParameterUpdates called a non-string parameters: %s", parameters);
|
Daniel@0
|
254 } else {
|
Daniel@0
|
255 if (_.keys(this.attributes.plannedParameterUpdates.attributes).length) {
|
Daniel@0
|
256 this.attributes.plannedParameterUpdates.attributes.fix = 42;
|
Daniel@0
|
257 }
|
Daniel@0
|
258 this.attributes.plannedParameterUpdates.clear();
|
Daniel@0
|
259 }
|
Daniel@0
|
260 },
|
Daniel@0
|
261
|
Daniel@0
|
262 /**
|
Daniel@0
|
263 * @memberOf App.ContextModule.Config
|
Daniel@0
|
264 */
|
Daniel@0
|
265 applyPlannedParameterUpdates: function() {
|
Daniel@0
|
266
|
Daniel@0
|
267 // Combine parameters with planned updates
|
Daniel@0
|
268 var newParameters = _.extend(this.attributes.parameters.toJSON(), this.attributes.plannedParameterUpdates.toJSON());
|
Daniel@0
|
269
|
Daniel@0
|
270 // Remove "undefined" from the new parameters
|
Daniel@0
|
271 for (var key in newParameters) {
|
Daniel@0
|
272 if (!newParameters.hasOwnProperty(key)) continue;
|
Daniel@0
|
273
|
Daniel@0
|
274 if (typeof newParameters[key] === "undefined") {
|
Daniel@0
|
275 delete newParameters[key];
|
Daniel@0
|
276 }
|
Daniel@0
|
277 }
|
Daniel@0
|
278
|
Daniel@0
|
279 // If there are any existing keys with "undefined" within plannedParameterUpdates,
|
Daniel@0
|
280 // replace "undefined" with some value to make sure change:plannedParameterUpdates is triggered
|
Daniel@0
|
281 // Another part of this hack is in "planParameterUpdate" method
|
Daniel@0
|
282 var attributesInPlannedParameterUpdates = this.attributes.plannedParameterUpdates.attributes;
|
Daniel@0
|
283 for (var key in attributesInPlannedParameterUpdates) {
|
Daniel@0
|
284 if (attributesInPlannedParameterUpdates[key] === undefined) {
|
Daniel@0
|
285 attributesInPlannedParameterUpdates[key] = 42;
|
Daniel@0
|
286 break;
|
Daniel@0
|
287 }
|
Daniel@0
|
288 }
|
Daniel@0
|
289
|
Daniel@0
|
290 // Assign parameters and clear planned updates
|
Daniel@0
|
291 this.unserialize({
|
Daniel@0
|
292 clientId: this.cid,
|
Daniel@0
|
293 parameters: newParameters,
|
Daniel@0
|
294 plannedParameterUpdates: {}
|
Daniel@0
|
295 });
|
Daniel@0
|
296 },
|
Daniel@0
|
297
|
Daniel@0
|
298 /**
|
Daniel@0
|
299 * @memberOf App.ContextModule.Config
|
Daniel@0
|
300 */
|
Daniel@0
|
301 serialize: function() {
|
Daniel@0
|
302 var result = {
|
Daniel@0
|
303 clientId: this.cid,
|
Daniel@0
|
304 parameters: this.attributes.parameters.toJSON(),
|
Daniel@0
|
305 plannedParameterUpdates: this.attributes.plannedParameterUpdates.toJSON()
|
Daniel@0
|
306 };
|
Daniel@0
|
307
|
Daniel@0
|
308 return result;
|
Daniel@0
|
309 },
|
Daniel@0
|
310
|
Daniel@0
|
311 /**
|
Daniel@0
|
312 * @memberOf App.ContextModule.Config
|
Daniel@0
|
313 */
|
Daniel@0
|
314 unserialize: function(serializedAttributes) {
|
Daniel@0
|
315 var fixedSerializedAttributes = serializedAttributes;
|
Daniel@0
|
316 if (!_.isSimpleObject(serializedAttributes)) {
|
Daniel@0
|
317 logger.warn("Config::unserialize called for not an object: ", serializedAttributes);
|
Daniel@0
|
318 fixedSerializedAttributes = {};
|
Daniel@0
|
319 }
|
Daniel@0
|
320
|
Daniel@0
|
321 if (this.cid != fixedSerializedAttributes.clientId && !_.isUndefined(fixedSerializedAttributes.clientId)) {
|
Daniel@0
|
322 throw _.str.sprintf("Parameter bag client id (%s) is not equal to the client id of the serialized object (%s).", this.cid, fixedSerializedAttributes.clientId);
|
Daniel@0
|
323 }
|
Daniel@0
|
324
|
Daniel@0
|
325 this._parametersWereModified = false;
|
Daniel@0
|
326 this._plannedParameterUpdatesWereModified = false;
|
Daniel@0
|
327 this._modificationPropagationEnabled = false;
|
Daniel@0
|
328
|
Daniel@0
|
329 var fixedSerializedPlannedParameterUpdates = fixedSerializedAttributes.plannedParameterUpdates;
|
Daniel@0
|
330 if (!_.isSimpleObject(fixedSerializedPlannedParameterUpdates)) {
|
Daniel@0
|
331 if (_.isSimpleObject(serializedAttributes)) {
|
Daniel@0
|
332 logger.warn("Config::unserialize called for object with faulty plannedParameterUpdates: ", fixedSerializedPlannedParameterUpdates);
|
Daniel@0
|
333 }
|
Daniel@0
|
334 fixedSerializedPlannedParameterUpdates = {};
|
Daniel@0
|
335 }
|
Daniel@0
|
336 if (!_.isEqual(this.attributes.plannedParameterUpdates.attributes, fixedSerializedPlannedParameterUpdates)) {
|
Daniel@0
|
337 this.attributes.plannedParameterUpdates
|
Daniel@0
|
338 .set("fix", 42, {silent: true})
|
Daniel@0
|
339 .clear()
|
Daniel@0
|
340 .set(fixedSerializedPlannedParameterUpdates);
|
Daniel@0
|
341 }
|
Daniel@0
|
342
|
Daniel@0
|
343 var fixedSerializedParameters = fixedSerializedAttributes.parameters;
|
Daniel@0
|
344 if (!_.isSimpleObject(fixedSerializedParameters)) {
|
Daniel@0
|
345 if (_.isSimpleObject(serializedAttributes)) {
|
Daniel@0
|
346 logger.warn("Config::unserialize called for object with faulty parameters: ", fixedSerializedParameters);
|
Daniel@0
|
347 }
|
Daniel@0
|
348 fixedSerializedParameters = {};
|
Daniel@0
|
349 }
|
Daniel@0
|
350 if (!_.isEqual(this.attributes.parameters.toJSON(), fixedSerializedParameters)) {
|
Daniel@0
|
351 this.attributes.parameters
|
Daniel@0
|
352 .clear()
|
Daniel@0
|
353 .set(fixedSerializedParameters);
|
Daniel@0
|
354 }
|
Daniel@0
|
355
|
Daniel@0
|
356 this._triggerModificationEventsIfNeeded();
|
Daniel@0
|
357 this._modificationPropagationEnabled = true;
|
Daniel@0
|
358 },
|
Daniel@0
|
359
|
Daniel@0
|
360 clone: function() {
|
Daniel@0
|
361 var serializedAttributes = this.serialize();
|
Daniel@0
|
362 delete serializedAttributes.clientId;
|
Daniel@0
|
363 return new ContextModule.Config(serializedAttributes);
|
Daniel@0
|
364 },
|
Daniel@0
|
365
|
Daniel@0
|
366 getHashForParameters: function() {
|
Daniel@0
|
367 if (this._cachedHashForParameters === null) {
|
Daniel@0
|
368 this._cachedHashForParameters = JSON.stringify(this.attributes.parameters.attributes);
|
Daniel@0
|
369 }
|
Daniel@0
|
370 return this._cachedHashForParameters;
|
Daniel@0
|
371 },
|
Daniel@0
|
372
|
Daniel@0
|
373 getHashForTrimmedParameters: function() {
|
Daniel@0
|
374 if (this._cachedHashForTrimmedParameters === null) {
|
Daniel@0
|
375 var attributesToHash = _.clone(this.attributes.parameters.attributes);
|
Daniel@0
|
376 for (var key in attributesToHash){
|
Daniel@0
|
377 if (attributesToHash.hasOwnProperty(key) && _.isString(attributesToHash[key])) {
|
Daniel@0
|
378 attributesToHash[key] = _.str.trim(attributesToHash[key]);
|
Daniel@0
|
379 }
|
Daniel@0
|
380 }
|
Daniel@0
|
381 this._cachedHashForTrimmedParameters = JSON.stringify(attributesToHash);
|
Daniel@0
|
382 }
|
Daniel@0
|
383 return this._cachedHashForTrimmedParameters;
|
Daniel@0
|
384 },
|
Daniel@0
|
385
|
Daniel@0
|
386 getHashForPlannedParameterUpdates: function() {
|
Daniel@0
|
387 if (this._cachedHashForPlannedParameterUpdates === null) {
|
Daniel@0
|
388 var attributes = this.attributes.plannedParameterUpdates.attributes;
|
Daniel@0
|
389 this._cachedHashForPlannedParameterUpdates = JSON.stringify(attributes);
|
Daniel@0
|
390 // special treatment of undefined is needed here
|
Daniel@0
|
391 // see http://stackoverflow.com/questions/26540706/json-stringify-removes-hash-keys-with-undefined-values
|
Daniel@0
|
392 for (var key in attributes) {
|
Daniel@0
|
393 if (attributes.hasOwnProperty(key) && attributes[key] === undefined) {
|
Daniel@0
|
394 this._cachedHashForPlannedParameterUpdates += key + "|";
|
Daniel@0
|
395 }
|
Daniel@0
|
396 }
|
Daniel@0
|
397 }
|
Daniel@0
|
398 return this._cachedHashForPlannedParameterUpdates;
|
Daniel@0
|
399 },
|
Daniel@0
|
400
|
Daniel@0
|
401 getHashForPermanent: function() {
|
Daniel@0
|
402 if (this._cachedHashForPermanent === null) {
|
Daniel@0
|
403 this._cachedHashForPermanent = this.getHashForParameters() + this.getHashForPlannedParameterUpdates();
|
Daniel@0
|
404 }
|
Daniel@0
|
405 return this._cachedHashForPermanent;
|
Daniel@0
|
406 },
|
Daniel@0
|
407
|
Daniel@0
|
408 getHashForTemp: function() {
|
Daniel@0
|
409 if (this._cachedHashForTemp === null) {
|
Daniel@0
|
410 this._cachedHashForTemp = "";
|
Daniel@0
|
411 }
|
Daniel@0
|
412 return this._cachedHashForTemp;
|
Daniel@0
|
413 },
|
Daniel@0
|
414
|
Daniel@0
|
415 getHash: function() {
|
Daniel@0
|
416 if (!this._cachedHash) {
|
Daniel@0
|
417 this._cachedHash = this.getHashForPermanent() + this.getHashForTemp();
|
Daniel@0
|
418 }
|
Daniel@0
|
419 return this._cachedHash;
|
Daniel@0
|
420 },
|
Daniel@0
|
421
|
Daniel@0
|
422 _registerModificationOfParameters: function() {
|
Daniel@0
|
423 this._cachedHashForParameters = null;
|
Daniel@0
|
424 this._cachedHashForTrimmedParameters = null;
|
Daniel@0
|
425 this._cachedHashForPermanent = null;
|
Daniel@0
|
426 this._cachedHash = null;
|
Daniel@0
|
427
|
Daniel@0
|
428 this._parametersWereModified = true;
|
Daniel@0
|
429 if (this._modificationPropagationEnabled) {
|
Daniel@0
|
430 this._triggerModificationEventsIfNeeded();
|
Daniel@0
|
431 };
|
Daniel@0
|
432 },
|
Daniel@0
|
433
|
Daniel@0
|
434 _registerModificationOfPlannedParameterUpdates: function() {
|
Daniel@0
|
435 this._cachedHashForPlannedParameterUpdates = null;
|
Daniel@0
|
436 this._cachedHashForPermanent = null;
|
Daniel@0
|
437 this._cachedHash = null;
|
Daniel@0
|
438
|
Daniel@0
|
439 this._plannedParameterUpdatesWereModified = true;
|
Daniel@0
|
440 if (this._modificationPropagationEnabled) {
|
Daniel@0
|
441 this._triggerModificationEventsIfNeeded();
|
Daniel@0
|
442 };
|
Daniel@0
|
443 },
|
Daniel@0
|
444
|
Daniel@0
|
445 _triggerModificationEventsIfNeeded: function() {
|
Daniel@0
|
446 this.changed = [true];
|
Daniel@0
|
447 if (this._parametersWereModified) {
|
Daniel@0
|
448 this.trigger("change:parameters");
|
Daniel@0
|
449 }
|
Daniel@0
|
450 if (this._plannedParameterUpdatesWereModified) {
|
Daniel@0
|
451 this.trigger("change:plannedParameterUpdates");
|
Daniel@0
|
452 }
|
Daniel@0
|
453 if (this._tempParametersWereModified) {
|
Daniel@0
|
454 this.trigger("change:tempParameters");
|
Daniel@0
|
455 }
|
Daniel@0
|
456
|
Daniel@0
|
457 if (this._parametersWereModified || this._plannedParameterUpdatesWereModified) {
|
Daniel@0
|
458 this.trigger("change:parametersOrPlannedParameterUpdates");
|
Daniel@0
|
459 this.trigger("change");
|
Daniel@0
|
460 }
|
Daniel@0
|
461 this._parametersWereModified = false;
|
Daniel@0
|
462 this._plannedParameterUpdatesWereModified = false;
|
Daniel@0
|
463 this._tempParametersWereModified = false;
|
Daniel@0
|
464 this.changed = null;
|
Daniel@0
|
465 },
|
Daniel@0
|
466 });
|
Daniel@0
|
467 });
|
Daniel@0
|
468 }, Logger);
|