Subversion Repositories Applications.papyrus

Rev

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