Source: common/Application.js

/**
 * Created by seeker910 on 13-12-31.
 */
Rsd.define('Rsd.common.Application', {
    extend:'Rsd.common.Object',
    requires:['Rsd.data.Plugin','Rsd.data.ModelSchema',"Rsd.common.EventList",'Rsd.data.Service','Rsd.data.Logger','Rsd.common.Lang'],
    xtype:'application',
    /**
     * 用户身份授权
     */
    authorization:null,
    //应用ID ==>clientId
    appId:null,
    //应用token ==>clientSecret ,appId+appToken 换取 accessToken ,用于验证app授权
    appToken:null,
    //标题
    appTitle: '',
    //名称
    appName: '',
    /*
    * web,wap,wxapp,
    * */
    appType:null,
    //源文件
    appFolder:'src', 
    //版本号
    appVersion:'0.0.0.0',
    //版本发布日期
    appDate:new Date().getTime(),
    //js 脚本代理服务器地址 ,设置该值后,所有js脚本请求 会被指向该地址,且请求格式为jsAgentHost/base64(path),且需要在代理服务上 先解析path内容 
    jsAgentHost:'',
    lang:'zh-cn',
    svg:null,
    /*api service*/
    //services:{},
    schemas:{},
    /**
     * 环境变量
     */
    globalVariables:{},
    //app启动时间
    startTime:0,
    // Hosts 服务已加载完毕
    isReady:false,
    isDemo: window.location.protocol  == 'file:',
    getSchemaListHandler:'',
    getSchemaHandler:'',
    /**
     * @description 延时启动时长(毫秒),一般用于等待框架加载
     */
    delay:100,
    //应用内 插件  
    plugins:[], 
    /**
     * {
     * //标题
     * text:'电商服务',
     * //名称
     * name:'biz',
     * //地址
     * url:'http://hermes.redmicro.cn/',
     * //服务端 状态探测地址
     * index:'dev/index',
     * routeList:'/dev/getroutetable',
     * controllers:[{name:'',path:''}]
     * isLoaded:false//已加载
     * //是否使用ssl
     * useSSL:false
     * }
     */ 
    //apiHost:[]

    /**
     * 模板文件库 ,程序启动时,将模板加载到本地并编译后 存在 indexDB中
     * {
     *   name:'',path
     * }
     */
    templates:[],
    /*
    * */
    constructor: function Application(config) {
        //debugger;
        this.apply(config);
    },
    /**
     * */
    run :function run() {
        var me = this;
        //console.trace('run');
        Rsd.create('Rsd.common.Lang',{}).load(me.lang);

        if(me.svg)
        {
            Rsd.create('Rsd.data.SvgLoader',{}).load('./resources/svg/' + me.svg+'.js?t=' + Rsd.timestamp);
        }

        if (Rsd.validateBrowser() == false) {
            var error = '浏览器版本过低,请升级或选择其他浏览器。';
            Rsd.alert(error);
            document.title = error;
            return;
        }
        if(!Rsd.isEmpty(this.appTitle))
        {
            window.document.title =  this.appTitle;
        }

        //加载依赖项
        setTimeout(function () {

            var _obj;

            for (var c in me.requires) {

                if(!me.requires.hasOwnProperty(c))
                {
                    continue;
                }
                _obj = me.requires[c];
                var isJs = /(\.js)$/.test(_obj);
                if (isJs) {

                    Rsd.loadScriptFile(_obj);
                }
                else {
                    //console.log('application run',_obj);
                    Rsd.loadClass(_obj);
                }

            }
        },0);

        setTimeout(function () {
            //探测API是否可用
            me.testServerHost(function (data) {
                //console.trace('testServerHost');
                if(!data.success)
                {
                    Rsd.create('Rsd.zen.page.ErrorPage',{text:data.msg}).show(); 
                }
                else
                {
                    //延时启动程序
                    setTimeout(function(){
                        me.launch.call(me);
                    },me.delay||0);
                    
                }

            })

        },0);

        Rsd.debug('App is runing.');
    },
    /**
     * 应用重启
     */
    restart:function restart()
    {
        this.run();
    },
    /**
     * @description 加载应用插件
     * * */
    loadPlugin:function loadPlugin(plugin,callback)
    {
        var app = this;
        if(Rsd.isString(plugin))
        {
            var _plugin = {path:plugin};
            var _fn = function () {
                var _p = this;
                
                var _s = new Rsd.data.Store({
                    proxy: {
                        url: plugin + '/config.js',
                        method:'get'
                    }});

                _s.load({},function (config) {
 
                    if(config)
                    { 
                        var pConfig = new Rsd.data.Plugin(config);
                        pConfig.path = _p.path;
                       
                        app.loadPlugin(pConfig);
                    }

                    if(callback)
                    {
                        callback(pConfig);
                    }
                });
            }
            _fn.call(_plugin);

            return;
        }

        this.plugins = this.plugins || [];
        this.__plugin_mapping = this.__plugin_mapping || {};
        this.plugins.push(plugin);
        this.__plugin_mapping[plugin.name.toLowerCase()] = plugin;
    },
    /**
     * 应用内插件
     */
    getPlugin:function getPlugin(name)
    { 
       return  this.__plugin_mapping && this.__plugin_mapping[name.toLowerCase()] ;
    },
    /**
    * 探测服务端 是否可用
    * */
    testServerHost:function testServerHost(callback) {

        if( Rsd.app.apiHosts == null || Rsd.app.apiHosts.length == 0)
        {
            Rsd.callFunction(callback,me,[{success:true}]);  
            return ;            
        }

        var me = this;
        var _count = 0;

        var _fn = function()
        { 
            var host = this;
           
            if(Rsd.isEmpty(host.url))
            {
                _count++; 
                console.error('Host属性Url不存在',host);
                if(me.apiHosts.length == _count)
                { 
                    Rsd.callFunction(callback,me,[{success:true}]);  
                }   
                
                return;
            }

            var _testUrl = host.url + host.index||'';
            host.testTimers = host.testTimers||1; 
            var _method = 'GET';
            console.log('第'+ host.testTimers + '次:探测'+_method+'=>(url:'+ _testUrl +')远程服务。');
           
            Rsd.httpRequest({ 
                    url:_testUrl,
                    method:_method,
                    fail:function(data){
                        _count++; 
                        console.log('testServer',data);
                        Rsd.warn('系统繁忙,稍后再试');
                    },
                    error: function (xhr,text,event) {
    
                        _count++; 
                        console.log(text||"error",host,event);
                        if(host.testTimers < 5)
                        { 
                            setTimeout(function () {
                                _fn.call(host);
                                host.testTimers++;
                            },200*host.testTimers);
 
                        }
                       
                        if(me.apiHosts.length == _count)
                        { 
                            Rsd.callFunction(callback,me,[{success:true}]); 
                            console.error(text||"error",event);
                        }
                    }
                },
                {},
                function(data){
                    
                    _count++; 
                    host.success = true;
                    if(me.apiHosts.length == _count)
                    { 
                         Rsd.callFunction(callback,me,[{success:true}]);
                    }
            });
        }

        for(var i in Rsd.app.apiHosts)
        {
            var host = Rsd.app.apiHosts[i]; 
           
            (function(){
                var _host = this;
                setTimeout(function() {
                    _fn.call(_host); 
                }, 0);
            
            }).call(host);
            
        }    
        
      
    },
    /**
     * 设置环境变量,不区分大小写
     * @param {*} key 
     * @param {*} value 
     * @returns 
     */
    setGlobalVariable:function setGlobalVariable(key,value)
    {
        if(Rsd.isEmpty(key))
        {
            return;    
        }
        this.globalVariables[key.toLowerCase()] = value;
    },
    /**
     * 获取环境变量,不区分大小写
     * @param {*} key 
     */
    getGlobalVariable:function getGlobalVariable(key)
    {
        if(Rsd.isEmpty(key))
        {
            return "";    
        }
        return this.globalVariables[key.toLowerCase()] || '';
    },
    
    /**
    *
    *
    * */
    addService:function addService(key,config)
    {
        var _name = key.toLowerCase();
        var _group = _name.substr(0,_name.lastIndexOf('.'));
        var _method = _name.substr(_name.lastIndexOf('.')+1);

        this.services[_group].api[_method] = new Rsd.data.Service(config);
    },

    /**
     * @description 获取当前服务环境中的服务
     * */
    getService: function getService(name){

        if(Rsd.isEmpty(name))
        {
            throw new Error('param [name] is null when call  Application.getService method.');
        }
        var _name = name.toLowerCase();
        var _group = _name.substr(0,_name.lastIndexOf('.'));
        var _method = _name.substr(_name.lastIndexOf('.')+1);


        var service = Rsd.services[_group];

        if(Rsd.isEmpty(service) )
        {
            var _error =  '服务['+ name +']不存在,请先注册';
            Rsd.warn(_error);
            console.error(_error);
            return;
        }

        //console.log(service);

        if(!service.api.hasOwnProperty(_method))
        {
            Rsd.error('服务['+ name +']不存在,请确认');
            return null;
        }

        if(Rsd.isEmpty(service.api) && service.isLoading)
        {
            Rsd.error('服务['+ name +']正在加载,请稍后');
            return;
        }

        var item = service.api[_method];

        if(item instanceof  Rsd.data.Service)
        {
            return item;
        }

        return new Rsd.data.Service({
            key:_name,
            group:_group,
            parent : this,
            errorHandler :'',
            failureHandler : '',
            successHandler : '',
            progressHandler: '',
            ajaxType:'ajax',
            local:{method:'get',url:''},
            server:{
                url:item.Url,
                method:item.Method || 'POST',
                //contentType:'application/json',
                //dataType: 'json',
                async:true
            }

        });
    },

    /**
     * @description 服务未加载完成时,有两次各延时1秒的处理
     * @param {*} name 
     * @param {*} data 
     * @param {*} callback  请求成功(status==200)回调方法,且优先执行,执行返回true时,后续方法(success,failure)继续执行,返回false时,后续方法终止
     * @param {*} msg 
     * @param {*} timeout 
     */
    requestService:function requestService(name, data, callback,msg,timeout) {

        var _name = name;
        var _data = data;
        var _callback = callback;
        var _msg = msg||"正在加载"
        var _timeout = timeout;
        if(Rsd.isNumber(msg))
        {
            _timeout = msg;
        }
        if(Rsd.isString(timeout))
        {
            _msg = timeout;
        }
        Rsd.requestService(_name, _data, _callback,_msg,timeout);
    },

    /**
     * @description 展示表单
     * @param modeltype
     * @param formfields
     * @param record
     * @param title
     * @param buttons
     * @param readOnly
     * @param parent
     *  
     * */
    showModelView:function(config) {

        var _config = config||{};
        

        if(!_config.modelType.startWith('Rsd.'))
        {
            _config.modelType = Rsd.app.assembelyName + '.' + _config.modelType ;
        }
        _config.parent = _config.parent ||this;
        _config.readOnly = (_config.readOnly==undefined?false:_config.readOnly);
       
        this.getSchema(_config.modelType,function (schema) {
           
            config.schema = schema;
            var form = Rsd.create('Rsd.zen.dialog.FormDialog', config);

            form.showDialog().load();

          });

    },

    /**
    * 表单 模型
     * */
    getSchemaList:function getSchemaList(callback) {

        if(!this.getSchemaListHandler)
        {
            Rsd.error('Application 类中未找到getSchemaListHandler的定义。');
            return;
        }
        return this.funApplyByIOC(this.getSchemaListHandler,[callback]);
    },
    /**
     * 表单 jsonSchema
     * @param {*} modelType 
     * @param {*} callback 
     */
    getJsonSchema:function getJsonSchema(modelType,callback) {
        console.error('需要将model schema 转化为jsonSchema');
    },
    /** 
    * 表单 model 
    * */
    getSchema:function getSchema(modelType,callback) {

        //debugger;
        if(!this.getSchemaHandler)
        {
            Rsd.error('Application 类中未找到getSchemaHandler的定义。');
            return;
        }
        return this.funApplyByIOC(this.getSchemaHandler,[modelType,callback])

    }
    
},function(type){
    //
    this.defineProperty(type,'appHosts',function(){return this.__appHost||[];},function(appHost){
        if(Rsd.isArray(appHost))
        {
            this.__appHost = appHost; 
            return ;
        }
        if(Rsd.isString(appHost))
        {
            this.__appHost = [{url:appHost,useSSL:false,index:'',name:'biz',text:"业务"}]; 
            return ;
        }
        this.__appHost = [appHost];

    },false);



});