aboutsummaryrefslogblamecommitdiffstats
path: root/src/js/imc.js
blob: ae81684b7a5a8fd06a22d984e22671017e0e2875 (plain) (tree)
1
2
3
4
5
6
7
8
9
10

            



                                        
                         


                                     
                        
 
                               
                                 
                         






                                                    

                                                          



             
                                                    


                                  
                        
                                   
                              
                               
                                                             
 
                                              
                  
                      
                     

































                                                                                                          
                         


                            
                     
 

                                                          


                                       
              

                                  








                                                      
 




                                                                        
 




                                                         
 

                                                                                 
 


                                                                                                   

                                                                 
                                      
                      
                                                                
                    
                  


                                                          
                     
 
                                                                                                      
                   


             
                                                

                                        


                                               
                                        


             

                                                                                                         
                                    
                                          
                                            
                                    

                                      
                                  

                             
 
                                               

                                               
                                             

                                                
                                        


                                          
 
                                                                                                
                                                              
                                                                       
                   
                     

          

                                                                          
                                   
                                          






                                               
                                                 

                                                   
                     
 



                                                                                           



                                          

                                                                       

                   


                                       

                                           
                                           
          


                                             
          



                                           

                                       
                                           
          

                                                    
                                          

                                                      




                               


                                  
                                         


             









                                                                

                                    
                                                                                                                     


                                                           




                                         





                                                        




                                                   
          












                                                     
 
                                      
 
                                  

      





                                                       











                                                            
 
                                         

                                 
  
'use strict'

var __extend__ = function(child,parent){
    child.prototype.__super__ = parent;
};

var imc = new function(){
    var that = this;

    that.Connection = function(link){
        var that = this;

        that.link_linkmap = {};
        that.close_callback = [];
        that.link = link;

        that.send_msg = function(data){};
        that.start_recv = function(recv_callback){};

        that.close = function(){
            var i;

            for(i = 0;i < that.close_callback.length;i++){
                that.close_callback[i](that);
            }
        };
    };

    that.Proxy = function(self_link,auth,conn_link){
        var MSGTYPE_CALL = 'call';
        var MSGTYPE_RET = 'ret';

        var that = this;
        var caller_retid_count = 0;
        var conn_linkmap = {};
        var conn_retidmap = {};
        var callpath_root = {'child':{},'name':{},'filt':[]};

        var walk_path = function(path,create){
            var i;
            var parts;
            var part;
            var cnode;
            var nnode;
            
            parts = path.split('/');
            parts.pop();
            cnode = callpath_root;
            for(i = 0;i < parts.length;i++){
                part = parts[i];
                if(part in cnode.child){
                    cnode = cnode.child[part];
                }else{
                    break;
                }
            }

            if(create == true){
                for(;i < parts.length;i++){
                    part = parts[i];
                    nnode = {'child':{},'name':{},'filt':[]};
                    cnode.child[part] = nnode;
                    cnode = nnode;
                }
            }else if(i < parts.length){
                return undefined;
            }

            return cnode;
        };

        var route_call = function(caller_link,caller_retid,idendesc,dst,func_name,timeout,callback,param){
            var i;
            var j;
            var part;
            var dst_link;
            var dst_path;
            var caller_link;
            var cnode;
            var dpart;
            var func;

            var _add_wait_caller = function(conn_link){
                conn_retidmap[conn_link][caller_retid] = {
                    'timeout':timeout,
                    'callback':callback
                }   
            };

            part = dst.split('/');
            dst_link = part.slice(0,3).join('/') + '/'
            dst_path = part.slice(3,-1);

            if(dst_link == self_link){
                cnode = callpath_root;
                dpart = dst_path.slice(0);
                for(i = 0;i < cnode.filt.length;i++){
                    cnode.filt[i](dpart,func_name);
                }

                for(i = 0;i < dst_path.length;i++){
                    if((cnode = cnode.child[dst_path[i]]) == undefined){
                        cnode = null;
                        break;
                    }

                    dpart.shift();
                    for(j = 0;j < cnode.filt.length;j++){
                        cnode.filt[j](dpart,func_name);
                    }
                }

                if(cnode != null && (func = cnode.name[func_name]) != undefined){
                    _add_wait_caller(self_link);

                    func.apply(undefined,[function(data){
                        if(self_link in conn_retidmap && caller_retid in conn_retidmap[self_link]){
                            delete conn_retidmap[self_link][caller_retid];
                            callback({'stat':true,'data':data}); 
                        }   
                    }].concat(param));
                }else{
                    callback({'stat':false,'data':'Enoexist'}); 
                }   
            }else{
                that.request_conn(dst_link,function(conn){
                    if(caller_link == self_link){
                        _add_wait_caller(conn.link);
                    }

                    send_msg_call(conn,caller_link,caller_retid,idendesc,dst,func_name,timeout,param);
                });
            }
        };

        var recv_dispatch = function(conn,data){
            var msgo = JSON.parse(data);

            if(msgo.type == MSGTYPE_CALL){
                recv_msg_call(conn,msgo);
            }else if(msgo.type == MSGTYPE_RET){
                recv_msg_ret(conn,msgo);
            }
        };

        var send_msg_call = function(conn,caller_link,caller_retid,idendesc,dst,func_name,timeout,param){
            var msg = {
                'type':MSGTYPE_CALL,
                'caller_link':caller_link,
                'caller_retid':caller_retid,
                'idendesc':idendesc,
                'dst':dst,
                'func_name':func_name,
                'timeout':timeout,
                'param':param
            };

            conn.send_msg(JSON.stringify(msg));
        };
        var recv_msg_call = function(conn,msg){
            var caller_link = msg.caller_link
            var caller_retid = msg.caller_retid;
            var timeout = msg.timeout;
            var idendesc = msg.idendesc;
            var dst = msg.dst;
            var func_name = msg.func_name;
            var param = msg.param;

            route_call(caller_link,caller_retid,idendesc,dst,func_name,timeout,function(result){
                that.request_conn(caller_retid,function(conn){
                    send_msg_ret(conn,caller_link,caller_retid,result);
                });
            },param);
        };

        var send_msg_ret = function(conn,caller_link,caller_retid,result){
            var msg = {
                'type':MSGTYPE_RET,
                'caller_link':caller_link,
                'caller_retid':caller_retid,
                'result':result
            };

            conn.send_msg(JSON.stringify(msg));
        };
        var recv_msg_ret = function(conn,msg){
            var caller_link = msg['caller_link'];
            var caller_retid = msg['caller_retid'];
            var result = msg['result'];
            var wait;

            if(caller_link == self_link){
                if(conn.link in conn_retidmap && caller_retid in conn_retidmap[conn.link]){
                    wait = conn_retidmap[conn.link][caller_retid];
                    delete conn_retidmap[conn.link][caller_retid];

                    wait.callback(result);
                }   
            }else{
                request_conn(caller_link,function(conn){
                    send_msg_ret(conn,caller_link,caller_retid,result);
                });
            }
        };

        that.add_conn = function(conn){
            conn_linkmap[conn.link] = conn;
            conn_retidmap[conn.link] = {};
            conn.start_recv(recv_dispatch);
        };
        that.link_conn = function(link,conn){
            conn.link_linkmap[link] = true;
            conn_linkmap[link] = conn;    
        };
        that.unlink_conn = function(link){
            conn = conn_linkmap[link];
            delete conn_linkmap[link];
            delete conn.link_linkmap[link];
        };
        that.del_conn = function(conn){
            delete conn_linkmap[conn.link];
        };
        that.request_conn = function(link,callback){
            var conn = conn_linkmap[link];
            var _conn_cb = function(conn){
                if(conn != null && conn.link != link){
                    that.link_conn(link,conn);
                }

                callback(conn);
            };

            if(conn != undefined){
                _conn_cb(conn); 
            }else{
                conn_link(link,_conn_cb);
            }
        };

        that.call = function(dst,func_name,timeout,callback){
            var i;
            var params = new Array()
            var caller_retid;

            for(i = 4;i < arguments.length;i++){
                params.push(arguments[i]); 
            }

            caller_retid = self_link + '/' + caller_retid_count;
            caller_retid_count += 1;

            route_call(self_link,caller_retid,imc.Auth.get_current_idendesc(),dst,func_name,timeout,callback,params);
        };

        that.register_call = function(path,func_name,func){
            var cnode;

            cnode = walk_path(path,true);
            cnode.name[func_name] = func;
        };
        that.unregister_call = function(path,func_name){
            var cnode;

            cnode = walk_path(path,true);
            delete cnode.name[func_name];
        }
        that.register_filter = function(path,func){
            var cnode;

            cnode = walk_path(path,true);
            cnode.filt.push(func);
        };
        that.unregister_filter = function(path,func){
            var i;
            var cnode;
            var new_filt = new Array();

            cnode = walk_path(path,true);
            for(i = 0;i < cnode.filt.length;i++){
                if(cnode.filt[i] != func){
                    new_filt.push(cnode.filt[i]); 
                }
            }
            cnode.filt.remove(func);
        };

        conn_retidmap[self_link] = {};

        imc.Proxy.instance = that;
    };

    this.Auth = function(){
        var that = this;

        that.get_iden = function(idendesc){
            return JSON.parse(JSON.parse(idendesc)[0]);
        };
        
        imc.Auth.change_current_iden = function(idendesc){
            var iden = imc.Auth.instance.get_iden(idendesc);

            imc.Auth.current_idendata = [iden,idendesc];
        };
        imc.Auth.get_current_iden = function(){
            return imc.Auth.current_idendata[0];
        };
        imc.Auth.get_current_idendesc = function(){
            return imc.Auth.current_idendata[1];
        };

        imc.Auth.current_idendata = null;
        imc.Auth.instance = that;
    };
};