Beispiel #1
0
        protected override void WriteProxy(IndentedTextWriter writer)
        {
            if (writer == null)
            {
                throw new ArgumentNullException("writer");
            }

            WriteProlog(writer);

            ServiceClass serviceClass = Service.GetClass();

            WriteClass(writer, serviceClass);

            foreach (Method method in serviceClass.GetMethods())
            {
                WriteMethod(writer, method);
            }

            WriteClassTail(writer);

            WriteEpilog(writer);
        }
        private void Version2(ServiceClass service, Uri url, IndentedTextWriter writer)
        {
            Debug.Assert(service != null);
            Debug.Assert(url != null);
            Debug.Assert(!url.IsFile);
            Debug.Assert(writer != null);

            if (JsonRpcTrace.TraceWarning)
            {
                writer.WriteLine(@"// *** O B S O L E T E *** 
//
// You are using version 2 of the JavaScript proxy that MAY 
// be obsoleted and removed in the next release. The functionality has 
// been integrated into the original proxy version via the channel 
// property on the JavaScript proxy.
");
            }

            writer.WriteLine("// Proxy version 2.0");
            writer.WriteLine();

            writer.Write("var ");
            writer.Write(service.Name);
            writer.Write(@" = function()
{
    var nextId = 0;

    var proxy = {

        url : """);
            writer.Write(url);
            writer.Write(@""",
        rpc : {");
            writer.WriteLine();
            writer.Indent += 3;

            Method[] methods = service.GetMethods();

            string[] methodNames = new string[methods.Length];
            for (int i = 0; i < methods.Length; i++)
            {
                methodNames[i] = methods[i].Name;
            }

            Array.Sort(methodNames, methods);

            for (int i = 0; i < methods.Length; i++)
            {
                Method method = methods[i];

                writer.WriteLine();

                if (method.Description.Length > 0)
                {
                    // TODO: What to do if /* and */ appear in the summary?

                    writer.Write("/* ");
                    writer.Write(method.Description);
                    writer.WriteLine(" */");
                    writer.WriteLine();
                }

                writer.Write('\"');
                writer.Write(method.Name);
                writer.Write("\" : function(");

                Parameter[] parameters = method.GetParameters();

                foreach (Parameter parameter in parameters)
                {
                    writer.Write(parameter.Name);
                    writer.Write(", ");
                }

                writer.WriteLine("callback) {");
                writer.Indent++;

                writer.Write("return new Call(\"");
                writer.Write(method.Name);
                writer.Write("\", [");

                foreach (Parameter parameter in parameters)
                {
                    if (parameter.Position > 0)
                    {
                        writer.Write(',');
                    }
                    writer.Write(' ');
                    writer.Write(parameter.Name);
                }

                writer.WriteLine(" ], callback);");

                writer.Indent--;
                writer.Write("}");
                if (i < (methods.Length - 1))
                {
                    writer.Write(',');
                }
                writer.WriteLine();
            }

            writer.Indent--;
            writer.WriteLine(@"}
    }

    function Call(method, params, callback)
    {
        this.url = proxy.url;
        this.callback = callback;
        this.request = 
        { 
            id     : ++nextId, 
            method : method, 
            params : params
        };
    }
    
    Call.prototype.call = function(channel) { return channel(this); }
    
    return proxy;
}();");

            writer.Indent--;
        }
        private static void Version1(ServiceClass service, Uri url, IndentedTextWriter writer)
        {
            Debug.Assert(service != null);
            Debug.Assert(url != null);
            Debug.Assert(!url.IsFile);
            Debug.Assert(writer != null);

            writer.Write("function ");
            writer.Write(service.Name);
            writer.WriteLine("(url)");
            writer.WriteLine("{");
            writer.Indent++;
            writer.WriteLine("var self = this;");

            Method[] methods = service.GetMethods();

            string[] methodNames = new string[methods.Length];
            bool[]   idempotents = new bool[methods.Length];

            for (int i = 0; i < methods.Length; i++)
            {
                methodNames[i] = methods[i].Name;
                idempotents[i] = methods[i].Idempotent;
            }

            writer.Write("var m = ");
            JsonConvert.Export(methodNames, writer);
            writer.WriteLine(';');
            writer.Write("var idems = ");
            JsonConvert.Export(idempotents, writer);
            writer.WriteLine(';');
            writer.WriteLine();

            for (int i = 0; i < methods.Length; i++)
            {
                Method method = methods[i];
                string index  = i.ToString(CultureInfo.InvariantCulture);

                if (method.Description.Length > 0)
                {
                    // TODO: What to do if summary breaks over several lines?

                    writer.Write("// ");
                    writer.WriteLine(method.Description);
                    writer.WriteLine();
                }

                writer.Write("this[m[");
                writer.Write(index);
                writer.Write("]] = function /* ");
                writer.Write(method.Name);
                writer.Write(" */ (");

                Parameter[] parameters = method.GetParameters();

                foreach (Parameter parameter in parameters)
                {
                    writer.Write(parameter.Name);
                    writer.Write(", ");
                }

                writer.WriteLine("callback)");
                writer.WriteLine("{");
                writer.Indent++;

                writer.Write("if (self.kwargs) return rpc(new Call(");
                writer.Write(index);
                writer.Write(", {");

                foreach (Parameter parameter in parameters)
                {
                    if (parameter.Position > 0)
                    {
                        writer.Write(',');
                    }
                    writer.Write(' ');
                    writer.Write(parameter.Name);
                    writer.Write(": ");
                    writer.Write(parameter.Name);
                }

                writer.WriteLine(" }, callback));");

                writer.Write("return rpc(new Call(");
                writer.Write(index);
                writer.Write(", [");

                foreach (Parameter parameter in parameters)
                {
                    if (parameter.Position > 0)
                    {
                        writer.Write(',');
                    }
                    writer.Write(' ');
                    writer.Write(parameter.Name);
                }

                writer.WriteLine(" ], callback));");

                writer.Indent--;
                writer.WriteLine("}");
                writer.WriteLine();
            }

            writer.Write("var url = typeof(url) === 'string' ? url : '");
            writer.Write(url);
            writer.WriteLine("';");
            writer.WriteLine(@"var nextId = 0;

    function Call(method, params, callback)
    {
        this.url = url;
        this.callback = callback;
        this.proxy = self;
        this.idempotent = idems[method];
        this.request = 
        { 
            id     : ++nextId, 
            method : m[method], 
            params : params 
        };
    }

    function rpc(call)
    {
        return self.channel != null && typeof(self.channel.rpc) === 'function' ?
            self.channel.rpc(call) : call;
    }

    this.kwargs = false;
    this.channel = new JayrockChannel();

    function JayrockChannel()
    {
        this.rpc = function(call)
        {
            var async = typeof(call.callback) === 'function';
            var xhr = newXHR();
            xhr.open('POST', call.url, async, this.httpUserName, this.httpPassword);
            xhr.setRequestHeader('Content-Type', this.contentType || 'application/json; charset=utf-8');
            xhr.setRequestHeader('X-JSON-RPC', call.request.method);
            if (async) xhr.onreadystatechange = function() { xhr_onreadystatechange(xhr, call.callback); }
            xhr.send(JSON.stringify(call.request));
            call.handler = xhr;
            if (async) return call;
            if (xhr.status != 200) throw new Error(xhr.status + ' ' + xhr.statusText);
            var response = JSON.parse(xhr.responseText);
            if (response.error != null) throw response.error;
            return response.result;
        }

        function xhr_onreadystatechange(sender, callback)
        {
            if (sender.readyState == /* complete */ 4)
            {
                try { 
                    sender.onreadystatechange = null; // Avoid IE7 leak (bug #12964)
                } 
                catch (e) { 
                    /* IE 6/Mobile throws for onreadystatechange = null */ 
                }

                var response = sender.status == 200 ? 
                    JSON.parse(sender.responseText) : {};
                
                callback(response, sender);
            }
        }

        function newXHR()
        {
            if (typeof(window) !== 'undefined' && window.XMLHttpRequest)
                return new XMLHttpRequest(); /* IE7, Safari 1.2, Mozilla 1.0/Firefox, and Netscape 7 */
            else
                return new ActiveXObject('Microsoft.XMLHTTP'); /* WSH and IE 5 to IE 6 */
        }
    }");

            writer.Indent--;
            writer.WriteLine("}");

            writer.WriteLine();
            writer.Write(service.Name);
            writer.Write(".rpcMethods = ");
            JsonConvert.Export(methodNames, writer);
            writer.WriteLine(";");
        }
        protected override void WriteProxy(IndentedTextWriter writer)
        {
            if (writer == null)
            {
                throw new ArgumentNullException("writer");
            }

            writer.WriteLine("# This PowerShell script was automatically generated by");
            writer.Write("# ");
            writer.WriteLine(GetType().AssemblyQualifiedName);
            writer.Write("# on ");
            DateTime now      = DateTime.Now;
            TimeZone timeZone = TimeZone.CurrentTimeZone;

            writer.Write(now.ToLongDateString());
            writer.Write(" at ");
            writer.Write(now.ToLongTimeString());
            writer.Write(" (");
            writer.Write(timeZone.IsDaylightSavingTime(now) ?
                         timeZone.DaylightName : timeZone.StandardName);
            writer.WriteLine(")");
            writer.WriteLine();

            Uri          url     = new Uri(Request.Url.GetLeftPart(UriPartial.Path));
            ServiceClass service = Service.GetClass();

            writer.Write("function ");
            writer.Write(service.Name);
            writer.WriteLine(" {");
            writer.Indent++;
            writer.Write("param($url = '");
            writer.Write(url.ToString());
            writer.WriteLine("')");
            writer.WriteLine();
            writer.WriteLine("$self = New-Object PSObject");
            writer.WriteLine("$self | Add-Member NoteProperty url $url");
            writer.WriteLine("$self | Add-Member NoteProperty id 0");
            writer.WriteLine();

            Method[] methods     = service.GetMethods();
            string[] methodNames = new string[methods.Length];

            for (int i = 0; i < methods.Length; i++)
            {
                Method method = methods[i];
                methodNames[i] = method.Name;

                if (method.Description.Length > 0)
                {
                    writer.Write("# ");
                    writer.WriteLine(Regex.Replace(method.Description, "(\r\n)|\r|\n", "$0 #", RegexOptions.None));
                    writer.WriteLine();
                }

                writer.Write("$self | Add-Member ScriptMethod ");
                writer.Write(method.Name.Replace(".", "_"));
                writer.WriteLine(" {");
                writer.Indent++;
                writer.Write("$this.maticsoft_rpc('");
                writer.Write(method.Name);
                writer.Write("', @{");

                Parameter[] parameters = method.GetParameters();

                foreach (Parameter parameter in parameters)
                {
                    if (parameter.Position > 0)
                    {
                        writer.Write(';');
                    }
                    writer.Write(' ');
                    writer.Write(parameter.Name);
                    writer.Write(" = $args[");
                    writer.Write(parameter.Position.ToString(CultureInfo.InvariantCulture));
                    writer.Write(']');
                }

                writer.WriteLine(" })");
                writer.Indent--;
                writer.WriteLine("}");
                writer.WriteLine();
            }

            writer.WriteLine();
            writer.WriteLine(@"$self | Add-Member ScriptMethod maticsoft_rpc {
        $this.id++
        $req = [YSWL.Json.Conversion.JsonConvert]::ExportToString(@{ 
            'id' = $this.id; 'method' = $args[0]; 'params' = $args[1]})
        $form = New-Object Collections.Specialized.NameValueCollection
        $form.Add('JSON-RPC', $req)
        $wc = New-Object Net.WebClient
        $bytes = $wc.UploadValues($this.url, $form)
        if ($bytes) {
            # TODO: Get the encoding from the charset in the Content-Type response header
            $rsp = [YSWL.Json.Conversion.JsonConvert]::Import([Text.Encoding]::UTF8.GetString($bytes))
            if ($rsp.error) {
                throw $rsp.error.message
            }
            else {
                $rsp.result
            }
        }
    }

    $self");

            writer.Indent--;
            writer.WriteLine("}");
        }
        public void WriteProxy(ServiceClass service, IndentedTextWriter writer, HttpRequest request)
        {
            ValidationUtils.ArgumentNotNull(writer, "writer");
            writer.WriteLine("// This JavaScript was automatically generated by");
            writer.Write("// ");
            writer.WriteLine(base.GetType().AssemblyQualifiedName);
            writer.Write("// on ");
            DateTime now             = DateTime.Now;
            TimeZone currentTimeZone = TimeZone.CurrentTimeZone;

            writer.Write(now.ToLongDateString());
            writer.Write(" at ");
            writer.Write(now.ToLongTimeString());
            writer.Write(" (");
            writer.Write(currentTimeZone.IsDaylightSavingTime(now) ? currentTimeZone.DaylightName : currentTimeZone.StandardName);
            writer.WriteLine(")");
            writer.WriteLine();
            Uri url = request.Url;

            Debug.Assert(service != null);
            Debug.Assert(url != null);
            Debug.Assert(!url.IsFile);
            Debug.Assert(writer != null);
            writer.WriteLine("// Default Proxy");
            writer.WriteLine();
            writer.Write("function ");
            writer.Write(service.Name);
            writer.WriteLine("(url)");
            writer.WriteLine("{");
            writer.Indent++;
            ICollection methods = service.GetMethods();

            string[] values = new string[methods.Count];
            int      num    = 0;

            foreach (Method method in methods)
            {
                values[num++] = method.Name;
                writer.Write("this[\"");
                writer.Write(method.Name);
                writer.Write("\"] = function(");
                Parameter[] parameters = method.GetParameters();
                foreach (Parameter parameter in parameters)
                {
                    writer.Write(parameter.Name);
                    writer.Write(", ");
                }
                writer.WriteLine("callback)");
                writer.WriteLine("{");
                writer.Indent++;
                writer.Write("return call(\"");
                writer.Write(method.Name);
                writer.Write("\", [");
                foreach (Parameter parameter in parameters)
                {
                    if (parameter.Position > 0)
                    {
                        writer.Write(',');
                    }
                    writer.Write(' ');
                    writer.Write(parameter.Name);
                }
                writer.WriteLine(" ], callback);");
                writer.Indent--;
                writer.WriteLine("}");
                writer.WriteLine();
            }
            writer.Write("var url = typeof(url) === 'string' ? url : '");
            writer.Write(url);
            writer.WriteLine("';");
            writer.WriteLine("var self = this;\r\n    var nextId = 0;\r\n    var credentials;\r\n\r\n    this['setCredentials'] = function(userid, password)\r\n    {\r\n        if( userid == null && password == null )\r\n            this.credentials = null;\r\n        else\r\n            this.credentials = Base64.encode(userid + ':' + password);\r\n    }\r\n\r\n    function call(method, params, callback)\r\n    {\r\n        var request = { id : nextId++, method : method, params : params, credentials:self.credentials };\r\n        return callback == null ? \r\n            callSync(method, request) : callAsync(method, request, callback);\r\n    }\r\n\r\n    function callSync(method, request)\r\n    {\r\n        var http = newHTTP();\r\n        http.open('POST', url, false, self.httpUserName, self.httpPassword);\r\n        setupHeaders(http, method);\r\n        http.send(JSON.stringify(request));\r\n        if (http.status != 200)\r\n            throw { message : http.status + ' ' + http.statusText, toString : function() { return message; } };\r\n        var response = JSON.parse(http.responseText);\r\n        if (response.error != null) throw response.error;\r\n        return response.result;\r\n    }\r\n\r\n    function callAsync(method, request, callback)\r\n    {\r\n        var http = newHTTP();\r\n        http.open('POST', url, true, self.httpUserName, self.httpPassword);\r\n        setupHeaders(http, method);\r\n        http.onreadystatechange = function() { http_onreadystatechange(http, callback); }\r\n        http.send(JSON.stringify(request));\r\n        return request.id;\r\n    }\r\n\r\n    function setupHeaders(http, method)\r\n    {\r\n        http.setRequestHeader('Content-Type', 'text/plain; charset=utf-8');\r\n        http.setRequestHeader('X-JSON-RPC', method);\r\n    }\r\n\r\n    function http_onreadystatechange(sender, callback)\r\n    {\r\n        if (sender.readyState == /* complete */ 4)\r\n        {\r\n            var response = sender.status == 200 ? \r\n                JSON.parse(sender.responseText) : {};\r\n            \r\n            response.xmlHTTP = sender;\r\n                \r\n            callback(response);\r\n        }\r\n    }\r\n\r\n    function newHTTP()\r\n    {\r\n        if (typeof(window) != 'undefined' && window.XMLHttpRequest)\r\n            return new XMLHttpRequest(); /* IE7, Safari 1.2, Mozilla 1.0/Firefox, and Netscape 7 */\r\n        else\r\n            return new ActiveXObject('Microsoft.XMLHTTP'); /* WSH and IE 5 to IE 6 */\r\n    }");
            writer.Indent--;
            writer.WriteLine("}");
            writer.WriteLine();
            writer.Write(service.Name);
            writer.Write(".rpcMethods = ");
            new JsonWriter(writer).WriteStringArray(values);
            writer.WriteLine(";");
        }
        public void TaggedMethodsExported()
        {
            ServiceClass clazz = JsonRpcServices.GetClassFromType(typeof(TestService));

            Assert.AreEqual(4, clazz.GetMethods().Length);
        }
        public void UntaggedMethodsNotExported()
        {
            ServiceClass clazz = JsonRpcServices.GetClassFromType(typeof(EmptyService));

            Assert.AreEqual(0, clazz.GetMethods().Length);
        }