Subversion Repositories Applications.papyrus

Rev

Rev 1372 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1318 alexandre_ 1
/*
2
	Copyright (c) 2004-2006, The Dojo Foundation
3
	All Rights Reserved.
4
 
5
	Licensed under the Academic Free License version 2.1 or above OR the
6
	modified BSD license. For more information on Dojo licensing, see:
7
 
8
		http://dojotoolkit.org/community/licensing.shtml
9
*/
10
 
1422 alexandre_ 11
 
12
 
1318 alexandre_ 13
dojo.provide("dojo.data.core.RemoteStore");
14
dojo.require("dojo.data.core.Read");
15
dojo.require("dojo.data.core.Write");
16
dojo.require("dojo.data.core.Result");
17
dojo.require("dojo.experimental");
18
dojo.require("dojo.Deferred");
19
dojo.require("dojo.lang.declare");
20
dojo.require("dojo.json");
21
dojo.require("dojo.io.*");
22
dojo.experimental("dojo.data.core.RemoteStore");
23
dojo.lang.declare("dojo.data.core.RemoteStore", [dojo.data.core.Read, dojo.data.core.Write], {_datatypeMap:{}, _jsonRegistry:dojo.json.jsonRegistry, initializer:function (kwArgs) {
24
	if (!kwArgs) {
25
		kwArgs = {};
26
	}
27
	this._serverQueryUrl = kwArgs.queryUrl || "";
28
	this._serverSaveUrl = kwArgs.saveUrl || "";
29
	this._deleted = {};
30
	this._changed = {};
31
	this._added = {};
32
	this._results = {};
33
	this._data = {};
34
	this._numItems = 0;
35
}, _setupQueryRequest:function (result, requestKw) {
36
	result.query = result.query || "";
37
	requestKw.url = this._serverQueryUrl + encodeURIComponent(result.query);
38
	requestKw.method = "get";
39
	requestKw.mimetype = "text/json";
40
}, _resultToQueryMetadata:function (serverResponseData) {
41
	return serverResponseData;
42
}, _resultToQueryData:function (serverResponseData) {
43
	return serverResponseData.data;
44
}, _remoteToLocalValues:function (attributes) {
45
	for (var key in attributes) {
46
		var values = attributes[key];
47
		for (var i = 0; i < values.length; i++) {
48
			var value = values[i];
49
			var type = value.datatype || value.type;
50
			if (type) {
51
				var localValue = value.value;
52
				if (this._datatypeMap[type]) {
53
					localValue = this._datatypeMap[type](value);
54
				}
55
				values[i] = localValue;
56
			}
57
		}
58
	}
59
	return attributes;
60
}, _queryToQueryKey:function (query) {
61
	if (typeof query == "string") {
62
		return query;
63
	} else {
64
		return dojo.json.serialize(query);
65
	}
66
}, _assertIsItem:function (item) {
67
	if (!this.isItem(item)) {
68
		throw new Error("dojo.data.RemoteStore: a function was passed an item argument that was not an item");
69
	}
70
}, get:function (item, attribute, defaultValue) {
71
	var valueArray = this.getValues(item, attribute);
72
	if (valueArray.length == 0) {
73
		return defaultValue;
74
	}
75
	return valueArray[0];
76
}, getValues:function (item, attribute) {
77
	var itemIdentity = this.getIdentity(item);
78
	this._assertIsItem(itemIdentity);
79
	var changes = this._changed[itemIdentity];
80
	if (changes) {
81
		var newvalues = changes[attribute];
82
		if (newvalues !== undefined) {
83
			return newvalues;
84
		} else {
85
			return [];
86
		}
87
	}
88
	return this._data[itemIdentity][0][attribute];
89
}, getAttributes:function (item) {
90
	var itemIdentity = this.getIdentity(item);
91
	if (!itemIdentity) {
92
		return undefined;
93
	}
94
	var atts = [];
95
	var attrDict = this._data[itemIdentity][0];
96
	for (var att in attrDict) {
97
		atts.push(att);
98
	}
99
	return atts;
100
}, hasAttribute:function (item, attribute) {
101
	var valueArray = this.getValues(item, attribute);
102
	return valueArray.length ? true : false;
103
}, containsValue:function (item, attribute, value) {
104
	var valueArray = this.getValues(item, attribute);
105
	for (var i = 0; i < valueArray.length; i++) {
106
		if (valueArray[i] == value) {
107
			return true;
108
		}
109
	}
110
	return false;
111
}, isItem:function (something) {
112
	if (!something) {
113
		return false;
114
	}
115
	var itemIdentity = something;
116
	if (this._deleted[itemIdentity]) {
117
		return false;
118
	}
119
	if (this._data[itemIdentity]) {
120
		return true;
121
	}
122
	if (this._added[itemIdentity]) {
123
		return true;
124
	}
125
	return false;
126
}, find:function (keywordArgs) {
127
	var result = null;
128
	if (keywordArgs instanceof dojo.data.core.Result) {
129
		result = keywordArgs;
130
		result.store = this;
131
	} else {
132
		result = new dojo.data.core.Result(keywordArgs, this);
133
	}
134
	var query = result.query;
135
	var self = this;
136
	var bindfunc = function (type, data, evt) {
137
		var scope = result.scope || dj_global;
138
		if (type == "load") {
139
			result.resultMetadata = self._resultToQueryMetadata(data);
140
			var dataDict = self._resultToQueryData(data);
141
			if (result.onbegin) {
142
				result.onbegin.call(scope, result);
143
			}
144
			var count = 0;
145
			var resultData = [];
146
			var newItemCount = 0;
147
			for (var key in dataDict) {
148
				if (result._aborted) {
149
					break;
150
				}
151
				if (!self._deleted[key]) {
152
					var values = dataDict[key];
153
					var attributeDict = self._remoteToLocalValues(values);
154
					var existingValue = self._data[key];
155
					var refCount = 1;
156
					if (existingValue) {
157
						refCount = ++existingValue[1];
158
					} else {
159
						newItemCount++;
160
					}
161
					self._data[key] = [attributeDict, refCount];
162
					resultData.push(key);
163
					count++;
164
					if (result.onnext) {
165
						result.onnext.call(scope, key, result);
166
					}
167
				}
168
			}
169
			self._results[self._queryToQueryKey(query)] = resultData;
170
			self._numItems += newItemCount;
171
			result.length = count;
172
			if (result.saveResult) {
173
				result.items = resultData;
174
			}
175
			if (!result._aborted && result.oncompleted) {
176
				result.oncompleted.call(scope, result);
177
			}
178
		} else {
179
			if (type == "error" || type == "timeout") {
180
				dojo.debug("find error: " + dojo.json.serialize(data));
181
				if (result.onerror) {
182
					result.onerror.call(scope, data);
183
				}
184
			}
185
		}
186
	};
187
	var bindKw = keywordArgs.bindArgs || {};
188
	bindKw.sync = result.sync;
189
	bindKw.handle = bindfunc;
190
	this._setupQueryRequest(result, bindKw);
191
	var request = dojo.io.bind(bindKw);
192
	result._abortFunc = request.abort;
193
	return result;
194
}, getIdentity:function (item) {
195
	if (!this.isItem(item)) {
196
		return null;
197
	}
198
	return (item.id ? item.id : item);
199
}, newItem:function (attributes, keywordArgs) {
200
	var itemIdentity = keywordArgs["identity"];
201
	if (this._deleted[itemIdentity]) {
202
		delete this._deleted[itemIdentity];
203
	} else {
204
		this._added[itemIdentity] = 1;
205
	}
206
	if (attributes) {
207
		for (var attribute in attributes) {
208
			var valueOrArrayOfValues = attributes[attribute];
209
			if (dojo.lang.isArray(valueOrArrayOfValues)) {
210
				this.setValues(itemIdentity, attribute, valueOrArrayOfValues);
211
			} else {
212
				this.set(itemIdentity, attribute, valueOrArrayOfValues);
213
			}
214
		}
215
	}
216
	return {id:itemIdentity};
217
}, deleteItem:function (item) {
218
	var identity = this.getIdentity(item);
219
	if (!identity) {
220
		return false;
221
	}
222
	if (this._added[identity]) {
223
		delete this._added[identity];
224
	} else {
225
		this._deleted[identity] = 1;
226
	}
227
	if (this._changed[identity]) {
228
		delete this._changed[identity];
229
	}
230
	return true;
231
}, setValues:function (item, attribute, values) {
232
	var identity = this.getIdentity(item);
233
	if (!identity) {
234
		return undefined;
235
	}
236
	var changes = this._changed[identity];
237
	if (!changes) {
238
		changes = {};
239
		this._changed[identity] = changes;
240
	}
241
	changes[attribute] = values;
242
	return true;
243
}, set:function (item, attribute, value) {
244
	return this.setValues(item, attribute, [value]);
245
}, unsetAttribute:function (item, attribute) {
246
	return this.setValues(item, attribute, []);
247
}, _initChanges:function () {
248
	this._deleted = {};
249
	this._changed = {};
250
	this._added = {};
251
}, _setupSaveRequest:function (saveKeywordArgs, requestKw) {
252
	requestKw.url = this._serverSaveUrl;
253
	requestKw.method = "post";
254
	requestKw.mimetype = "text/plain";
255
	var deleted = [];
256
	for (var key in this._deleted) {
257
		deleted.push(key);
258
	}
259
	var saveStruct = {"changed":this._changed, "deleted":deleted};
260
	var oldRegistry = dojo.json.jsonRegistry;
261
	dojo.json.jsonRegistry = this._jsonRegistry;
262
	var jsonString = dojo.json.serialize(saveStruct);
263
	dojo.json.jsonRegistry = oldRegistry;
264
	requestKw.postContent = jsonString;
265
}, save:function (keywordArgs) {
266
	keywordArgs = keywordArgs || {};
267
	var result = new dojo.Deferred();
268
	var self = this;
269
	var bindfunc = function (type, data, evt) {
270
		if (type == "load") {
271
			if (result.fired == 1) {
272
				return;
273
			}
274
			var key = null;
275
			for (key in self._added) {
276
				if (!self._data[key]) {
277
					self._data[key] = [{}, 1];
278
				}
279
			}
280
			for (key in self._changed) {
281
				var existing = self._data[key];
282
				var changes = self._changed[key];
283
				if (existing) {
284
					existing[0] = changes;
285
				} else {
286
					self._data[key] = [changes, 1];
287
				}
288
			}
289
			for (key in self._deleted) {
290
				if (self._data[key]) {
291
					delete self._data[key];
292
				}
293
			}
294
			self._initChanges();
295
			result.callback(true);
296
		} else {
297
			if (type == "error" || type == "timeout") {
298
				result.errback(data);
299
			}
300
		}
301
	};
302
	var bindKw = {sync:keywordArgs["sync"], handle:bindfunc};
303
	this._setupSaveRequest(keywordArgs, bindKw);
304
	var request = dojo.io.bind(bindKw);
305
	result.canceller = function (deferred) {
306
		request.abort();
307
	};
308
	return result;
309
}, revert:function () {
310
	this._initChanges();
311
	return true;
312
}, isDirty:function (item) {
313
	if (item) {
314
		var identity = item.id || item;
315
		return this._deleted[identity] || this._changed[identity];
316
	} else {
317
		var key = null;
318
		for (key in this._changed) {
319
			return true;
320
		}
321
		for (key in this._deleted) {
322
			return true;
323
		}
324
		for (key in this._added) {
325
			return true;
326
		}
327
		return false;
328
	}
329
}, createReference:function (idstring) {
330
	return {id:idstring};
331
}, getSize:function () {
332
	return this._numItems;
333
}, forgetResults:function (query) {
334
	var queryKey = this._queryToQueryKey(query);
335
	var results = this._results[queryKey];
336
	if (!results) {
337
		return false;
338
	}
339
	var removed = 0;
340
	for (var i = 0; i < results.length; i++) {
341
		var key = results[i];
342
		var existingValue = this._data[key];
343
		if (existingValue[1] <= 1) {
344
			delete this._data[key];
345
			removed++;
346
		} else {
347
			existingValue[1] = --existingValue[1];
348
		}
349
	}
350
	delete this._results[queryKey];
351
	this._numItems -= removed;
352
	return true;
353
}});
354