diff options
author | Atsushi Eno <atsushieno@gmail.com> | 2009-08-10 18:22:21 +0400 |
---|---|---|
committer | Atsushi Eno <atsushieno@gmail.com> | 2009-08-10 18:22:21 +0400 |
commit | 5b3009e9d5e4d11830a65323f53e8335ba5b66e0 (patch) | |
tree | 26eccd095b81b63b9183584244384a698ad3d56f /mcs | |
parent | a88efb6f0185e37eb93c7f7ab1121d39fc45ad1b (diff) |
2009-08-10 Atsushi Enomoto <atsushi@ximian.com>
* Driver.cs, CommandLineOptions.cs : add moonlight proxy generator
support.
* MoonlightChannelBaseExtension.cs : new, moonlight proxy generator.
Implemented as I[Service|Operation]ContractGenerationExtension.
* svcutil.exe.sources : add above.
svn path=/trunk/mcs/; revision=139641
Diffstat (limited to 'mcs')
-rw-r--r-- | mcs/tools/svcutil/ChangeLog | 8 | ||||
-rw-r--r-- | mcs/tools/svcutil/CommandLineOptions.cs | 13 | ||||
-rw-r--r-- | mcs/tools/svcutil/Driver.cs | 15 | ||||
-rw-r--r-- | mcs/tools/svcutil/MoonlightChannelBaseExtension.cs | 287 | ||||
-rw-r--r-- | mcs/tools/svcutil/svcutil.exe.sources | 1 |
5 files changed, 322 insertions, 2 deletions
diff --git a/mcs/tools/svcutil/ChangeLog b/mcs/tools/svcutil/ChangeLog index e6276385c58..ee5e9deb32c 100644 --- a/mcs/tools/svcutil/ChangeLog +++ b/mcs/tools/svcutil/ChangeLog @@ -1,3 +1,11 @@ +2009-08-10 Atsushi Enomoto <atsushi@ximian.com> + + * Driver.cs, CommandLineOptions.cs : add moonlight proxy generator + support. + * MoonlightChannelBaseExtension.cs : new, moonlight proxy generator. + Implemented as I[Service|Operation]ContractGenerationExtension. + * svcutil.exe.sources : add above. + 2006-10-19 Ankit Jain <jankit@novell.com> * Driver.cs: Try to use HTTP GET to get wsdl, if it fails then try diff --git a/mcs/tools/svcutil/CommandLineOptions.cs b/mcs/tools/svcutil/CommandLineOptions.cs index e748a60dcb9..1b1e0ccba31 100644 --- a/mcs/tools/svcutil/CommandLineOptions.cs +++ b/mcs/tools/svcutil/CommandLineOptions.cs @@ -59,6 +59,19 @@ namespace Mono.ServiceContractTool [Option ("Generate typed messages.", "typedMessage", "tm")] public bool GenerateTypedMessages; + bool generate_moonlight_proxy; + + [Option ("Generate moonlight client. (This option may vanish.)", "moonlight")] + public bool GenerateMoonlightProxy { + get { return generate_moonlight_proxy; } + set { + if (!value) + return; + generate_moonlight_proxy = true; + GenerateAsync = true; + } + } + [Option ("Generate types as internal.", 'i', "internal")] public bool GenerateTypesAsInternal; diff --git a/mcs/tools/svcutil/Driver.cs b/mcs/tools/svcutil/Driver.cs index af22f105696..d365aca1a6d 100644 --- a/mcs/tools/svcutil/Driver.cs +++ b/mcs/tools/svcutil/Driver.cs @@ -6,6 +6,7 @@ using System.Reflection; using System.ServiceModel; using System.ServiceModel.Channels; using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; using System.Collections.ObjectModel; using System.Xml; using System.Xml.Schema; @@ -92,8 +93,18 @@ namespace Mono.ServiceContractTool generator.GenerateServiceContractType (se.Contract);*/ Collection<ContractDescription> contracts = importer.ImportAllContracts (); - foreach (ContractDescription cd in contracts) - generator.GenerateServiceContractType (cd); + foreach (ContractDescription cd in contracts) { + if (co.GenerateMoonlightProxy) { + var moonctx = new MoonlightChannelBaseContext (); + cd.Behaviors.Add (new MoonlightChannelBaseContractExtension (moonctx)); + foreach (var od in cd.Operations) + od.Behaviors.Add (new MoonlightChannelBaseOperationExtension (moonctx)); + generator.GenerateServiceContractType (cd); + moonctx.Fixup (); + } + else + generator.GenerateServiceContractType (cd); + } /*if (cns.Types.Count == 0) { Console.Error.WriteLine ("Argument assemblies have no types."); diff --git a/mcs/tools/svcutil/MoonlightChannelBaseExtension.cs b/mcs/tools/svcutil/MoonlightChannelBaseExtension.cs new file mode 100644 index 00000000000..06457cf1c68 --- /dev/null +++ b/mcs/tools/svcutil/MoonlightChannelBaseExtension.cs @@ -0,0 +1,287 @@ +// +// MoonlightChannelBaseExtension.cs +// +// Author: +// Atsushi Enomoto <atsushi@ximian.com> +// +// Copyright (C) 2009 Novell, Inc. http://www.novell.com +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// +using System; +using System.CodeDom; +using System.CodeDom.Compiler; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.IO; +using System.Reflection; +using System.ServiceModel; +using System.ServiceModel.Channels; +using System.ServiceModel.Description; +using System.ServiceModel.Dispatcher; + +namespace Mono.ServiceContractTool +{ + class MoonlightChannelBaseContext + { + public MoonlightChannelBaseContractExtension Contract; + public List<MoonlightChannelBaseOperationExtension> Operations = new List<MoonlightChannelBaseOperationExtension> (); + + public CodeTypeDeclaration ClientType { get; set; } + public CodeTypeDeclaration ChannelType { get; set; } + + public void FindClientType (ServiceContractGenerationContext context) + { + var cd = context.Contract; + string name = cd.Name + "Client"; + if (name [0] == 'I') + name = name.Substring (1); + + foreach (CodeNamespace cns in context.ServiceContractGenerator.TargetCompileUnit.Namespaces) + foreach (CodeTypeDeclaration ct in cns.Types) + if (ct == context.ContractType) + foreach (CodeTypeDeclaration ct2 in cns.Types) + if (ct2.Name == name) { + ClientType = ct2; + return; + } + throw new Exception (String.Format ("Contract '{0}' not found", name)); + } + + public void Fixup () + { + Contract.Fixup (); + foreach (var op in Operations) + op.Fixup (); + } + } + + class MoonlightChannelBaseContractExtension : IContractBehavior, IServiceContractGenerationExtension + { + public MoonlightChannelBaseContractExtension (MoonlightChannelBaseContext mlContext) + { + ml_context = mlContext; + } + + MoonlightChannelBaseContext ml_context; + + // IContractBehavior + public void AddBindingParameters (ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) + { + throw new NotSupportedException (); + } + + public void ApplyClientBehavior ( + ContractDescription description, + ServiceEndpoint endpoint, + ClientRuntime proxy) + { + throw new NotSupportedException (); + } + + public void ApplyDispatchBehavior ( + ContractDescription description, + ServiceEndpoint endpoint, + DispatchRuntime dispatch) + { + throw new NotSupportedException (); + } + + public void Validate ( + ContractDescription description, + ServiceEndpoint endpoint) + { + throw new NotSupportedException (); + } + + // IServiceContractGenerationExtensions + + public void GenerateContract ( + ServiceContractGenerationContext context) + { + this.context = context; + ml_context.Contract = this; + } + + ServiceContractGenerationContext context; + + public void Fixup () + { + ContractDescription cd = context.Contract; + ml_context.FindClientType (context); + var parentClass = ml_context.ClientType; + + string name = cd.Name + "Channel"; + if (name [0] == 'I') + name = name.Substring (1); + + var gt = new CodeTypeReference (cd.Name); + var clientBaseType = new CodeTypeReference ("System.ServiceModel.ClientBase", gt); + // this omits namespace, but should compile + var channelBase = new CodeTypeReference ("ChannelBase", gt); + var type = new CodeTypeDeclaration (name); + parentClass.Members.Add (type); + type.TypeAttributes = TypeAttributes.Public; + type.BaseTypes.Add (channelBase); + type.BaseTypes.Add (new CodeTypeReference (cd.Name)); + + ml_context.ChannelType = type; + + // .ctor(ClientBase<T> client) + var ctor = new CodeConstructor (); + ctor.Attributes = MemberAttributes.Public; + ctor.Parameters.Add ( + new CodeParameterDeclarationExpression ( + clientBaseType, "client")); + ctor.BaseConstructorArgs.Add ( + new CodeArgumentReferenceExpression ("client")); + type.Members.Add (ctor); + } + } + + class MoonlightChannelBaseOperationExtension : IOperationBehavior, IOperationContractGenerationExtension + { + public MoonlightChannelBaseOperationExtension (MoonlightChannelBaseContext mlContext) + { + ml_context = mlContext; + } + + MoonlightChannelBaseContext ml_context; + + // IOperationBehavior + + public void AddBindingParameters ( + OperationDescription description, + BindingParameterCollection parameters) + { + throw new NotSupportedException (); + } + + public void ApplyDispatchBehavior ( + OperationDescription description, + DispatchOperation dispatch) + { + throw new NotSupportedException (); + } + + public void ApplyClientBehavior ( + OperationDescription description, + ClientOperation proxy) + { + throw new NotSupportedException (); + } + + public void Validate ( + OperationDescription description) + { + throw new NotSupportedException (); + } + + // IOperationContractGenerationContext + + public void GenerateOperation (OperationContractGenerationContext context) + { + this.context = context; + ml_context.Operations.Add (this); + } + + OperationContractGenerationContext context; + + public void Fixup () + { + var type = ml_context.ChannelType; + var od = context.Operation; + + CodeMemberMethod cm = new CodeMemberMethod (); + type.Members.Add (cm); + cm.Name = "Begin" + od.Name; + cm.Attributes = MemberAttributes.Public + | MemberAttributes.Final; + + List<CodeExpression> inArgs = new List<CodeExpression> (); + List<CodeExpression> outArgs = new List<CodeExpression> (); + + foreach (var md in od.Messages) { + var l = md.Direction == MessageDirection.Input ? inArgs : outArgs; + foreach (var p in md.Body.Parts) + if (p != md.Body.ReturnValue) + l.Add (new CodeArgumentReferenceExpression (p.Name)); + } + + cm.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference (typeof (AsyncCallback)), "asyncCallback")); + cm.Parameters.Add (new CodeParameterDeclarationExpression (new CodeTypeReference (typeof (object)), "userState")); + cm.ReturnType = new CodeTypeReference (typeof (IAsyncResult)); + + var argsDecl = new CodeVariableDeclarationStatement ( + typeof (object []), + "args", + new CodeArrayCreateExpression (typeof (object), inArgs.ToArray ())); + cm.Statements.Add (argsDecl); + + var args = new List<CodeExpression> (); + args.Add (new CodePrimitiveExpression (od.Name)); + args.Add (new CodeVariableReferenceExpression ("args")); + args.Add (new CodeArgumentReferenceExpression ("asyncCallback")); + args.Add (new CodeArgumentReferenceExpression ("userState")); + + CodeExpression call = new CodeMethodInvokeExpression ( + new CodeBaseReferenceExpression (), + "BeginInvoke", + args.ToArray ()); + + if (cm.ReturnType.BaseType == "System.Void") + cm.Statements.Add (new CodeExpressionStatement (call)); + else + cm.Statements.Add (new CodeMethodReturnStatement (call)); + + // EndXxx() implementation + + cm = new CodeMemberMethod (); + cm.Attributes = MemberAttributes.Public + | MemberAttributes.Final; + type.Members.Add (cm); + cm.Name = "End" + od.Name; + + var res = new CodeParameterDeclarationExpression (new CodeTypeReference (typeof (IAsyncResult)), "result"); + cm.Parameters.Add (res); + + cm.ReturnType = context.EndMethod.ReturnType; + + string resultArgName = "result"; + argsDecl = new CodeVariableDeclarationStatement ( + typeof (object []), + "args", + new CodeArrayCreateExpression (typeof (object), new CodePrimitiveExpression (outArgs.Count))); + cm.Statements.Add (argsDecl); + + call = new CodeMethodInvokeExpression ( + new CodeBaseReferenceExpression (), + "EndInvoke", + new CodePrimitiveExpression (od.Name), + new CodeVariableReferenceExpression ("args"), + new CodeArgumentReferenceExpression (resultArgName)); + + if (cm.ReturnType.BaseType == "System.Void") + cm.Statements.Add (new CodeExpressionStatement (call)); + else + cm.Statements.Add (new CodeMethodReturnStatement (call)); + } + } +} diff --git a/mcs/tools/svcutil/svcutil.exe.sources b/mcs/tools/svcutil/svcutil.exe.sources index 17425629cbe..aa7b6bfd125 100644 --- a/mcs/tools/svcutil/svcutil.exe.sources +++ b/mcs/tools/svcutil/svcutil.exe.sources @@ -1,3 +1,4 @@ Driver.cs CommandLineOptions.cs +MoonlightChannelBaseExtension.cs |