Project

General

Profile

Download (13.8 KB) Statistics
| Branch: | Revision:
1
define([
2
"dojo/_base/declare", 
3
"dojo/_base/lang", 
4
"dojo/_base/window", 
5
"dojo/_base/json", 
6
"dojo/_base/xhr"],
7
  function(declare, lang, winUtil, jsonUtil, xhr) {
8

    
9
return declare("fileTree.FileStore", null, {
10
    constructor: function(/*Object*/args){
11
        //	summary:
12
        //		A simple store that provides a datastore interface to a filesystem.
13
        //	description:
14
        //		A simple store that provides a datastore interface to a filesystem.  It takes a few parameters
15
        //		for initialization:
16
        //			url:	The URL of the service which provides the file store serverside implementation.
17
        //			label:	The attribute of the file to use as the huma-readable text.  Default is 'name'.
18
        //		The purpose of this store is to represent a file as a datastore item.  The
19
        //		datastore item by default has the following attributes that can be examined on it.
20
        //			directory:	Boolean indicating if the file item represents a directory.
21
        //			name:	The filename with no path informatiom.
22
        //			path:	The file complete file path including name, relative to the location the
23
        //					file service scans from
24
        //			size:	The size of the file, in bytes.
25
        //			children:	Any child files contained by a directory file item.
26
        //
27
        //		Note that the store's server call pattern is RESTlike.
28
        //
29
        //		The store also supports the passing of configurable options to the back end service, such as
30
        //		expanding all child files (no lazy load), displaying hidden files, displaying only directories, and so on.
31
        //		These are defined through a comma-separated list in declarative, or through setting the options array in programmatic.
32
        //		example:	options="expand,dirsOnly,showHiddenFiles"
33
        if(args && args.label){
34
            this.label = args.label;
35
        }
36
        if(args && args.url){
37
            this.url = args.url;
38
        }
39
        if(args && args.options){
40
            if(lang.isArray(args.options)){
41
                this.options = args.options;
42
            }else{
43
                if(lang.isString(args.options)){
44
                    this.options = args.options.split(",");
45
                }
46
            }
47
        }
48
        if(args && args.pathAsQueryParam){
49
            this.pathAsQueryParam = true;
50
        }
51
        if(args && "urlPreventCache" in args){
52
            this.urlPreventCache = args.urlPreventCache?true:false;
53
        }
54
    },
55

    
56
    // url: [public] string
57
    //		The URL to the file path service.
58
    url: "",
59

    
60
    // _storeRef: [private] string
61
    //		Internal variable used to denote an item came from this store instance.
62
    _storeRef: "_S",
63

    
64
    // label: [public] string
65
    //		Default attribute to use to represent the item as a user-readable
66
    //		string.  Public, so users can change it.
67
    label: "name",
68

    
69
    // _identifier: [private] string
70
    //		Default attribute to use to represent the item's identifier.
71
    //		Path should always be unique in the store instance.
72
    _identifier: "path",
73

    
74
    // _attributes: [private] string
75
    //		Internal variable of attributes all file items should have.
76
    _attributes: ["children", "directory", "name", "path", "modified", "size"], 
77

    
78
    // pathSeparator: [public] string
79
    //		The path separator to use when chaining requests for children
80
    //		Can be overriden by the server on initial load
81
    pathSeparator: "/",
82

    
83
    // options: [public] array
84
    //		Array of options to always send when doing requests.
85
    //		Back end service controls this, like 'dirsOnly', 'showHiddenFiles', 'expandChildren', etc.
86
    options: [],
87

    
88
    // failOk: [public] boolean
89
    //		Flag to pass on to xhr functions to check if we are OK to fail the call silently
90
    failOk: false,
91

    
92
    // urlPreventCache: [public] string
93
    //		Flag to dennote if preventCache should be passed to xhrGet.
94
    urlPreventCache: true,
95

    
96
    _assertIsItem: function(/* item */ item){
97
        // summary:
98
        //      This function tests whether the item passed in is indeed an item in the store.
99
        // item:
100
        //		The item to test for being contained by the store.
101
        if(!this.isItem(item)){
102
            throw new Error("dojox.data.FileStore: a function was passed an item argument that was not an item");
103
        }
104
    },
105

    
106
    _assertIsAttribute: function(/* attribute-name-string */ attribute){
107
        // summary:
108
        //		This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
109
        // attribute:
110
        //		The attribute to test for being contained by the store.
111
        if(typeof attribute !== "string"){
112
            throw new Error("dojox.data.FileStore: a function was passed an attribute argument that was not an attribute name string");
113
        }
114
    },
115

    
116
    pathAsQueryParam: false, //Function to switch between REST style URL lookups and passing the path to specific items as a query param: 'path'.
117

    
118
    getFeatures: function(){
119
        // summary:
120
        //      See dojo.data.api.Read.getFeatures()
121
        return {
122
            'dojo.data.api.Read': true, 'dojo.data.api.Identity':true
123
        };
124
    },
125

    
126
    getValue: function(item, attribute, defaultValue){
127
        // summary:
128
        //      See dojo.data.api.Read.getValue()
129
        var values = this.getValues(item, attribute);
130
        if(values && values.length > 0){
131
            return values[0];
132
        }
133
        return defaultValue;
134
    },
135

    
136
    getAttributes: function(item){
137
        // summary:
138
        //      See dojo.data.api.Read.getAttributes()
139
        return this._attributes;
140
    },
141

    
142
    hasAttribute: function(item, attribute){
143
        // summary:
144
        //      See dojo.data.api.Read.hasAttribute()
145
        this._assertIsItem(item);
146
        this._assertIsAttribute(attribute);
147
        return (attribute in item);
148
    },
149

    
150
    getIdentity: function(/* item */ item){
151
        // summary:
152
        //		See dojo.data.api.Identity.getIdentity()
153
        return this.getValue(item, this._identifier);
154
    },
155

    
156
    getIdentityAttributes: function(item){
157
        // summary:
158
        //      See dojo.data.api.Read.getLabelAttributes()
159
        return [this._identifier];
160
    },
161

    
162

    
163
    isItemLoaded: function(item){
164
         //	summary:
165
         //      See dojo.data.api.Read.isItemLoaded()
166
         var loaded = this.isItem(item);
167
         if(loaded && typeof item._loaded == "boolean" && !item._loaded){
168
            loaded = false;
169
         }
170
         return loaded;
171
    },
172

    
173
    loadItem: function(keywordArgs){
174
        // summary:
175
        //      See dojo.data.api.Read.loadItem()
176
        var item = keywordArgs.item;
177
        var self = this;
178
        var scope = keywordArgs.scope || winUtil.global;
179

    
180
        var content = {};
181

    
182
        if(this.options.length > 0){
183
            content.options = jsonUtil.toJson(this.options);
184
        }
185

    
186
        if(this.pathAsQueryParam){
187
            // content.path = item.parentPath + this.pathSeparator + item.name;
188
            content.path = item.path;
189
        }
190
        var xhrData = {
191
            url: this.pathAsQueryParam ? this.url : this.url + item.path,
192
            handleAs: "json-comment-optional",
193
            content: content,
194
            preventCache: this.urlPreventCache,
195
            failOk: this.failOk
196
        };
197

    
198
        var deferred = xhr.get(xhrData);
199
        deferred.addErrback(function(error){
200
                if(keywordArgs.onError){
201
                    keywordArgs.onError.call(scope, error);
202
                }
203
        });
204

    
205
        deferred.addCallback(function(data){
206
            // got children (subdir) from backend
207
            item.children = data;
208
            item._loaded = true;
209
            self._processItemArray(data);
210
            if(keywordArgs.onItem){
211
                keywordArgs.onItem.call(scope, item);
212
            }
213
        });
214
    },
215

    
216
    getLabel: function(item){
217
        // summary:
218
        //      See dojo.data.api.Read.getLabel()
219
        return this.getValue(item,this.label);
220
    },
221

    
222
    getLabelAttributes: function(item){
223
        // summary:
224
        //      See dojo.data.api.Read.getLabelAttributes()
225
        return [this.label];
226
    },
227

    
228
    containsValue: function(item, attribute, value){
229
        // summary:
230
        //      See dojo.data.api.Read.containsValue()
231
        var values = this.getValues(item,attribute);
232
        for(var i = 0; i < values.length; i++){
233
            if(values[i] == value){
234
                return true;
235
            }
236
        }
237
        return false;
238
    },
239

    
240
    getValues: function(item, attribute){
241
        // summary:
242
        //      See dojo.data.api.Read.getValue()
243
        this._assertIsItem(item);
244
        this._assertIsAttribute(attribute);
245

    
246
        var value = item[attribute];
247
        if(typeof value !== "undefined" && !lang.isArray(value)){
248
            value = [value];
249
        }else if(typeof value === "undefined"){
250
            value = [];
251
        }
252
        return value;
253
    },
254

    
255
    isItem: function(item){
256
        // summary:
257
        //      See dojo.data.api.Read.isItem()
258
        if(item && item[this._storeRef] === this){
259
            return true;
260
        }
261
        return false;
262
    },
263

    
264
    close: function(request){
265
        // summary:
266
        //      See dojo.data.api.Read.close()
267
    },
268

    
269
    fetch: function(request){
270
        // summary:
271
        //		Fetch  items that match to a query
272
        // request:
273
        //		A request object
274

    
275
        request = request || {};
276
        if(!request.store){
277
            request.store = this;
278
        }
279
        var self = this;
280
        var scope = request.scope || winUtil.global;
281

    
282
        //Generate what will be sent over.
283
        var reqParams = {};
284
        if(request.query){
285
            reqParams.query = jsonUtil.toJson(request.query);
286
        }
287

    
288
        if(request.sort){
289
            reqParams.sort = jsonUtil.toJson(request.sort);
290
        }
291

    
292
        if(request.queryOptions){
293
            reqParams.queryOptions = jsonUtil.toJson(request.queryOptions);
294
        }
295

    
296
        if(typeof request.start == "number"){
297
            reqParams.start = "" + request.start;
298
        }
299
        if(typeof request.count == "number"){
300
            reqParams.count = "" + request.count;
301
        }
302

    
303
        if(this.options.length > 0){
304
            reqParams.options = jsonUtil.toJson(this.options);
305
        }
306

    
307
        var getArgs = {
308
            url: this.url,
309
            preventCache: this.urlPreventCache,
310
            failOk: this.failOk,
311
            handleAs: "json-comment-optional",
312
            content: reqParams
313
        };
314

    
315

    
316
        var deferred = xhr.get(getArgs);
317

    
318
        deferred.addCallback(function(data){self._processResult(data, request);});
319
        deferred.addErrback(function(error){
320
            if(request.onError){
321
                request.onError.call(scope, error, request);
322
            }
323
        });
324
    },
325

    
326
    fetchItemByIdentity: function(keywordArgs){
327
        // summary:
328
        //      See dojo.data.api.Read.loadItem()
329
        console.error('not implemented yet!');
330

    
331
        // var path = keywordArgs.identity;
332
        // var self = this;
333
        // var scope = keywordArgs.scope || winUtil.global;
334

    
335
        // var content = {};
336

    
337
        // if(this.options.length > 0){
338
        //     content.options = jsonUtil.toJson(this.options);
339
        // }
340

    
341
        // if(this.pathAsQueryParam){
342
        //     content.path = path;
343
        // }
344
        // var xhrData = {
345
        //     url: this.pathAsQueryParam? this.url : this.url + "/" + path,
346
        //     handleAs: "json-comment-optional",
347
        //     content: content,
348
        //     preventCache: this.urlPreventCache,
349
        //     failOk: this.failOk
350
        // };
351

    
352
        // var deferred = xhr.get(xhrData);
353
        // deferred.addErrback(function(error){
354
        //         if(keywordArgs.onError){
355
        //             keywordArgs.onError.call(scope, error);
356
        //         }
357
        // });
358

    
359
        // deferred.addCallback(function(data){
360
        //     var item = self._processItem(data);
361
        //     if(keywordArgs.onItem){
362
        //         keywordArgs.onItem.call(scope, item);
363
        //     }
364
        // });
365
    },
366

    
367
    _processResult: function(data, request){
368
         var scope = request.scope || winUtil.global;
369
         try{
370
             //If the data contains a path separator, set ours
371
             if(data.pathSeparator){
372
                 this.pathSeparator = data.pathSeparator;
373
             }
374

    
375
			 if(request.onBegin){
376
				 request.onBegin.call(scope, data.length, request);
377
			 }
378

    
379
             var items = this._processItemArray(data);
380
             
381
             if(request.onItem){
382
				var i;
383
				for(i = 0; i < items.length; i++){
384
					request.onItem.call(scope, items[i], request);
385
				}
386
				items = null;
387
             }
388
             if(request.onComplete){
389
                 request.onComplete.call(scope, items, request);
390
             }
391
         }catch (e){
392
             if(request.onError){
393
                 request.onError.call(scope, e, request);
394
             }else{
395
                 console.log(e);
396
             }
397
         }
398
    },
399

    
400
    _processItemArray: function(itemArray){
401
         //	summary:
402
         //		Internal function for processing an array of items for return.
403
         var i;
404
         for(i = 0; i < itemArray.length; i++){
405
            this._processItem(itemArray[i]);
406
         }
407
         return itemArray;
408
    },
409

    
410
    _processItem: function(item){
411
        //	summary:
412
        //		Internal function for processing an item returned from the store.
413
        //		It sets up the store ref as well as sets up the attributes necessary
414
        //		to invoke a lazy load on a child, if there are any.
415
        if(!item){return null;}
416

    
417
        item[this._storeRef] = this;
418
        item.directory = item.path.charAt(item.path.length-1) === '/';
419

    
420
        if(!item['_loaded']){
421
            if(item.directory){
422
                // the model (ForestStoreModel) picks up this
423
                // childrenAttrs there must contain 'children'
424
                item.children = [];
425
                item._loaded = false;
426
            }
427
        }
428
        return item;
429
    }
430
});
431
});
(1-1/5)