Changeset 98

Show
Ignore:
Timestamp:
08/02/06 08:02:35 (2 years ago)
Author:
robin
Message:

namespace refactor done

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • streamservice/trunk/lib/streamservice/Dispatch.js

    r97 r98  
    1  
    2 split_schemedomainandport = function( url){ 
    3     /*** 
    4      
    5     **Split a url into its constituent parts.** 
    6  
    7     If port and or path parts are missing from the url, the associated fields  
    8     are set to null:: 
    9  
    10         sdpp => [scheme, domain, port|null, path|null] 
    11  
    12     Both, ``join_schemedomainandport`` and ``replace_schemedomainandport_path`` 
    13     cope with this. Note that:: 
    14  
    15         join(split('http://some.domain')) => 'http://some.domain/' 
    16         join(split('http://some.domain:8080')) => 'http://some.domain:8080/' 
    17         join(split('http://some.domain/')) => 'http://some.domain/' 
    18         join(split('http://some.domain:8080/')) => 'http://some.domain:8080/' 
    19      
    20     Ie., root path is forced if it is missing. 
    21  
    22     ``url: url to split. if null or undefined currentDocument().URL is used.`` 
    23      
     1if (typeof(streamservice) == 'undefined') { 
     2    streamservice = {}; 
     3
     4 
     5update(streamservice, { 
     6    strip_tag_inplace : function(seperator, item){ 
     7        item[0] = item[0].slice(item[0].split(seperator,1)[0].length + 1); 
     8        return item; 
     9    }, 
     10 
     11    strip_tag : function (seperator, tag){ 
     12        return tag.slice(tag.split(seperator,1)[0].length + 1); 
     13    }, 
     14 
     15    prepare_protocol : function (self, servicepath,  
     16         dispatchparametername, names, values, sdpp){ 
     17        if(self == null) 
     18            self=this; 
     19        if(typeof(self)=="undefined") 
     20            self={}; 
     21 
     22        if(typeof(dispatchparametername) == "undefined" ||  
     23            dispatchparametername==null) 
     24            dispatchparametername="dispatcher"; 
     25        self.dispatchparametername=dispatchparametername; 
     26 
     27        if(typeof(names) == "undefined" || names==null){ 
     28            self.queryparameters=parseQueryString( 
     29                queryString([self.dispatchparametername],["[[],[]]"]), true); 
     30            /*log("***: self.queryparameters = " +  
     31                serializeJSON(self.queryparameters));*/ 
     32        } else { 
     33            /* normalize parameter representation */ 
     34            self.queryparameters=parseQueryString(queryString( 
     35                names, values), true); 
     36            log("***: self.queryparameters = " + serializeJSON( 
     37                self.queryparameters)); 
     38            /* if there is a collision the first element of user specified 
     39               value is clobbered */ 
     40            if(typeof(self.queryparameters[self.dispatchparametername])  
     41                != "undefined"){ 
     42                self.queryparameters[self.dispatchparametername][0]="[[],[]]" 
     43            } 
     44            else{ 
     45                self.queryparameters[self.dispatchparametername]=["[[],[]]"]; 
     46            } 
     47        } 
     48 
     49        if(typeof(sdpp)=="undefined" || sdpp == null){ 
     50            self.sdpp=streamservice.split_schemedomainandport(); 
     51        } else { 
     52            self.sdpp = sdpp; 
     53        } 
     54        self.baseurl=streamservice.replace_schemedomainandport_path( 
     55            self.sdpp, servicepath); 
     56        self.sdpp[3]=servicepath; 
     57 
     58        /* If interval is null or undefined, the Dispatcher uses its own value. 
     59           Otherwise it uses this one. */ 
     60 
     61        return self; 
     62    }, 
     63 
     64    poll_loopback_json : function( 
     65        clientdata,  
     66         latency, 
     67         emulatedbackendpollresult, 
     68         ignoreemulatedresponses){ 
     69        /*** 
     70         
     71        **Loopback implementation for** ``Protocol.poll``.  
     72 
     73        Provided for the benefit of test code. Echos query items, encoded in  
     74        clientdata, as the loopbackresult. 
     75 
     76        ``clientdata: the serialized and encoded queries & responses`` to 
     77        submit on the clients behalf. response items in ``clientdata``  
     78        are silently ignored. 
     79 
     80        ``latency: how long the poll should take``. the default is 0. *Note* 
     81        that latency <= 0 is special, it forces synchronous behaviour. 
     82 
     83        ``emulatedbackendpollresult: emulated backend responses``, Serialized  
     84        and encoded queries & responses fake response to this poll. By  
     85        default, response items are not included in the items looped back 
     86        to the client. 
     87         
     88        ``ignoreemulatedresponses: Don't throw away emulated responses``. if this  
     89        parameter is true then emulated backend responses are included in the  
     90        loopback result. 
     91 
     92        if latency was zero or unspecified the returned 
     93        deferred has allready been fired.:: 
     94 
     95            if latency unspecified or latency <= 0 
     96                returns succede(loopbackresult) 
     97            Otherwise: 
     98                wait(latency, loopbackresult) 
     99 
     100        ``rtype: Deferred`` 
     101 
     102        ***/ 
     103 
     104        if(typeof(latency)=="undefined" || latency==null){ 
     105            latency=0; 
     106        } 
     107        try{ 
     108            /*log("***:" + clientdata);*/ 
     109            var sent = streamservice.split_json(clientdata); 
     110            var recvd = [null,null]; 
     111            if( typeof(emulatedbackendpollresult)!="undefined" && 
     112                emulatedbackendpollresult != null){ 
     113                /*log("***:" + emulatedbackendpollresult); 
     114                  log("***:" + typeof(emulatedbackendpollresult));*/ 
     115                recvd = streamservice.split_json(emulatedbackendpollresult); 
     116                if(ignoreemulatedresponses != false) 
     117                    recvd = [recvd[0],null]; 
     118            } 
     119            /* log("***:" + serializeJSON(recvd)); */ 
     120            var result = streamservice.join_json(recvd[0], sent[0]); 
     121            if(recvd[1] != null){ 
     122                /* merge the emulated responses in *before* the looped back 
     123                   responses */ 
     124                result = streamservice.split_json(result); 
     125                result = streamservice.join_json(result[0],  
     126                    extend(recvd[1], result[1])); 
     127            } 
     128            return latency <= 0 ? succeed(result) : wait(latency, result); 
     129        } catch (result){ 
     130            log("loopback raised:" + result); 
     131            waitfail = function(seconds,  value){ 
     132                var d = wait(seconds); 
     133                d.addBoth(partial(function (value){throw value;}, value)); 
     134                return d; 
     135            } 
     136            return latency <= 0 ? fail(result) : waitfail(latency, result); 
     137        } 
     138    }, 
     139 
     140    split_schemedomainandport : function( url){ 
     141        /*** 
     142         
     143        **Split a url into its constituent parts.** 
     144 
     145        If port and or path parts are missing from the url, the associated fields  
     146        are set to null:: 
     147 
     148            sdpp => [scheme, domain, port|null, path|null] 
     149 
     150        Both, ``join_schemedomainandport`` and ``replace_schemedomainandport_path`` 
     151        cope with this. Note that:: 
     152 
     153            join(split('http://some.domain')) => 'http://some.domain/' 
     154            join(split('http://some.domain:8080')) => 'http://some.domain:8080/' 
     155            join(split('http://some.domain/')) => 'http://some.domain/' 
     156            join(split('http://some.domain:8080/')) => 'http://some.domain:8080/' 
     157         
     158        Ie., root path is forced if it is missing. 
     159 
     160        ``url: url to split. if null or undefined currentDocument().URL is used.`` 
     161         
     162        ***/ 
     163        if(typeof(url)=="undefined" || url==null){ 
     164            url=currentDocument().URL; 
     165        } 
     166        var scheme = url.split(':',1)[0]; 
     167        var domain = url.split('/')[2].split(':')[0]; 
     168        var port = url.split('/')[2].split(':')[1]; 
     169        var pathparts = url.split('/'); 
     170        var path = null; 
     171        if(pathparts.length > 3){ 
     172            path = pathparts.slice(3, pathparts.length).join('/'); 
     173        } 
     174        if(typeof(port)=="undefined" || port == null) 
     175            port=null; 
     176        return [scheme, domain, port, path]; 
     177    }, 
     178 
     179    join_schemedomainandport : function(sdpp){ 
     180        /*** 
     181         
     182        **Compliment of split_schemedomainandport** 
     183            
     184        ``sdpp: [scheme, domain, port|null, path| null]`` 
     185 
     186        ***/ 
     187 
     188        if(typeof(sdpp[2]) == "undefined" || sdpp[2] == null){ 
     189            return sdpp[0] + "://" +  
     190                    sdpp[1] + "/" +  
     191                    sdpp.slice(3,sdpp.length).join('/'); 
     192        } else { 
     193            return sdpp[0] + "://" +  
     194                    sdpp[1] + ":" + sdpp[2] + "/" + 
     195                    sdpp.slice(3,sdpp.length).join('/'); 
     196        } 
     197    }, 
     198 
     199    replace_schemedomainandport_path : function(sdpp, replacement){ 
     200        /*** 
     201         
     202        **Like, join but** ``replacement`` **clobbers path.** 
     203 
     204        This is a shortcut for:: 
     205 
     206            var url =  split_schemedomainandport(url); 
     207            url[3] = replacement; 
     208            url = join_schemedomainandport(url); 
     209             
     210        ***/ 
     211 
     212        if(typeof(replacement) == "undefined" || replacement == null) 
     213            replacement=""; 
     214        if(typeof(sdpp[2]) == "undefined" || sdpp[2] == null){ 
     215            return sdpp[0] + "://" +  
     216                    sdpp[1] + "/" + replacement; 
     217        } else { 
     218            return sdpp[0] + "://" +  
     219                    sdpp[1] + ":" + sdpp[2] + "/" + replacement; 
     220        } 
     221    }, 
     222 
     223    join_json : function (queryitems, responseitems){ 
     224        /*** 
     225      
     226        **Serialize queued queries.** 
     227 
     228        Into a format appropriate for a ``GET/POST`` request parameter. If you  
     229        need to escape or otherwise encode data elements, see  
     230        ``join_json_encodeitems`` 
     231 
     232        ``queryitems: [[queryid1,data1], ... [queryidN,dataN]]`` 
     233         
     234        ``responseitems: [[responseid1,data1], ... [responseidN,dataN]]`` 
     235         
     236        ``rtype: json formated string`` 
     237 
     238        ***/ 
     239 
     240        if (typeof(queryitems) == "undefined" || queryitems == null) 
     241            var queryitems = []; 
     242        if (typeof(responseitems) == "undefined" || responseitems == null) 
     243            var responseitems = []; 
     244        return "[" + MochiKit.Base.serializeJSON(queryitems) + "," + 
     245                     MochiKit.Base.serializeJSON(responseitems) + "]"; 
     246    }, 
     247 
     248    join_json_encodeitems : function (queryitems, responseitems,  
     249        queryitemencoder, responseitemencoder){ 
     250        /*** 
     251         
     252        **join, with custom item encoding.** 
     253 
     254        See ``join_json`` 
     255             
     256        queryitemencoder: called for each datafield in queryitems, 
     257        should return ``encode(queryitemdata)``. 
     258 
     259        responseitemencoder: called for each datafield in responseitems, 
     260        should return ``encode(queryitemdata)``.  
     261 
     262        If ``repsonseitemencoder`` is null or undefined it defaults to  
     263        ``queryitemencoder``. 
     264         
     265        If both ``responseitemencoder`` and ``queryitemencoder`` are either 
     266        null or undefined this function short circuits to ``join_json``. 
     267         
     268        ***/ 
     269         
     270        if(typeof(responseitemencoder)=="undefined"  
     271            || responseitemencoder == null) 
     272            responseitemencoder = queryitemencoder; 
     273        if(typeof(queryitemencoder)=="undefined" || queryitemencoder == null) 
     274            return streamservice.join_json(queryitems, responseitems); 
     275        if (typeof(queryitems) == "undefined" || queryitems == null) 
     276            var queryitems = []; 
     277        if (typeof(responseitems) == "undefined" || responseitems == null) 
     278            var responseitems = []; 
     279 
     280        var querydata=""; 
     281        var responsedata=""; 
     282 
     283        if(queryitems.length > 0){ 
     284            querydata += queryitemencoder(queryitems[0]); 
     285            if(queryitems.length > 1){ 
     286                for(var i=1; i < queryitems.length; i++){ 
     287                    querydata += "," + queryitemencoder(queryitems[i]); 
     288                } 
     289            } 
     290        } 
     291        if(responseitems.length > 0){ 
     292            responsedata += responseitemencoder(responseitems[0]); 
     293            if(responseitems.length > 1){ 
     294                for(var i=1; i < responseitems.length; i++){ 
     295                    responsedata += "," + responseitemencoder(responseitems[i]); 
     296                } 
     297            } 
     298        } 
     299        return "[[" + querydata + "]" + ",[" + responsedata + "]]"; 
     300    }, 
     301 
     302    split_json : function(data) { 
     303        /*** 
     304      
     305        Converse of join_json(queryitems, responseitems).  
     306 
     307        WARNING: uses eval, You need to decide if you trust ``data``. 
     308         
     309        ``data: a json string``, assumed to describe an array with the form 
     310 
     311            |    [iterablequeries, iterableresponses] 
     312            | 
     313            |    [[[queryid1,data1], ... [queryidN,dataN]], 
     314            |     [[responseid1,data1], ... [responseidN,dataN]]] 
     315 
     316         
     317 
     318        ``rtype: Iter`` 
     319 
     320        ***/ 
     321 
     322        if (typeof(data) == "undefined" || data == null){ 
     323            return [iter([]), iter([])]; 
     324        } 
     325        return eval(data); 
     326    } 
     327 
     328    /***split_json_decodeitems 
     329 
     330    don't think it makes sense to provide 'split_json_decodeitems' as it  
     331    would be highly sensitive to different ``join_json_encodeitems`` 
     332    encoding schemes. If you can't use end to end json, or, more  
     333    importantly, you decide not to trust eval, then you need to write  
     334    a custom split for your protocol implementation. 
     335 
    24336    ***/ 
    25     if(typeof(url)=="undefined" || url==null){ 
    26         url=currentDocument().URL; 
    27     } 
    28     var scheme = url.split(':',1)[0]; 
    29     var domain = url.split('/')[2].split(':')[0]; 
    30     var port = url.split('/')[2].split(':')[1]; 
    31     var pathparts = url.split('/'); 
    32     var path = null; 
    33     if(pathparts.length > 3){ 
    34         path = pathparts.slice(3, pathparts.length).join('/'); 
    35     } 
    36     if(typeof(port)=="undefined" || port == null) 
    37         port=null; 
    38     return [scheme, domain, port, path]; 
    39 
    40  
    41 join_schemedomainandport = function(sdpp){ 
    42     /*** 
    43      
    44     **Compliment of split_schemedomainandport** 
    45         
    46     ``sdpp: [scheme, domain, port|null, path| null]`` 
    47  
    48     ***/ 
    49  
    50     if(typeof(sdpp[2]) == "undefined" || sdpp[2] == null){ 
    51         return sdpp[0] + "://" +  
    52                 sdpp[1] + "/" +  
    53                 sdpp.slice(3,sdpp.length).join('/'); 
    54     } else { 
    55         return sdpp[0] + "://" +  
    56                 sdpp[1] + ":" + sdpp[2] + "/" + 
    57                 sdpp.slice(3,sdpp.length).join('/'); 
    58     } 
    59 
    60  
    61 replace_schemedomainandport_path = function(sdpp, replacement){ 
    62     /*** 
    63      
    64     **Like, join but** ``replacement`` **clobbers path.** 
    65  
    66     This is a shortcut for:: 
    67  
    68         var url =  split_schemedomainandport(url); 
    69         url[3] = replacement; 
    70         url = join_schemedomainandport(url); 
    71          
    72     ***/ 
    73  
    74     if(typeof(replacement) == "undefined" || replacement == null) 
    75         replacement=""; 
    76     if(typeof(sdpp[2]) == "undefined" || sdpp[2] == null){ 
    77         return sdpp[0] + "://" +  
    78                 sdpp[1] + "/" + replacement; 
    79     } else { 
    80         return sdpp[0] + "://" +  
    81                 sdpp[1] + ":" + sdpp[2] + "/" + replacement; 
    82     } 
    83 
    84  
    85 join_json = function (queryitems, responseitems){ 
    86     /*** 
    87   
    88     **Serialize queued queries.** 
    89  
    90     Into a format appropriate for a ``GET/POST`` request parameter. If you  
    91     need to escape or otherwise encode data elements, see  
    92     ``join_json_encodeitems`` 
    93  
    94     ``queryitems: [[queryid1,data1], ... [queryidN,dataN]]`` 
    95      
    96     ``responseitems: [[responseid1,data1], ... [responseidN,dataN]]`` 
    97      
    98     ``rtype: json formated string`` 
    99  
    100     ***/ 
    101  
    102     if (typeof(queryitems) == "undefined" || queryitems == null) 
    103         var queryitems = []; 
    104     if (typeof(responseitems) == "undefined" || responseitems == null) 
    105         var responseitems = []; 
    106     return "[" + MochiKit.Base.serializeJSON(queryitems) + "," + 
    107                  MochiKit.Base.serializeJSON(responseitems) + "]"; 
    108 
    109  
    110 join_json_encodeitems = function (queryitems, responseitems,  
    111     queryitemencoder, responseitemencoder){ 
    112     /*** 
    113      
    114     **join, with custom item encoding.** 
    115  
    116     See ``join_json`` 
    117          
    118     queryitemencoder: called for each datafield in queryitems, 
    119     should return ``encode(queryitemdata)``. 
    120  
    121     responseitemencoder: called for each datafield in responseitems, 
    122     should return ``encode(queryitemdata)``.  
    123  
    124     If ``repsonseitemencoder`` is null or undefined it defaults to  
    125     ``queryitemencoder``. 
    126      
    127     If both ``responseitemencoder`` and ``queryitemencoder`` are either 
    128     null or undefined this function short circuits to ``join_json``. 
    129      
    130     ***/ 
    131      
    132     if(typeof(responseitemencoder)=="undefined" || responseitemencoder == null) 
    133         responseitemencoder = queryitemencoder; 
    134     if(typeof(queryitemencoder)=="undefined" || queryitemencoder == null) 
    135         return join_json(queryitems, responseitems); 
    136     if (typeof(queryitems) == "undefined" || queryitems == null) 
    137         var queryitems = []; 
    138     if (typeof(responseitems) == "undefined" || responseitems == null) 
    139         var responseitems = []; 
    140  
    141     var querydata=""; 
    142     var responsedata=""; 
    143  
    144     if(queryitems.length > 0){ 
    145         querydata += queryitemencoder(queryitems[0]); 
    146         if(queryitems.length > 1){ 
    147             for(var i=1; i < queryitems.length; i++){ 
    148                 querydata += "," + queryitemencoder(queryitems[i]); 
    149             } 
    150         } 
    151     } 
    152     if(responseitems.length > 0){ 
    153         responsedata += responseitemencoder(responseitems[0]); 
    154         if(responseitems.length > 1){ 
    155             for(var i=1; i < responseitems.length; i++){ 
    156                 responsedata += "," + responseitemencoder(responseitems[i]); 
    157             } 
    158         } 
    159     } 
    160     return "[[" + querydata + "]" + ",[" + responsedata + "]]"; 
    161 
    162  
    163 split_json = function(data) { 
    164     /*** 
    165   
    166     Converse of join_json(queryitems, responseitems).  
    167  
    168     WARNING: uses eval, You need to decide if you trust ``data``. 
    169      
    170     ``data: a json string``, assumed to describe an array with the form 
    171  
    172         |    [iterablequeries, iterableresponses] 
    173         | 
    174         |    [[[queryid1,data1], ... [queryidN,dataN]], 
    175         |     [[responseid1,data1], ... [responseidN,dataN]]] 
    176  
    177      
    178  
    179     ``rtype: Iter`` 
    180  
    181     ***/ 
    182  
    183     if (typeof(data) == "undefined" || data == null){ 
    184         return [iter([]), iter([])]; 
    185     } 
    186     return eval(data); 
    187 }; 
    188  
    189 /***split_json_decodeitems 
    190  
    191 don't think it makes sense to provide 'split_json_decodeitems' as it  
    192 would be highly sensitive to different ``join_json_encodeitems`` 
    193 encoding schemes. If you can't use end to end json, or, more  
    194 importantly, you decide not to trust eval, then you need to write  
    195 a custom split for your protocol implementation. 
    196  
    197 ***/ 
    198  
    199  
    200 prepare_protocol = function (self, servicepath,  
    201      dispatchparametername, names, values, sdpp){ 
    202     if(self == null) 
    203         self=this; 
    204     if(typeof(self)=="undefined") 
    205         self={}; 
    206  
    207     if(typeof(dispatchparametername) == "undefined" ||  
    208         dispatchparametername==null) 
    209         dispatchparametername="dispatcher"; 
    210     self.dispatchparametername=dispatchparametername; 
    211  
    212     if(typeof(names) == "undefined" || names==null){ 
    213         self.queryparameters=parseQueryString( 
    214             queryString([self.dispatchparametername],["[[],[]]"]), true); 
    215         /*log("***: self.queryparameters = " +  
    216             serializeJSON(self.queryparameters));*/ 
    217     } else { 
    218         /* normalize parameter representation */ 
    219         self.queryparameters=parseQueryString(queryString( 
    220             names, values), true); 
    221         log("***: self.queryparameters = " + serializeJSON(self.queryparameters)); 
    222         /* if there is a collision the first element of user specified 
    223            value is clobbered */ 
    224         if(typeof(self.queryparameters[self.dispatchparametername]) != "undefined"){ 
    225             self.queryparameters[self.dispatchparametername][0]="[[],[]]" 
    226         } 
    227         else{ 
    228             self.queryparameters[self.dispatchparametername]=["[[],[]]"]; 
    229         } 
    230     } 
    231  
    232     if(typeof(sdpp)=="undefined" || sdpp == null){ 
    233         self.sdpp=split_schemedomainandport(); 
    234     } else { 
    235         self.sdpp = sdpp; 
    236     } 
    237     self.baseurl=replace_schemedomainandport_path(self.sdpp, servicepath); 
    238     self.sdpp[3]=servicepath; 
    239  
    240     /* If interval is null or undefined, the Dispatcher uses its own value. 
    241        Otherwise it uses this one. */ 
    242  
    243     return self; 
    244 
    245  
    246 XMLHttpRequestProtocol = function (servicepath,  
     337 
     338 
     339 
     340}); 
     341 
     342streamservice.XMLHttpRequestProtocol = function (servicepath,  
    247343     dispatchparametername, names, values, sdpp){ 
    248344    bindMethods(this); 
    249     prepare_protocol( 
     345    streamservice.prepare_protocol( 
    250346        this, servicepath,  
    251347        dispatchparametername, names, values, sdpp); 
    252348    this.req = getXMLHttpRequest(); 
    253349} 
    254  
    255 XMLHttpRequestProtocol.prototype.response_error = function(err) { 
    256    throw err; 
    257 
    258  
    259 XMLHttpRequestProtocol.prototype.poll = function(queryitems, replyitems){ 
    260  
    261     var data = join_json(queryitems, replyitems); 
    262      
    263     try{ 
    264         this.req.abort(); /* this should allways be benign, the 
    265             dispatcher doesn't start the next poll until the current 
    266             poll returns some result or error status */ 
    267      
    268         /* TODO: do I need to care more about sizeof character ? 
    269             currently assuming sizeof("foo"[0]) <= 2 
    270             so if data is unicode we will definitely post  
    271             if numbytes(data) >= 512 */ 
    272      
    273         var method="GET"; 
    274         if (data.length >= 128) 
    275             method="POST"; 
    276         this.queryparameters[this.dispatchparametername][0]=data 
    277         var url = this.baseurl + "?" + queryString(this.queryparameters); 
    278  
    279         log("###: POLLING = " +  
    280             this.queryparameters[this.dispatchparametername][0]); 
    281      
    282         /*log("###: queryitems = " + serializeJSON(queryitems)); 
    283           log("###: url = " + url);*/ 
    284         this.queryparameters[this.dispatchparametername][0]="[[][]]"; 
    285  
    286         /* reusing the same request object */ 
    287         this.req.open(method, url, true); 
    288  
    289         var getresult = function(req){ 
    290             log("***: req.responseText = " + req.responseText); 
    291             /* 
    292             log("***: evalJSONRequest(req) = " + evalJSONRequest(req)); 
    293             log("***: split_json(req.responseText) = " + split_json( 
    294                 req.responseText));*/ 
    295             /*return split_json(req.responseText);*/ 
    296             return evalJSONRequest(req); 
    297         } 
    298         return sendXMLHttpRequest(this.req).addCallbacks( 
    299                         getresult, this.response_error); 
    300     } catch (e){ 
    301         log("***: error polling " + repr(e)); 
    302         return fail(e).addBoth(this.response_error); 
     350streamservice.XMLHttpRequestProtocol.prototype = { 
     351    response_error : function(err) { 
     352       throw err; 
     353    }, 
     354 
     355    poll : function(queryitems, replyitems){ 
     356 
     357        var data = streamservice.join_json(queryitems, replyitems); 
     358         
     359        try{ 
     360            this.req.abort(); /* this should allways be benign, the 
     361                dispatcher doesn't start the next poll until the current 
     362                poll returns some result or error status */ 
     363         
     364            /* TODO: do I need to care more about sizeof character ? 
     365                currently assuming sizeof("foo"[0]) <= 2 
     366                so if data is unicode we will definitely post  
     367                if numbytes(data) >= 512 */ 
     368         
     369            var method="GET"; 
     370            if (data.length >= 128) 
     371                method="POST"; 
     372            this.queryparameters[this.dispatchparametername][0]=data 
     373            var url = this.baseurl + "?" + queryString(this.queryparameters); 
     374 
     375            log("###: POLLING = " +  
     376                this.queryparameters[this.dispatchparametername][0]); 
     377         
     378            /*log("###: queryitems = " + serializeJSON(queryitems)); 
     379              log("###: url = " + url);*/ 
     380            this.queryparameters[this.dispatchparametername][0]="[[][]]"; 
     381 
     382            /* reusing the same request object */ 
     383            this.req.open(method, url, true); 
     384 
     385            var getresult = function(req){ 
     386                log("***: req.responseText = " + req.responseText); 
     387                /* 
     388                log("***: evalJSONRequest(req) = " + evalJSONRequest(req)); 
     389                log("***: split_json(req.responseText) = " + split_json( 
     390                    req.responseText));*/ 
     391                /*return split_json(req.responseText);*/ 
     392                return evalJSONRequest(req); 
     393            } 
     394            return sendXMLHttpRequest(this.req).addCallbacks( 
     395                            getresult, this.response_error); 
     396        } catch (e){ 
     397            log("***: error polling " + repr(e)); 
     398            return fail(e).addBoth(this.response_error); 
     399        } 
    303400    } 
    304401}; 
    305402 
    306 Dispatcher = function () { 
     403streamservice.Dispatcher = function () { 
    307404    bindMethods(this); 
    308405    this.initialize.apply(this, arguments); 
    309406}; 
    310407 
    311 strip_tag_inplace = function(seperator, item){ 
    312     item[0] = item[0].slice(item[0].split(seperator,1)[0].length + 1); 
    313     return item; 
    314 
    315 strip_tag = function (seperator, tag){ 
    316     return tag.slice(tag.split(seperator,1)[0].length + 1); 
    317 
    318  
    319 Dispatcher.prototype = { 
     408streamservice.Dispatcher.prototype = { 
    320409    TAG_SEPERATOR : '.', 
    321410    initialize : function ( 
     
    344433    }, 
    345434    strip_tag_inplace : function (item){ 
    346         return strip_tag_inplace(this.TAG_SEPERATOR, item); 
     435        return streamservice.strip_tag_inplace(this.TAG_SEPERATOR, item); 
    347436    }, 
    348437    strip_tag : function (tag) { 
    349         return strip_tag(this.TAG_SEPERATOR, tag); 
     438        return streamservice.strip_tag(this.TAG_SEPERATOR, tag); 
    350439    }, 
    351440    respond : function (response_id, body) { 
     
    480569 
    481570 
    482 Service = function (dispatcher) { 
     571streamservice.Service = function (dispatcher) { 
    483572    /*** 
    484573     
     
    489578     
    490579    bindMethods(this); 
    491     this.id = Service.prototype.NEXT_SERVICE_ID; 
    492     Service.prototype.NEXT_SERVICE_ID += 1; 
     580    this.id = streamservice.Service.prototype.NEXT_SERVICE_ID; 
     581    streamservice.Service.prototype.NEXT_SERVICE_ID += 1; 
    493582    this.TAG_SEPERATOR = '.'; 
    494583    this.observers={}; 
     
    497586 
    498587 
    499 Service.prototype = { 
     588streamservice.Service.prototype = { 
    500589 
    501590    NEXT_SERVICE_ID: 0, 
     
    506595    }, 
    507596    strip_tag_inplace: function(item){ 
    508         return strip_tag_inplace(this.TAG_SEPERATOR,  
     597        return streamservice.strip_tag_inplace(this.TAG_SEPERATOR,  
    509598            this.dispatcher.strip_tag_inplace(item)); 
    510599    }, 
    511600    strip_tag : function(tag){ 
    512         return strip_tag(this.TAG_SEPERATOR, tag); 
     601        return streamservice.strip_tag(this.TAG_SEPERATOR, tag); 
    513602    }, 
    514603    start : function (repeatpolldelay) { 
     
    555644}; 
    556645 
    557 Observer = function(service, idinservice, client_dispatcher){ 
     646streamservice.Observer = function(service, idinservice, client_dispatcher){ 
    558647    bindMethods(this); 
    559648    this.service = service; 
     
    564653} 
    565654 
    566 Observer.prototype = { 
     655streamservice.Observer.prototype = { 
    567656    query : function (tag, body, d){ 
    568657        return this.service.query(this.idinservice, tag, body, d); 
     
    574663            this.client_dispatcher(body, tag).addBoth(responseback); 
    575664        } else { 
    576             responseback(body); /* just echo's, override to do something interesing! */ 
     665            /* just echo's, override to do something interesing! */  
     666            responseback(body);  
    577667        } 
    578668    } 
    579669}; 
    580670 
    581 poll_loopback_json = function( 
    582     clientdata,  
    583      latency, 
    584      emulatedbackendpollresult, 
    585      ignoreemulatedresponses){ 
    586     /*** 
    587      
    588     **Loopback implementation for** ``Protocol.poll``.  
    589  
    590     Provided for the benefit of test code. Echos query items, encoded in  
    591     clientdata, as the loopbackresult. 
    592  
    593     ``clientdata: the serialized and encoded queries & responses`` to 
    594     submit on the clients behalf. response items in ``clientdata``  
    595     are silently ignored. 
    596  
    597     ``latency: how long the poll should take``. the default is 0. *Note* 
    598     that latency <= 0 is special, it forces synchronous behaviour. 
    599  
    600     ``emulatedbackendpollresult: emulated backend responses``, Serialized  
    601     and encoded queries & responses fake response to this poll. By  
    602     default, response items are not included in the items looped back 
    603     to the client. 
    604      
    605     ``ignoreemulatedresponses: Don't throw away emulated responses``. if this  
    606     parameter is true then emulated backend responses are included in the  
    607     loopback result. 
    608  
    609     if latency was zero or unspecified the returned 
    610     deferred has allready been fired.:: 
    611  
    612         if latency unspecified or latency <= 0 
    613             returns succede(loopbackresult) 
    614         Otherwise: 
    615             wait(latency, loopbackresult) 
    616  
    617     ``rtype: Deferred`` 
    618  
    619     ***/ 
    620  
    621     if(typeof(latency)=="undefined" || latency==null){ 
    622         latency=0; 
    623     } 
    624     try{ 
    625         /*log("***:" + clientdata);*/ 
    626         var sent = split_json(clientdata); 
    627         var recvd = [null,null]; 
    628         if( typeof(emulatedbackendpollresult)!="undefined" && 
    629             emulatedbackendpollresult != null){ 
    630             /*log("***:" + emulatedbackendpollresult); 
    631               log("***:" + typeof(emulatedbackendpollresult));*/ 
    632             recvd = split_json(emulatedbackendpollresult); 
    633             if(ignoreemulatedresponses != false) 
    634                 recvd = [recvd[0],null]; 
    635         } 
    636         /* log("***:" + serializeJSON(recvd)); */ 
    637         var result = join_json(recvd[0], sent[0]); 
    638         if(recvd[1] != null){ 
    639             /* merge the emulated responses in *before* the looped back 
    640                responses */ 
    641             result = split_json(result); 
    642             result = join_json(result[0], extend(recvd[1], result[1])); 
    643         } 
    644         return latency <= 0 ? succeed(result) : wait(latency, result); 
    645     } catch (result){ 
    646         log("loopback raised:" + result); 
    647         waitfail = function(seconds,  value){ 
    648             var d = wait(seconds); 
    649             d.addBoth(partial(function (value){throw value;}, value)); 
    650             return d; 
    651         } 
    652         return latency <= 0 ? fail(result) : waitfail(latency, result); 
    653     } 
    654 }; 
     671 
  • streamservice/trunk/lib/streamservice/Loopback.js

    r97 r98  
    5454            /*log("protcol.poll: manualpoll == true");*/ 
    5555            return new Deferred().addCallbacks( 
    56                 split_json, this.response_error); 
     56                streamservice.split_json, this.response_error); 
    5757        }     
    5858        /*log("protocol.poll: " + queryitems); 
    5959          log("protocol.poll: " + replyitems);*/ 
    60         var data = join_json(queryitems, replyitems); 
     60        var data = streamservice.join_json(queryitems, replyitems); 
    6161        /*log("protocol.poll: " + data);*/ 
    6262        var emulatedbackendpollresult = null; 
     
    6565                this.emulatedbackendpollresult.shift(); 
    6666        } 
    67         return poll_loopback_json.apply( 
     67        return streamservice.poll_loopback_json.apply( 
    6868            this, [data,  
    6969                    this.latency,  
    7070                    emulatedbackendpollresult, 
    7171                    this.ignoreemulatedbackendresponses]).addCallbacks( 
    72                         split_json, this.response_error); 
     72                        streamservice.split_json, this.response_error); 
    7373    } 
    7474}; 
  • streamservice/trunk/tests/test_Dispatch.js

    r96 r98  
    33if (typeof(tests) == 'undefined') { tests = {}; } 
    44  
    5 tests.test_dispatch = function(t){ 
    6 try { 
    7  
    8     is(split_schemedomainandport()[1], document.domain, "schemedomainandport[1]==currentDocument().domain"); 
    9  
    10     is(join_schemedomainandport(split_schemedomainandport()), 
     5tests.test_Dispatch = function(t){ 
     6    var ss=streamservice; 
     7    t.is(ss.split_schemedomainandport()[1], document.domain, "schemedomainandport[1]==currentDocument().domain"); 
     8 
     9    t.is(ss.join_schemedomainandport(ss.split_schemedomainandport()), 
    1110       currentDocument().URL, 
    12        "join_schemedomainandport(split_schemddomainandport())  == currentDocument().URL"); 
    13     is(join_schemedomainandport(split_schemedomainandport( 
     11       "ss.join_schemedomainandport(split_schemddomainandport())  == currentDocument().URL"); 
     12    t.is(ss.join_schemedomainandport(ss.split_schemedomainandport( 
    1413        "http://localhost")), 
    1514        "http://localhost/", 
    1615        "join(split('http://localhost') == http://localhost/"); 
    17     is(join_schemedomainandport(split_schemedomainandport( 
     16    t.is(ss.join_schemedomainandport(ss.split_schemedomainandport( 
    1817        "http://localhost:80")), 
    1918        "http://localhost:80/", 
    2019        "join(split('http://localhost:80') == http://localhost:80/"); 
    21     is(join_schemedomainandport(split_schemedomainandport( 
     20    t.is(ss.join_schemedomainandport(ss.split_schemedomainandport( 
    2221        "http://localhost/foo")), 
    2322        "http://localhost/foo", 
    2423        "join(split('http://localhost/foo') == http://localhost/foo"); 
    2524 
    26     is(join_schemedomainandport(split_schemedomainandport( 
     25    t.is(ss.join_schemedomainandport(ss.split_schemedomainandport( 
    2726       "http://localhost/foo/bar")), 
    2827       "http://localhost/foo/bar", 
    2928       "join(split('http://localhost/foo/bar') == http://localhost/foo/bar"); 
    3029 
    31     is(join_schemedomainandport(split_schemedomainandport( 
     30    t.is(ss.join_schemedomainandport(ss.split_schemedomainandport( 
    3231        "http://localhost:80/foo/bar")), 
    3332        "http://localhost:80/foo/bar", 
     
    3534 
    3635    /* just sample some of the more interesting permutations */ 
    37     is(replace_schemedomainandport_path( 
    38         split_schemedomainandport( 
     36    t.is(ss.replace_schemedomainandport_path( 
     37        ss.split_schemedomainandport( 
    3938        "http://localhost")), 
    4039        "http://localhost/", 
    4140        "replace(split('http://localhost')) == http://localhost/"); 
    4241 
    43     is(replace_schemedomainandport_path( 
    44         split_schemedomainandport( 
     42    t.is(ss.replace_schemedomainandport_path( 
     43        ss.split_schemedomainandport( 
    4544        "http://localhost:80"),"foo/bar"), 
    4645        "http://localhost:80/foo/bar", 
    4746        "replace(split('http://localhost:80'), 'foo/bar') == http://localhost:80/foo/bar"); 
    4847 
    49     is(replace_schemedomainandport_path( 
    50         split_schemedomainandport( 
     48    t.is(ss.replace_schemedomainandport_path( 
     49        ss.split_schemedomainandport( 
    5150        "http://localhost/bar/foo"),"foo/bar"), 
    5251        "http://localhost/foo/bar", 
    5352        "replace(split('http://localhost/bar/foo'),'foo/bar') == http://localhost/foo/bar"); 
    5453 
    55     ok(true, "<*** end of xxx _schemedomainandport tests ***>"); 
     54    t.ok(true, "<*** end of xxx _schemedomainandport tests ***>"); 
    5655 
    5756    /* prepare_protcol */ 
    5857     
    59     var protocol = prepare_protocol({}, "foo/bar"); 
    60     is(protocol.dispatchparametername, "dispatcher",  
     58    var protocol = ss.prepare_protocol({}, "foo/bar"); 
     59    t.is(protocol.dispatchparametername, "dispatcher",  
    6160        "default dispatchparametername"); 
    62     is(protocol.queryparameters[protocol.dispatchparametername][0],  
     61    t.is(protocol.queryparameters[protocol.dispatchparametername][0],  
    6362       '[[],[]]', 
    6463        "queryparameters[dispatchparametername][0] == '[[],[]]'"); 
    65     var documentsdpp=split_schemedomainandport(); 
     64    var documentsdpp=ss.split_schemedomainandport(); 
    6665    /* 
    6766    log("***: documentsdpp = " + documentsdpp); 
    6867    log("***: protocol.sdpp = " + protocol.sdpp); 
    6968    log("***: protocol.baseurl = " + protocol.baseurl); 
    70     log("***: replace(documentsdpp, 'foo/bar') = " + replace_schemedomainandport_path(documentsdpp, "foo/bar")); 
     69    log("***: replace(documentsdpp, 'foo/bar') = " + ss.replace_schemedomainandport_path(documentsdpp, "foo/bar")); 
    7170    */ 
    72     ok(protocol.sdpp[0] == documentsdpp[0] && 
     71    t.ok(protocol.sdpp[0] == documentsdpp[0] && 
    7372       protocol.sdpp[1] == documentsdpp[1] && 
    7473       protocol.sdpp[2] == documentsdpp[2] && 
    7574       protocol.sdpp[3] != documentsdpp[3],  
    7675       "protocol.sdpp derived from document scheme,domain,port,path"); 
    77     is(protocol.baseurl, replace_schemedomainandport_path( 
     76    t.is(protocol.baseurl, ss.replace_schemedomainandport_path( 
    7877        documentsdpp, "foo/bar"), 
    7978       "protocol.baseurl == replace(split(currentDocument().URL), 'foo/bar'"); 
    8079 
    81     var protocol = prepare_protocol({}, "foo/bar", 
     80    var protocol = ss.prepare_protocol({}, "foo/bar", 
    8281      "dispatch", ["dispatch"],["badclient"]); 
    8382 
    84     is(protocol.queryparameters[protocol.dispatchparametername][0],  
     83    t.is(protocol.queryparameters[protocol.dispatchparametername][0],  
    8584       '[[],[]]', 
    8685        "clobbered first value of additional queryparameter that \ 
    8786conflits with dispatchparametername"); 
    8887 
    89     ok(true, "<*** end of prepare_protocol tests ***>"); 
     88    t.ok(true, "<*** end of ss.prepare_protocol tests ***>"); 
    9089 
    9190    /* various join corner cases */ 
    9291     
    93     is(join_json([]), "[[],[]]", "join_json, 0 items"); 
    94     is(join_json([[1,'a']]), "[[[1,\"a\"]],[]]", "join_json, 1 query item"); 
    95     is(join_json([[1,'a'],[2,'b']]),  
    96         "[[[1,\"a\"],[2,\"b\"]],[]]",  
    97         "join_json, 2 query items"); 
    98     is(join_json([[1,'a'],[2,'b'],[3,'c']]),  
    99         "[[[1,\"a\"],[2,\"b\"],[3,\"c\"]],[]]",  
    100         "join_json, 3 query items"); 
    101  
    102     is(join_json(null, [[1,'a']]),  
    103         "[[],[[1,\"a\"]]]",  
    104         "join_json, 1 response item"); 
    105     is(join_json(null, [[1,'a'],[2,'b']]),  
    106         "[[],[[1,\"a\"],[2,\"b\"]]]",  
    107         "join_json, 2 response items"); 
    108     is(join_json(null, [[1,'a'],[2,'b'],[3,'c']]),  
    109         "[[],[[1,\"a\"],[2,\"b\"],[3,\"c\"]]]",  
    110         "join_json, 3 response items"); 
    111     is(join_json( 
     92    t.is(ss.join_json([]), "[[],[]]", "join_json, 0 items"); 
     93    t.is(ss.join_json([[1,'a']]), '[[[1, \"a\"]],[]]', "join_json, 1 query item"); 
     94    t.is(ss.join_json([[1,'a'],[2,'b']]),  
     95        "[[[1, \"a\"], [2, \"b\"]],[]]",  
     96        "ss.join_json, 2 qu