summaryrefslogtreecommitdiff
path: root/frontend/gamma/js/Clipperz/PM/DataModel/User.Header.RecordIndex.js
Unidiff
Diffstat (limited to 'frontend/gamma/js/Clipperz/PM/DataModel/User.Header.RecordIndex.js') (more/less context) (show whitespace changes)
-rw-r--r--frontend/gamma/js/Clipperz/PM/DataModel/User.Header.RecordIndex.js705
1 files changed, 705 insertions, 0 deletions
diff --git a/frontend/gamma/js/Clipperz/PM/DataModel/User.Header.RecordIndex.js b/frontend/gamma/js/Clipperz/PM/DataModel/User.Header.RecordIndex.js
new file mode 100644
index 0000000..6ba58a8
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/DataModel/User.Header.RecordIndex.js
@@ -0,0 +1,705 @@
1/*
2
3Copyright 2008-2011 Clipperz Srl
4
5This file is part of Clipperz's Javascript Crypto Library.
6Javascript Crypto Library provides web developers with an extensive
7and efficient set of cryptographic functions. The library aims to
8obtain maximum execution speed while preserving modularity and
9reusability.
10For further information about its features and functionalities please
11refer to http://www.clipperz.com
12
13* Javascript Crypto Library is free software: you can redistribute
14 it and/or modify it under the terms of the GNU Affero General Public
15 License as published by the Free Software Foundation, either version
16 3 of the License, or (at your option) any later version.
17
18* Javascript Crypto Library is distributed in the hope that it will
19 be useful, but WITHOUT ANY WARRANTY; without even the implied
20 warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
21 See the GNU Affero General Public License for more details.
22
23* You should have received a copy of the GNU Affero General Public
24 License along with Javascript Crypto Library. If not, see
25 <http://www.gnu.org/licenses/>.
26
27*/
28
29try { if (typeof(Clipperz.PM.DataModel.User) == 'undefined') { throw ""; }} catch (e) {
30 throw "Clipperz.PM.DataModel.User.Header.RecordIndex depends on Clipperz.PM.DataModel.User!";
31}
32
33if (typeof(Clipperz.PM.DataModel.User.Header) == 'undefined') { Clipperz.PM.DataModel.User.Header = {}; }
34
35Clipperz.PM.DataModel.User.Header.RecordIndex = function(args) {
36 Clipperz.PM.DataModel.User.Header.RecordIndex.superclass.constructor.apply(this, arguments);
37
38//console.log("NEW Clipperz.PM.DataModel.User.Header.RecordIndex", args);
39 this._recordsData = new Clipperz.PM.DataModel.EncryptedRemoteObject({
40 'name':'recordsData',
41 'retrieveKeyFunction': args.retrieveKeyFunction,
42 'remoteData': {
43 'data': args.recordsData['data'],
44 'version': args.encryptedDataVersion,
45 'recordsStats': args.recordsStats
46 }//,
47 // 'encryptedDataKeypath': 'data',
48 // 'encryptedVersionKeypath': 'version'
49 });
50
51 this._directLoginsData = new Clipperz.PM.DataModel.EncryptedRemoteObject({
52 'name':'directLoginsData',
53 'retrieveKeyFunction': args.retrieveKeyFunction,
54 'remoteData': {
55 'data': args.directLoginsData['data'],
56 'version': args.encryptedDataVersion
57 }//,
58 // 'encryptedDataKeypath': 'data',
59 // 'encryptedVersionKeypath': 'version'
60 });
61
62 this._lock = new MochiKit.Async.DeferredLock();
63 this._transientState = null;
64
65 this._retrieveRecordDetailFunction = args.retrieveRecordDetailFunction|| Clipperz.Base.exception.raise('MandatoryParameter');
66 this._recordsIndex = args.recordsData['index'] || Clipperz.Base.exception.raise('MandatoryParameter');
67 this._directLoginsIndex = args.directLoginsData['index']|| Clipperz.Base.exception.raise('MandatoryParameter');
68
69 this._records = null;
70
71 return this;
72}
73
74
75Clipperz.Base.extend(Clipperz.PM.DataModel.User.Header.RecordIndex, Object, {
76
77 'toString': function() {
78 return "Clipperz.PM.DataModel.User.Header.RecordIndex";
79 },
80
81 //-------------------------------------------------------------------------
82
83 'retrieveRecordDetailFunction': function () {
84 return this._retrieveRecordDetailFunction;
85 },
86
87 //-------------------------------------------------------------------------
88
89 'recordsIndex': function () {
90 return this._recordsIndex;
91 },
92
93 'recordsData': function () {
94 return this._recordsData;
95 },
96
97 //-------------------------------------------------------------------------
98
99 'directLoginsIndex': function () {
100 return this._directLoginsIndex;
101 },
102
103 'directLoginsData': function () {
104 return this._directLoginsData;
105 },
106
107 //-------------------------------------------------------------------------
108
109 'lock': function () {
110 return this._lock;
111 },
112
113 //-------------------------------------------------------------------------
114
115 'transientState': function () {
116 if (this._transientState == null) {
117 this._transientState = new Clipperz.KeyValueObjectStore(/*{'name':'User.Header.RecordIndex.transientState [1]'}*/);
118 }
119
120 return this._transientState;
121 },
122
123 'resetTransientState': function (isCommitting) {
124//console.log("######## UserHeaderRecordIndex - resetTransientState", Clipperz.Base.deepClone(this._transientState));
125 if (this._transientState != null) {
126 this._transientState.removeAllData();
127 }
128
129 this._transientState = null;
130 },
131
132 //-------------------------------------------------------------------------
133
134 'getRecordKey': function (aRecordReference) {
135 return Clipperz.Async.callbacks("User.Header.RecordIndex.getRecordKey", [
136 MochiKit.Base.method(this, 'getRecordIndexData', aRecordReference),
137 MochiKit.Base.itemgetter('key')
138 ], {trace:false});
139 },
140
141 'setRecordKey': function (aRecordReference, aValue) {
142 return this.updateRecordIndexData(aRecordReference, 'key', aValue);
143 },
144
145 //-------------------------------------------------------------------------
146
147 'getRecordIndexData': function (aRecordReference) {
148 return this.recordsData().getValue(this.recordsIndex()[aRecordReference]);
149 },
150
151 //.........................................................................
152
153 'updateRecordIndexData': function (aRecordReference, aKey, aValue) {
154 return this.recordsData().setValue(this.recordsIndex()[aRecordReference]+'.'+aKey, aValue);
155 },
156
157 //-------------------------------------------------------------------------
158
159 'getDirectLoginIndexData': function (aDirectLoginReference) {
160 return this.directLoginsData().getValue(this.directLoginsIndex()[aDirectLoginReference]);
161 },
162
163 'setDirectLoginIndexData': function (aDirectLoginReference, aKey, aValue) {
164//console.log("UserHeaderRecordIndex.setDirectLoginIndexData", aDirectLoginReference, this.directLoginsIndex()[aDirectLoginReference], aKey);
165//if (MochiKit.Base.isUndefinedOrNull(this.directLoginsIndex()[aDirectLoginReference])) {
166 //throw "PIPPO";
167//}
168 return this.directLoginsData().setValue(this.directLoginsIndex()[aDirectLoginReference] + '.' + aKey, aValue);
169 },
170
171 'addDirectLoginIndexData': function (aDirectLoginReference) {
172//console.log("UserHeaderRecordIndex.addDirectLoginIndexData", aDirectLoginReference, this.directLoginsIndex()[aDirectLoginReference]);
173 return this.directLoginsData().setValue(this.directLoginsIndex()[aDirectLoginReference], {});
174 },
175
176 'removeDirectLoginIndexData': function (aDirectLoginReference) {
177 return this.directLoginsData().removeValue(this.directLoginsIndex()[aDirectLoginReference])
178 },
179
180 //-------------------------------------------------------------------------
181
182 'records': function () {
183 vardeferredResult;
184
185 deferredResult = new Clipperz.Async.Deferred("User.Header.RecordIndex.records", {trace:false});
186 deferredResult.acquireLock(this.lock());
187 deferredResult.addCallback(MochiKit.Base.bind(function () {
188 var innerDeferredResult;
189
190 if (this._records == null) {
191 innerDeferredResult = new Clipperz.Async.Deferred("User.Header.RecordIndex.records <inner deferred>", {trace:false});
192 innerDeferredResult.collectResults({
193 'records': [
194 // MochiKit.Base.method(this.recordsData(), 'getObjectDataStore'),
195 // MochiKit.Base.methodcaller('values')
196 MochiKit.Base.method(this.recordsData(), 'values')
197 ],
198 'recordsStats': [
199 MochiKit.Base.method(this.recordsData(), 'getRemoteData'),
200 MochiKit.Base.itemgetter('recordsStats')
201 ],
202 'directLogins': [
203 // MochiKit.Base.method(this.directLoginsData(), 'getObjectDataStore'),
204 // MochiKit.Base.methodcaller('values')
205 MochiKit.Base.method(this.directLoginsData(), 'values')
206 ]
207 })
208 innerDeferredResult.addCallback(MochiKit.Base.bind(function (someData) {
209 var indexReference;
210 var recordsInvertedIndex;
211 var directLoginsInvertedIndex;
212
213 recordsInvertedIndex = Clipperz.PM.DataModel.User.Header.RecordIndex.invertIndex(this.recordsIndex());
214 directLoginsInvertedIndex= Clipperz.PM.DataModel.User.Header.RecordIndex.invertIndex(this.directLoginsIndex());
215
216 this._records = {};
217
218 for (indexReference in someData['records']) {
219 varrecord;
220 var reference;
221 var updateDate;
222
223 reference = recordsInvertedIndex[indexReference];
224
225 if (typeof(someData['recordsStats'][reference]) != 'undefined') {
226 updateDate = someData['recordsStats'][reference]['updateDate'];
227
228 record = new Clipperz.PM.DataModel.Record({
229 'reference': reference,
230 'retrieveKeyFunction': MochiKit.Base.method(this, 'getRecordKey'),
231 'retrieveRemoteDataFunction':this.retrieveRecordDetailFunction(),
232
233 'retrieveIndexDataFunction':MochiKit.Base.method(this, 'getRecordIndexData'),
234 'updateIndexDataFunction': MochiKit.Base.method(this, 'updateRecordIndexData'),
235 'updateDate': updateDate,
236
237 'retrieveDirectLoginIndexDataFunction':MochiKit.Base.method(this, 'getDirectLoginIndexData'),
238 'setDirectLoginIndexDataFunction': MochiKit.Base.method(this, 'setDirectLoginIndexData'),
239 'removeDirectLoginIndexDataFunction':MochiKit.Base.method(this, 'removeDirectLoginIndexData'),
240
241 'createNewDirectLoginFunction': MochiKit.Base.method(this, 'createNewDirectLogin')
242 });
243
244 this._records[reference] = record;
245 } else {
246Clipperz.log("SKIPPING record " + reference + " as there are no stas associated - " + Clipperz.Base.serializeJSON(someData['records'][reference]));
247 //# skip the record, as it seems it is not present in the DB
248 //updateDate = Clipperz.PM.Date.formatDateWithUTCFormat(new Date());
249 }
250 }
251
252 for (indexReference in someData['directLogins']) {
253 // vardirectLogin;
254 var reference;
255 var record;
256
257 reference = directLoginsInvertedIndex[indexReference];
258 record = this._records[recordsInvertedIndex[someData['directLogins'][indexReference]['record']]];
259
260 if (record != null) {
261 // directLogin = new Clipperz.PM.DataModel.DirectLogin({
262 new Clipperz.PM.DataModel.DirectLogin({
263 'reference': reference,
264 'record': record
265 });
266 } else {
267Clipperz.log("WARNING: DIRECT LOGIN without a matching RECORD!!");
268//console.log("direct login data", someData['directLogins']);
269//console.log("current direct login data", someData['directLogins'][indexReference])
270//console.log("reference", reference);
271//console.log("record index", this.recordsIndex());
272//console.log("record inverted index", recordsInvertedIndex);
273 }
274 }
275
276 return this._records;
277 }, this));
278 innerDeferredResult.callback();
279 } else {
280 innerDeferredResult = MochiKit.Async.succeed(this._records);
281 }
282
283 return innerDeferredResult;
284 }, this));
285 deferredResult.releaseLock(this.lock());
286 deferredResult.callback();
287
288 return deferredResult;
289 },
290
291 //-------------------------------------------------------------------------
292
293 'updateRecordIndexForNewRecord': function (aNewRecord) {
294 var newRecordIndex;
295 var recordReference;
296
297 recordReference = aNewRecord.reference();
298 newRecordIndex = (MochiKit.Base.listMax(MochiKit.Base.map(MochiKit.Base.partial(MochiKit.Base.operator.mul, 1), MochiKit.Base.values(this.recordsIndex()))) + 1) + '';
299 this.recordsIndex()[recordReference] = newRecordIndex;
300
301 this.transientState().setValue('newlyCreatedRecordsIndex' + '.' + recordReference, newRecordIndex);
302 this.transientState().setValue('newlyCreatedRecordsReferences'+ '.' + recordReference, aNewRecord);
303 },
304
305 //.........................................................................
306
307 'createNewRecord': function () {
308 var deferredResult;
309 var newRecord;
310
311//console.log("#### new Clipperz.PM.DataModel.Record [4]");
312 newRecord = new Clipperz.PM.DataModel.Record({
313 'retrieveKeyFunction': MochiKit.Base.method(this, 'getRecordKey'),
314 'retrieveRemoteDataFunction':this.retrieveRecordDetailFunction(),
315
316 'retrieveIndexDataFunction':MochiKit.Base.method(this, 'getRecordIndexData'),
317 'updateIndexDataFunction': MochiKit.Base.method(this, 'updateRecordIndexData'),
318 'updateDate': Clipperz.PM.Date.formatDateWithUTCFormat(new Date()),
319
320 'retrieveDirectLoginIndexDataFunction':MochiKit.Base.method(this, 'getDirectLoginIndexData'),
321 'setDirectLoginIndexDataFunction': MochiKit.Base.method(this, 'setDirectLoginIndexData'),
322 'removeDirectLoginIndexDataFunction':MochiKit.Base.method(this, 'removeDirectLoginIndexData'),
323
324 'createNewDirectLoginFunction': MochiKit.Base.method(this, 'createNewDirectLogin')
325 });
326
327 this.transientState().setValue('newRecordsReferences' + '.' + newRecord.reference(), newRecord);
328 this.updateRecordIndexForNewRecord(newRecord);
329
330 deferredResult = Clipperz.Async.callbacks("User.Header.RecordIndex.createNewRecord", [
331 MochiKit.Base.method(this, 'records'),
332 MochiKit.Base.partial(Clipperz.Async.setItemOnObject, newRecord.reference(), newRecord),
333 MochiKit.Base.method(this, 'setRecordKey', newRecord.reference(), Clipperz.PM.Crypto.randomKey()),
334 MochiKit.Base.method(newRecord, 'setLabel', ''),
335 MochiKit.Base.partial(MochiKit.Async.succeed, newRecord)
336 ], {trace:false});
337
338
339 return deferredResult;
340 },
341
342 //-------------------------------------------------------------------------
343
344 'deleteRecord': function (aRecord) {
345 var deferredResult;
346 var recordReference;
347
348 recordReference = aRecord.reference();
349
350 deferredResult = new Clipperz.Async.Deferred("User.Header.RecordIndex.deleteRecord", {trace:false});
351
352 deferredResult.addMethod(aRecord, 'directLogins');
353 deferredResult.addCallback(MochiKit.Base.values);
354 deferredResult.addCallback(MochiKit.Base.map, MochiKit.Base.method(this, 'removeDirectLogin'));
355
356 deferredResult.addMethod(this.recordsData(), 'removeValue', this.recordsIndex()[recordReference]);
357 deferredResult.addCallback(MochiKit.Base.bind(function () {
358 this.transientState().setValue('deleteRecordsIndex' + '.' + recordReference, this.recordsIndex()[recordReference]);
359 delete this.recordsIndex()[recordReference];
360 }, this));
361
362 deferredResult.addMethod(this, 'records');
363 deferredResult.addCallback(MochiKit.Base.itemgetter(recordReference));
364 deferredResult.addMethod(this.transientState(), 'setValue', 'deleteRecordsReferences' + '.' + recordReference);
365
366 deferredResult.addMethod(this, 'records');
367 deferredResult.addCallback(MochiKit.Base.bind(function (someRecords) {
368 delete someRecords[recordReference];
369 }, this));
370 deferredResult.callback();
371
372 return deferredResult;
373 },
374
375 //=========================================================================
376
377 'removeDirectLogin': function (aDirectLogin) {
378 this.directLoginsData().removeValue(this.directLoginsIndex()[aDirectLogin.reference()]);
379 },
380
381 //-------------------------------------------------------------------------
382
383 'createNewDirectLogin': function (aRecord) {
384 var newDirectLogin;
385 varnewDirectLoginIndexValue;
386
387 newDirectLogin = new Clipperz.PM.DataModel.DirectLogin({record:aRecord});
388 newDirectLoginIndexValue = MochiKit.Base.listMax(MochiKit.Base.map(function (aValue) { return aValue * 1; }, MochiKit.Base.values(this.directLoginsIndex()))) + 1;
389
390 this.transientState().setValue('newDirectLoginReferences' + '.' + newDirectLogin.reference(), newDirectLogin);
391
392//console.log("UserHeaderRecordIndex.createNewDirectLogin [1]", newDirectLogin.reference(), newDirectLoginIndexValue);
393 this.directLoginsIndex()[newDirectLogin.reference()] = newDirectLoginIndexValue;
394//console.log("UserHeaderRecordIndex.createNewDirectLogin [2]", newDirectLogin.reference(), this.directLoginsIndex()[newDirectLogin.reference()]);
395 this.directLoginsData().setValue(this.directLoginsIndex()[newDirectLogin.reference()], {'record': this.recordsIndex()[aRecord.reference()]});
396
397 return newDirectLogin;
398 },
399
400 //=========================================================================
401
402 'deleteAllCleanTextData': function () {
403 return Clipperz.Async.callbacks("User.Header.RecordIndex.deleteAllCleanTextData", [
404 // MochiKit.Base.method(this, 'records'),
405 // MochiKit.Base.values,
406 // MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('deleteAllCleanTextData')),
407
408 MochiKit.Base.method(this, 'recordsData'),
409 MochiKit.Base.methodcaller('deleteAllCleanTextData'),
410 MochiKit.Base.method(this, 'directLoginsData'),
411 MochiKit.Base.methodcaller('deleteAllCleanTextData')
412 ], {trace:false});
413 },
414
415 //-------------------------------------------------------------------------
416
417 'hasAnyCleanTextData': function () {
418 var deferredResult;
419
420 deferredResult = new Clipperz.Async.Deferred({trace:false});
421 deferredResult.collectResults({
422 'recordsData': [
423 MochiKit.Base.method(this, 'recordsData'),
424 MochiKit.Base.methodcaller('hasAnyCleanTextData')
425 ],
426 'directLoginsData':[
427 MochiKit.Base.method(this, 'directLoginsData'),
428 MochiKit.Base.methodcaller('hasAnyCleanTextData')
429 ],
430 // 'records': [
431 // MochiKit.Base.method(this, 'records'),
432 // MochiKit.Base.values,
433 // MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('hasAnyCleanTextData')),
434 // Clipperz.Async.collectAll
435 // ]
436 });
437//deferredResult.addCallback(function (aValue) { console.log("USER.Header.RecordIndex.hasAnyCleanTextData", aValue); return aValue});
438
439 // deferredResult.addCallback(MochiKit.Base.values);
440 // deferredResult.addCallback(MochiKit.Base.flattenArguments);
441 // deferredResult.addCallback(function(someValues) {
442 // return MochiKit.Iter.some(someValues, MochiKit.Base.operator.identity);
443 // });
444 deferredResult.addCallback(Clipperz.Async.or);
445
446 deferredResult.callback();
447
448 return deferredResult;
449 },
450
451 //-------------------------------------------------------------------------
452
453 'hasPendingChanges': function () {
454 vardeferredResult;
455
456 deferredResult = new Clipperz.Async.Deferred("User.Header.RecordIndex.hasPendingChanges", {trace:false});
457 deferredResult.collectResults({
458 'recordsData': [
459 MochiKit.Base.method(this, 'recordsData'),
460 MochiKit.Base.methodcaller('hasPendingChanges')
461 ],
462 'directLoginsData': [
463 MochiKit.Base.method(this, 'directLoginsData'),
464 MochiKit.Base.methodcaller('hasPendingChanges')
465 ]
466 });
467//deferredResult.addCallback(function (aValue) { console.log("UserHeaderIndex.hasPendingResults", aValue); return aValue; });
468 deferredResult.addCallback(Clipperz.Async.or);
469 // deferredResult.addCallback(MochiKit.Base.values);
470 // deferredResult.addCallback(MochiKit.Base.flattenArguments);
471 // deferredResult.addCallback(function(someValues) {
472 // return MochiKit.Iter.some(someValues, MochiKit.Base.operator.identity);
473 // });
474 deferredResult.callback();
475
476 return deferredResult;
477 },
478
479 //-------------------------------------------------------------------------
480
481 'commitTransientState': function () {
482 var deferredResult;
483
484 deferredResut = Clipperz.Async.callbacks("User.Header.RecordIndex.commitTransientState", [
485 MochiKit.Base.method(this, 'recordsData'),
486 MochiKit.Base.methodcaller('commitTransientState'),
487
488 MochiKit.Base.method(this, 'directLoginsData'),
489 MochiKit.Base.methodcaller('commitTransientState'),
490
491 MochiKit.Base.method(this, 'resetTransientState', true)
492 ], {trace:false});
493
494 return deferredResult;
495 },
496
497 //-------------------------------------------------------------------------
498
499 'revertChanges': function () {
500 return Clipperz.Async.callbacks("User.Header.RecordIndex.revertChanges", [
501 MochiKit.Base.method(this, 'recordsData'),
502 MochiKit.Base.methodcaller('revertChanges'),
503
504 // MochiKit.Base.method(this, 'directLoginsData'),
505 // MochiKit.Base.methodcaller('revertChanges'),
506
507 MochiKit.Base.method(this, 'records'),
508 MochiKit.Base.bind(function (someRecords) {
509 varrecordReference;
510
511 for (recordReference in this.transientState().getValue('deleteRecordsReferences')) {
512 this.recordsIndex()[recordReference] = this.transientState().getValue('deleteRecordsIndex' + '.' + recordReference);
513 someRecords[recordReference] = this.transientState().getValue('deleteRecordsReferences' + '.' + recordReference);
514 }
515
516 for (recordReference in this.transientState().getValue('newRecordsReferences')) {
517 delete this.recordsIndex()[recordReference];
518 delete someRecords[recordReference];
519 }
520 }, this),
521
522 // MochiKit.Base.method(this, 'directLogins'),
523 MochiKit.Base.bind(function () {
524 vardirectLoginReference;
525
526 //this.transientState().setValue('newDirectLoginReferences' + '.' + newDirectLogin.reference(), newDirectLogin);
527//
528 //this.directLoginsIndex()[newDirectLogin.reference()] = newDirectLoginIndexValue;
529 //this.directLoginsData().setValue(this.directLoginsIndex()[newDirectLogin.reference()], {'record': this.recordsIndex()[aRecord.reference()]});
530
531
532 // for (directLoginReference in this.transientState().getValue('deleteDirectLoginReferences')) {
533 // someDirectLogins[directLoginReference] = this.transientState().getValue('deleteDirectLoginReferences' + '.' + recordReference);
534 // }
535
536 for (directLoginReference in this.transientState().getValue('newDirectLoginReferences')) {
537 // this.directLoginsData().removeValue(this.directLoginsIndex()[directLoginReference]);
538 delete this.directLoginsIndex()[directLoginReference];
539 }
540 }, this),
541
542 MochiKit.Base.method(this, 'directLoginsData'),
543 MochiKit.Base.methodcaller('revertChanges'),
544
545 MochiKit.Base.method(this, 'resetTransientState', false)
546 ], {trace:false});
547 },
548
549 //-------------------------------------------------------------------------
550
551 'prepareRemoteDataWithKey': function (aKey) {
552 // "records": {
553 // "index": {
554 // "eeda70e0392261967bda71c3764da78989c45bbd2bb7be6b941b90f81d9b81b5": "0",
555 // "13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551": "1",
556 // ...
557 // "465a067a0bd2b470fa834de5397e38494de0c7707938262fae3427932e219744": "18",
558 // "4fd1dc2ca860b7fb47cef10a84edb3270da05510b0a30a6b0b083898712d4b9e": "19"
559 // },
560 // "data": "n+AzGEEQXaSRSY4d ... BDypotrXgPo94uHfoXvGFzwCn8w="
561 // },
562 // "directLogins": {
563 // "index": {
564 // "61e87fdc4f1d9112e3b30c1f6812d095dcdb24f014c83319091eb6c9899ec348":"0",
565 // "989593d4c48929f0c8f1581aa96969c622807e99619ed4732026e967530a68ad":"1",
566 // ...
567 // "cb9ae0bba1957075ccdbfd3b3481704d62087687a2ac7c411a4f07d444bde0f7":"17",
568 // "7e1d069b7fa57c03bd7bf48807520feb953157834503aaff8c9d493f37dea69d":"18"
569 // },
570 // "data":"5YG9KKU/OZ5guUgFlms6k1 ... ZG/5Fn0uN+LoAsNfHm+EE62x"
571 // },
572
573 var deferredResult;
574 var result;
575
576//console.log("recordsIndex", this.recordsIndex());
577 result = {};
578
579 deferredResult = new Clipperz.Async.Deferred("User.Header.RecordIndex.prepareRemoteDataWithKey", {trace:false});
580 deferredResult.collectResults({
581 'index':MochiKit.Base.partial(MochiKit.Async.succeed, this.recordsIndex()),
582 'data': [
583 MochiKit.Base.method(this.recordsData(), 'prepareRemoteDataWithKey', aKey),
584 MochiKit.Base.itemgetter('data')
585 ]
586 });
587 deferredResult.addCallback(Clipperz.Async.setItem, result, 'records');
588
589 deferredResult.collectResults({
590 'index':MochiKit.Base.partial(MochiKit.Async.succeed, this.directLoginsIndex()),
591 'data': [
592 MochiKit.Base.method(this.directLoginsData(), 'prepareRemoteDataWithKey', aKey),
593 MochiKit.Base.itemgetter('data')
594 ]
595 });
596 deferredResult.addCallback(Clipperz.Async.setItem, result, 'directLogins');
597
598 deferredResult.addCallback(MochiKit.Async.succeed, result);
599
600 deferredResult.callback();
601
602 return deferredResult;
603 },
604
605 //-------------------------------------------------------------------------
606
607 'updateRecordKeyAndPrepareRemoteData': function (aRecord) {
608 varnewRecordKey;
609 var deferredResult;
610
611 newRecordKey = Clipperz.PM.Crypto.randomKey();
612
613 deferredResult = new Clipperz.Async.Deferred("User.Header.RecordIndex.updateRecordKeyAndPrepareRemoteData", {trace:false});
614 deferredResult.addCallback(MochiKit.Base.method(aRecord, 'prepareRemoteDataWithKey', newRecordKey));
615 deferredResult.addCallbackPass(MochiKit.Base.method(this, 'setRecordKey', aRecord.reference(), newRecordKey));
616 deferredResult.callback();
617
618 return deferredResult;
619 },
620
621 //.........................................................................
622
623 'removeNewRecordWithNoChanges': function (aRecord) {
624 var deferredResult;
625 var recordReference;
626
627 recordReference = aRecord.reference();
628
629 deferredResult = new Clipperz.Async.Deferred("User.Header.RecordIndex.removeNewRecordWithNoChanges", {trace:false});
630
631 deferredResult.addMethod(this.recordsData(), 'removeValue', this.recordsIndex()[recordReference]);
632 deferredResult.addCallback(MochiKit.Base.bind(function () {
633 delete this.recordsIndex()[recordReference];
634 }, this));
635
636 deferredResult.addMethod(this, 'records');
637 deferredResult.addCallback(MochiKit.Base.bind(function (someRecords) {
638 delete someRecords[recordReference];
639 }, this));
640 deferredResult.callback();
641
642 return deferredResult;
643 },
644
645 //.........................................................................
646
647 'prepareRemoteDataForChangedRecords': function () {
648 vardeferredResult;
649 varresult;
650
651 result = {};
652
653 deferredResult = new Clipperz.Async.Deferred("User.Header.RecordIndex.prepareRemoteDataForChangedRecords", {trace:false});
654
655 deferredResult.addMethod(this, 'records');
656 deferredResult.addCallback(MochiKit.Base.values);
657 deferredResult.addCallback(Clipperz.Async.deferredFilter, MochiKit.Base.methodcaller('isBrandNewWithNoPendingChanges'));
658 deferredResult.addCallback(MochiKit.Base.map, MochiKit.Base.method(this, 'removeNewRecordWithNoChanges'));
659
660 deferredResult.addMethod(this, 'records');
661 deferredResult.addCallback(MochiKit.Base.values);
662 deferredResult.addCallback(Clipperz.Async.deferredFilter, MochiKit.Base.methodcaller('hasPendingChanges'));
663 deferredResult.addCallback(MochiKit.Base.map, MochiKit.Base.method(this, 'updateRecordKeyAndPrepareRemoteData'));
664 deferredResult.addCallback(Clipperz.Async.collectAll);
665
666 deferredResult.addCallback(Clipperz.Async.deferredIf("updated records != null", [
667 MochiKit.Base.operator.identity
668 ], [
669 MochiKit.Base.partial(MochiKit.Async.succeed, [])
670 ]));
671 deferredResult.addCallback(Clipperz.Async.setItem, result, 'updated');
672
673 deferredResult.addMethod(this.transientState(), 'getValue', 'deleteRecordsReferences');
674 deferredResult.addCallback(MochiKit.Base.keys);
675 deferredResult.addCallback(Clipperz.Async.deferredIf("deleted records != null", [
676 MochiKit.Base.operator.identity
677 ], [
678 MochiKit.Base.partial(MochiKit.Async.succeed, [])
679 ]));
680 deferredResult.addCallback(Clipperz.Async.setItem, result, 'deleted');
681
682 deferredResult.addCallback(MochiKit.Async.succeed, result);
683 deferredResult.callback();
684
685 return deferredResult;
686 },
687
688 //-------------------------------------------------------------------------
689 __syntaxFix__: "syntax fix"
690});
691
692
693
694Clipperz.PM.DataModel.User.Header.RecordIndex.invertIndex = function (anIndex) {
695 var result;
696 var key;
697
698 result = {};
699
700 for (key in anIndex) {
701 result[anIndex[key]] = key;
702 }
703
704 return result;
705}; \ No newline at end of file