source: Dev/branches/rest-dojo-ui/client/dojox/atom/io/Connection.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

  • Property svn:executable set to *
File size: 13.6 KB
Line 
1define([
2        "dojo/_base/kernel",
3        "dojo/_base/xhr",
4        "dojo/_base/window",
5        "./model",
6        "dojo/_base/declare"], function (dojo, xhrUtil, windowUtil, model) {
7return dojo.declare("dojox.atom.io.Connection",null,{
8        // summary: This object implements a transport layer for working with ATOM feeds and ATOM publishing protocols.
9        // description: This object implements a transport layer for working with ATOM feeds and ATOM publishing protocols.
10        //   Specifically, it provides a mechanism by which feeds can be fetched and entries can be fetched, created
11        //   deleted, and modified.  It also provides access to the introspection data.
12
13        constructor: function(/* Boolean */sync, /* Boolean */preventCache){
14                //      summary:
15                //              initializer
16                this.sync = sync;
17                this.preventCache = preventCache;
18        },
19
20        preventCache: false, //Flag to denote if the instance should use the xhr prevent cache mechanism
21
22        alertsEnabled: false, //Flag to turn on alerts instead of throwing errors.
23
24        getFeed: function(/*String*/url, /*Function*/callback, /*Function*/errorCallback, scope){
25                //      summary:
26                //              Function to obtain a s specific ATOM feed from a given ATOM Feed url.
27                //      description:
28                //              This function takes the URL for a specific ATOM feed and returns
29                //              the data from that feed to the caller through the use of a callback
30                //              handler.
31                //
32                //      url: String
33                //              The URL of the ATOM feed to fetch.
34                //      callback:
35                //              Function
36                //              A function reference that will handle the feed when it has been retrieved.
37                //              The callback should accept two parameters:  The feed object and the original complete DOM object.
38                //      scope: Object
39                //              The scope to use for all callbacks.
40                //
41                //      returns:
42                //              Nothing. The return is handled through the callback handler.
43                this._getXmlDoc(url, "feed", new model.Feed(), model._Constants.ATOM_NS, callback, /*handleDocumentRetrieved,*/ errorCallback, scope);
44        },
45       
46        getService: function(url, callback, errorCallback, scope){
47                //      summary:
48                //              Function to retrieve an introspection document from the given URL.
49                //      description:
50                //              This function takes the URL for an ATOM item and feed and returns
51                //              the introspection document.
52                //
53                //      url:
54                //              String
55                //              The URL of the ATOM document to obtain the introspection document of.
56                //      callback:
57                //              Function
58                //              A function reference that will handle the introspection document when it has been retrieved.
59                //              The callback should accept two parameters:  The introspection document object and the original complete DOM object.
60                //
61                //      returns:
62                //              Nothing. The return is handled through the callback handler.
63                this._getXmlDoc(url, "service", new model.Service(url), model._Constants.APP_NS, callback, errorCallback, scope);
64        },
65       
66        getEntry: function(url, callback, errorCallback, scope){
67                //      summary:
68                //              Function to retrieve a single entry from an ATOM feed from the given URL.
69                //      description:
70                //              This function takes the URL for an ATOM entry and returns the constructed dojox.atom.io.model.Entry object through
71                //              the specified callback.
72                //
73                //      url:
74                //              String
75                //              The URL of the ATOM Entry document to parse.
76                //      callback:
77                //              Function
78                //              A function reference that will handle the Entry object obtained.
79                //              The callback should accept two parameters, the dojox.atom.io.model.Entry object and the original dom.
80                //
81                //      returns:
82                //              Nothing. The return is handled through the callback handler.
83                this._getXmlDoc(url, "entry", new model.Entry(), model._Constants.ATOM_NS, callback, errorCallback, scope);
84        },
85
86        _getXmlDoc: function(url, nodeName, newNode, namespace, callback, errorCallback, scope){
87                //      summary:
88                //              Internal Function to retrieve an XML document and pass the results to a callback.
89                //      description:
90                //              This internal function takes the URL for an XML document and and passes the
91                //              parsed contents to a specified callback.
92                //
93                //      url:
94                //              String
95                //              The URL of the XML document to retrieve
96                //      callback:
97                //              Function
98                //              A function reference that will handle the retrieved XML data.
99                //              The callback should accept one parameter, the DOM of the parsed XML document.
100                //
101                //      returns:
102                //              Nothing. The return is handled through the callback handler.
103                if(!scope){
104                        scope = windowUtil.global;
105                }
106                var ae = this.alertsEnabled;
107                var xhrArgs = {
108                        url: url,
109                        handleAs: "xml",
110                        sync: this.sync,
111                        preventCache: this.preventCache,
112                        load: function(data, args){
113                                var node         = null;
114                                var evaldObj = data;
115                                var nodes;
116                                if(evaldObj){
117                                        //find the first node of the appropriate name
118                                        if(typeof(evaldObj.getElementsByTagNameNS)!= "undefined"){
119                                                nodes = evaldObj.getElementsByTagNameNS(namespace,nodeName);
120                                                if(nodes && nodes.length > 0){
121                                                        node = nodes.item(0);
122                                                }else if(evaldObj.lastChild){
123                                                        // name_spaces can be used without declaration of atom (for example
124                                                        // gooogle feeds often returns iTunes name_space qualifiers on elements)
125                                                        // Treat this situation like name_spaces not enabled.
126                                                        node = evaldObj.lastChild;
127                                                }
128                                        }else if(typeof(evaldObj.getElementsByTagName)!= "undefined"){
129                                                // Find the first eith the correct tag name and correct namespace.
130                                                nodes = evaldObj.getElementsByTagName(nodeName);
131                                                if(nodes && nodes.length > 0){
132                                                        for(var i=0; i<nodes.length; i++){
133                                                                if(nodes[i].namespaceURI == namespace){
134                                                                        node = nodes[i];
135                                                                        break;
136                                                                }
137                                                        }
138                                                }else if(evaldObj.lastChild){
139                                                        node = evaldObj.lastChild;
140                                                }
141                                        }else if(evaldObj.lastChild){
142                                                node = evaldObj.lastChild;
143                                        }else{
144                                                callback.call(scope, null, null, args);
145                                                return;
146                                        }
147                                        newNode.buildFromDom(node);
148                                        if(callback){
149                                                callback.call(scope, newNode, evaldObj, args);
150                                        }else if(ae){
151                                                throw new Error("The callback value does not exist.");
152                                        }
153                                }else{
154                                        callback.call(scope, null, null, args);
155                                }
156                        }
157                };
158
159                if(this.user && this.user !== null){
160                        xhrArgs.user = this.user;
161                }
162                if(this.password && this.password !== null){
163                        xhrArgs.password = this.password;
164                }
165
166                if(errorCallback){
167                        xhrArgs.error = function(error, args){errorCallback.call(scope, error, args);};
168                }else{
169                        xhrArgs.error = function(){
170                                throw new Error("The URL requested cannot be accessed");
171                        };
172                }
173                xhrUtil.get(xhrArgs);
174        },
175
176        updateEntry: function(entry, callback, errorCallback, retrieveUpdated, xmethod, scope){
177                //      summary:
178                //              Function to update a specific ATOM entry by putting the new changes via APP.
179                //      description:
180                //              This function takes a specific dojox.atom.io.model.Entry object and pushes the
181                //              changes back to the provider of the Entry.
182                //              The entry MUST have a link tag with rel="edit" for this to work.
183                //
184                //      entry:
185                //              Object
186                //              The dojox.atom.io.model.Entry object to update.
187                //      callback:
188                //              Function
189                //              A function reference that will handle the results from the entry update.
190                //              The callback should accept two parameters:  The first is an Entry object, and the second is the URL of that Entry
191                //              Either can be null, depending on the value of retrieveUpdated.
192                //      retrieveUpdated:
193                //              boolean
194                //              A boolean flag denoting if the entry that was updated should then be
195                //              retrieved and returned to the caller via the callback.
196                //      xmethod:
197                //              boolean
198                //              Whether to use POST for PUT/DELETE items and send the X-Method-Override header.
199                //      scope:
200                //              Object
201                //              The scope to use for all callbacks.
202                //
203                //      returns:
204                //              Nothing. The return is handled through the callback handler.
205                if(!scope){
206                        scope = windowUtil.global;
207                }
208                entry.updated = new Date();
209                var url = entry.getEditHref();
210                if(!url){
211                        throw new Error("A URL has not been specified for editing this entry.");
212                }
213
214                var self = this;
215                var ae = this.alertsEnabled;
216                var xhrArgs = {
217                        url: url,
218                        handleAs: "text",
219                        contentType: "text/xml",
220                        sync: this.sync,
221                        preventCache: this.preventCache,
222                        load: function(data, args){
223                                var location = null;
224                                if(retrieveUpdated){
225                                        location = args.xhr.getResponseHeader("Location");
226                                        if(!location){location = url;}
227
228                                        //Function to handle the callback mapping of a getEntry after an update to return the
229                                        //entry and location.
230                                        var handleRetrieve = function(entry, dom, args){
231                                                if(callback){
232                                                        callback.call(scope, entry, location, args);
233                                                }else if(ae){
234                                                        throw new Error("The callback value does not exist.");
235                                                }
236                                        };
237                                        self.getEntry(location,handleRetrieve);
238                                }else{
239                                        if(callback){
240                                                callback.call(scope, entry, args.xhr.getResponseHeader("Location"), args);
241                                        }else if(ae){
242                                                throw new Error("The callback value does not exist.");
243                                        }
244                                }
245                                return data;
246                        }
247                };
248               
249                if(this.user && this.user !== null){
250                        xhrArgs.user = this.user;
251                }
252                if(this.password && this.password !== null){
253                        xhrArgs.password = this.password;
254                }
255
256                if(errorCallback){
257                        xhrArgs.error = function(error, args){errorCallback.call(scope, error, args);};
258                }else{
259                        xhrArgs.error = function(){
260                                throw new Error("The URL requested cannot be accessed");
261                        };
262                }
263
264                if(xmethod){
265                        xhrArgs.postData = entry.toString(true); //Set the content to send.
266                        xhrArgs.headers = {"X-Method-Override": "PUT"};
267                        xhrUtil.post(xhrArgs);
268                }else{
269                        xhrArgs.putData = entry.toString(true); //Set the content to send.
270                        var xhr = xhrUtil.put(xhrArgs);
271                }
272        },
273
274        addEntry: function(entry, url, callback, errorCallback, retrieveEntry, scope){
275                //      summary:
276                //              Function to add a new ATOM entry by posting the new entry via APP.
277                //      description:
278                //              This function takes a specific dojox.atom.io.model.Entry object and pushes the
279                //              changes back to the provider of the Entry.
280                //
281                //      entry:
282                //              Object
283                //              The dojox.atom.io.model.Entry object to publish.
284                //      callback:
285                //              Function
286                //              A function reference that will handle the results from the entry publish.
287                //              The callback should accept two parameters:   The first is an dojox.atom.io.model.Entry object, and the second is the location of the entry
288                //              Either can be null, depending on the value of retrieveUpdated.
289                //      retrieveEntry:
290                //              boolean
291                //              A boolean flag denoting if the entry that was created should then be
292                //              retrieved and returned to the caller via the callback.
293                //      scope:
294                //              Object
295                //              The scope to use for all callbacks.
296                //
297                //      returns:
298                //              Nothing. The return is handled through the callback handler.
299                if(!scope){
300                        scope = windowUtil.global;
301                }
302
303                entry.published = new Date();
304                entry.updated = new Date();
305
306                var feedUrl = entry.feedUrl;
307                var ae = this.alertsEnabled;
308
309                //Determine which URL to use for the post.
310                if(!url && feedUrl){url = feedUrl;}
311                if(!url){
312                        if(ae){
313                                throw new Error("The request cannot be processed because the URL parameter is missing.");
314                        }
315                        return;
316                }
317
318                var self = this;
319                var xhrArgs = {
320                        url: url,
321                        handleAs: "text",
322                        contentType: "text/xml",
323                        sync: this.sync,
324                        preventCache: this.preventCache,
325                        postData: entry.toString(true),
326                        load: function(data, args){
327                                var location = args.xhr.getResponseHeader("Location");
328                                if(!location){
329                                        location = url;
330                                }
331                                if(!args.retrieveEntry){
332                                        if(callback){
333                                                callback.call(scope, entry, location, args);
334                                        }else if(ae){
335                                                throw new Error("The callback value does not exist.");
336                                        }
337                                }else{
338                                        //Function to handle the callback mapping of a getEntry after an update to return the
339                                        //entry and location.
340                                        var handleRetrieve = function(entry, dom, args){
341                                                if(callback){
342                                                        callback.call(scope, entry, location, args);
343                                                }else if(ae){
344                                                        throw new Error("The callback value does not exist.");
345                                                }
346                                        };
347                                        self.getEntry(location,handleRetrieve);
348                                }
349                                return data;
350                        }
351                };
352
353                if(this.user && this.user !== null){
354                        xhrArgs.user = this.user;
355                }
356                if(this.password && this.password !== null){
357                        xhrArgs.password = this.password;
358                }
359
360                if(errorCallback){
361                        xhrArgs.error = function(error, args){errorCallback.call(scope, error, args);};
362                }else{
363                        xhrArgs.error = function(){
364                                throw new Error("The URL requested cannot be accessed");
365                        };
366                }
367                xhrUtil.post(xhrArgs);
368        },
369
370        deleteEntry: function(entry,callback,errorCallback,xmethod,scope){
371                //      summary:
372                //              Function to delete a specific ATOM entry via APP.
373                //      description:
374                //              This function takes a specific dojox.atom.io.model.Entry object and calls for a delete on the
375                //              service housing the ATOM Entry database.
376                //              The entry MUST have a link tag with rel="edit" for this to work.
377                //
378                //      entry:
379                //              Object
380                //              The dojox.atom.io.model.Entry object to delete.
381                //      callback:
382                //              Function
383                //              A function reference that will handle the results from the entry delete.
384                //              The callback is called only if the delete is successful.
385                //
386                //      returns:
387                //              Nothing. The return is handled through the callback handler.
388                if(!scope){
389                        scope = windowUtil.global;
390                }
391
392                var url = null;
393                if(typeof(entry) == "string"){
394                        url = entry;
395                }else{
396                        url = entry.getEditHref();
397                }
398                if(!url){
399                        callback.call(scope, false, null);
400                        throw new Error("The request cannot be processed because the URL parameter is missing.");
401                }
402
403                var xhrArgs = {
404                        url: url,
405                        handleAs: "text",
406                        sync: this.sync,
407                        preventCache: this.preventCache,
408                        load: function(data, args){
409                                callback.call(scope, args);
410                                return data;
411                        }
412                };
413
414                if(this.user && this.user !== null){
415                        xhrArgs.user = this.user;
416                }
417                if(this.password && this.password !== null){
418                        xhrArgs.password = this.password;
419                }
420
421                if(errorCallback){
422                        xhrArgs.error = function(error, args){errorCallback.call(scope, error, args);};
423                }else{
424                        xhrArgs.error = function(){
425                                throw new Error("The URL requested cannot be accessed");
426                        };
427                }
428                if(xmethod){
429                        xhrArgs.headers = {"X-Method-Override": "DELETE"};
430                        dhxr.post(xhrArgs);
431                }else{
432                        xhrUtil.del(xhrArgs);
433                }
434        }
435});
436});
Note: See TracBrowser for help on using the repository browser.