| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850 |
- //
- // System.Web.Services.Description.ProtocolImporter.cs
- //
- // Author:
- // Tim Coleman ([email protected])
- // Lluis Sanchez Gual ([email protected])
- //
- // Copyright (C) Tim Coleman, 2002
- //
- //
- // 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.Web.Services;
- using System.Web.Services.Protocols;
- using System.Xml.Serialization;
- using System.Xml;
- using System.Xml.Schema;
- using System.Collections;
- using System.Configuration;
- namespace System.Web.Services.Description {
- public abstract class ProtocolImporter {
- #region Fields
- Binding binding;
- string className;
- CodeIdentifiers classNames;
- CodeNamespace codeNamespace;
- CodeCompileUnit codeCompileUnit;
- CodeTypeDeclaration codeTypeDeclaration;
- Message inputMessage;
- string methodName;
- Operation operation;
- OperationBinding operationBinding;
- Message outputMessage;
- Port port;
- PortType portType;
- string protocolName;
- Service service;
- ServiceDescriptionImportWarnings warnings = (ServiceDescriptionImportWarnings)0;
- ServiceDescriptionImporter descriptionImporter;
- ImportInfo iinfo;
- XmlSchemas xmlSchemas;
- XmlSchemas soapSchemas;
-
- #if NET_2_0
- ArrayList asyncTypes = new ArrayList ();
- #endif
- #endregion // Fields
- #region Constructors
-
- protected ProtocolImporter ()
- {
- }
-
- #endregion // Constructors
- #region Properties
- [MonoTODO]
- public XmlSchemas AbstractSchemas {
- get { return descriptionImporter.Schemas; }
- }
- public Binding Binding {
- get { return binding; }
- }
- public string ClassName {
- get { return className; }
- }
- public CodeIdentifiers ClassNames {
- get { return classNames; }
- }
- public CodeNamespace CodeNamespace {
- get { return codeNamespace; }
- }
- public CodeTypeDeclaration CodeTypeDeclaration {
- get { return codeTypeDeclaration; }
- }
- [MonoTODO]
- public XmlSchemas ConcreteSchemas {
- get { return descriptionImporter.Schemas; }
- }
- public Message InputMessage {
- get { return inputMessage; }
- }
- public string MethodName {
- get { return methodName; }
- }
- public Operation Operation {
- get { return operation; }
- }
- public OperationBinding OperationBinding {
- get { return operationBinding; }
- }
- public Message OutputMessage {
- get { return outputMessage; }
- }
- public Port Port {
- get { return port; }
- }
- public PortType PortType {
- get { return portType; }
- }
- public abstract string ProtocolName {
- get;
- }
- public XmlSchemas Schemas {
- get { return descriptionImporter.Schemas; }
- }
- public Service Service {
- get { return service; }
- }
- public ServiceDescriptionCollection ServiceDescriptions {
- get { return descriptionImporter.ServiceDescriptions; }
- }
- public ServiceDescriptionImportStyle Style {
- get { return descriptionImporter.Style; }
- }
- public ServiceDescriptionImportWarnings Warnings {
- get { return warnings; }
- set { warnings = value; }
- }
-
- internal ImportInfo ImportInfo
- {
- get { return iinfo; }
- }
-
- internal XmlSchemas LiteralSchemas
- {
- get { return xmlSchemas; }
- }
-
- internal XmlSchemas EncodedSchemas
- {
- get { return soapSchemas; }
- }
-
- #if NET_2_0
- internal CodeGenerationOptions CodeGenerationOptions {
- get { return descriptionImporter.CodeGenerationOptions; }
- }
-
- internal CodeDomProvider CodeGenerator {
- get { return descriptionImporter.CodeGenerator; }
- }
- internal ImportContext ImportContext {
- get { return descriptionImporter.Context; }
- }
- #endif
- #endregion // Properties
- #region Methods
-
- internal bool Import (ServiceDescriptionImporter descriptionImporter, CodeNamespace codeNamespace, CodeCompileUnit codeCompileUnit, ArrayList importInfo)
- {
- this.descriptionImporter = descriptionImporter;
- this.classNames = new CodeIdentifiers();;
- this.codeNamespace = codeNamespace;
- this.codeCompileUnit = codeCompileUnit;
- warnings = (ServiceDescriptionImportWarnings) 0;
-
- bool found = false;
-
- ClasifySchemas (importInfo);
- BeginNamespace ();
-
- foreach (ImportInfo info in importInfo)
- {
- foreach (Service service in info.ServiceDescription.Services)
- {
- this.service = service;
- int bindingCount = 0;
- foreach (Port port in service.Ports)
- {
- binding = ServiceDescriptions.GetBinding (port.Binding);
- if (IsBindingSupported ()) bindingCount ++;
- }
-
- foreach (Port port in service.Ports)
- {
- this.iinfo = info;
- this.port = port;
- binding = ServiceDescriptions.GetBinding (port.Binding);
- if (!IsBindingSupported ()) continue;
-
- found = true;
- ImportPortBinding (bindingCount > 1);
- }
- }
- }
-
- if (!found)
- {
- // Looks like MS.NET generates classes for all bindings if
- // no services are present
-
- foreach (ImportInfo info in importInfo)
- {
- this.iinfo = info;
- foreach (Binding b in info.ServiceDescription.Bindings)
- {
- this.binding = b;
- this.service = null;
- this.port = null;
- if (!IsBindingSupported ()) continue;
- found = true;
- ImportPortBinding (true);
- }
- }
- }
- EndNamespace ();
-
- if (!found) warnings = ServiceDescriptionImportWarnings.NoCodeGenerated;
- return true;
- }
- void ImportPortBinding (bool multipleBindings)
- {
- if (port != null) {
- if (multipleBindings) className = port.Name;
- else className = service.Name;
- }
- else
- className = binding.Name;
-
- className = classNames.AddUnique (CodeIdentifier.MakeValid (className), port);
- className = className.Replace ("_x0020_", ""); // MS.NET seems to do this
-
- try
- {
- portType = ServiceDescriptions.GetPortType (binding.Type);
- if (portType == null) throw new Exception ("Port type not found: " + binding.Type);
- CodeTypeDeclaration codeClass = BeginClass ();
- codeTypeDeclaration = codeClass;
- AddCodeType (codeClass, port != null ? port.Documentation : null);
- codeClass.Attributes = MemberAttributes.Public;
-
- if (service != null && service.Documentation != null && service.Documentation != "")
- AddComments (codeClass, service.Documentation);
- if (Style == ServiceDescriptionImportStyle.Client) {
- CodeAttributeDeclaration att = new CodeAttributeDeclaration ("System.Diagnostics.DebuggerStepThroughAttribute");
- AddCustomAttribute (codeClass, att, true);
-
- att = new CodeAttributeDeclaration ("System.ComponentModel.DesignerCategoryAttribute");
- att.Arguments.Add (GetArg ("code"));
- AddCustomAttribute (codeClass, att, true);
- }
- else
- codeClass.TypeAttributes = System.Reflection.TypeAttributes.Abstract | System.Reflection.TypeAttributes.Public;
- if (binding.Operations.Count == 0) {
- warnings |= ServiceDescriptionImportWarnings.NoMethodsGenerated;
- return;
- }
-
- foreach (OperationBinding oper in binding.Operations)
- {
- operationBinding = oper;
- operation = FindPortOperation ();
- if (operation == null)
- throw new Exception ("Operation " + operationBinding.Name + " not found in portType " + PortType.Name);
- inputMessage = null;
- outputMessage = null;
- foreach (OperationMessage omsg in operation.Messages)
- {
- Message msg = ServiceDescriptions.GetMessage (omsg.Message);
- if (msg == null) throw new Exception ("Message not found: " + omsg.Message);
-
- if (omsg is OperationInput)
- inputMessage = msg;
- else
- outputMessage = msg;
- }
-
- CodeMemberMethod method = GenerateMethod ();
-
- if (method != null)
- {
- methodName = method.Name;
- if (operation.Documentation != null && operation.Documentation != "")
- AddComments (method, operation.Documentation);
- #if NET_2_0
- if (Style == ServiceDescriptionImportStyle.Client)
- AddAsyncMembers (method.Name, method);
- #endif
- }
- }
-
- #if NET_2_0
- if (Style == ServiceDescriptionImportStyle.Client)
- AddAsyncTypes ();
- #endif
-
- EndClass ();
- }
- catch (InvalidOperationException ex)
- {
- warnings |= ServiceDescriptionImportWarnings.NoCodeGenerated;
- UnsupportedBindingWarning (ex.Message);
- }
- }
- Operation FindPortOperation ()
- {
- string inMessage = null;
- string outMessage = null;
- int numMsg = 1;
-
- if (operationBinding.Input == null) throw new InvalidOperationException ("Input operation binding not found");
- inMessage = (operationBinding.Input.Name != null) ? operationBinding.Input.Name : operationBinding.Name;
-
- if (operationBinding.Output != null) {
- outMessage = (operationBinding.Output.Name != null) ? operationBinding.Output.Name : operationBinding.Name;
- numMsg++;
- }
-
- string operName = operationBinding.Name;
-
- Operation foundOper = null;
- foreach (Operation oper in PortType.Operations)
- {
- if (oper.Name == operName)
- {
- int hits = 0;
- foreach (OperationMessage omsg in oper.Messages)
- {
- if (omsg is OperationInput && GetOperMessageName (omsg, operName) == inMessage) hits++;
- if (omsg is OperationOutput && GetOperMessageName (omsg, operName) == outMessage) hits++;
- }
- if (hits == numMsg) return oper;
- foundOper = oper;
- }
- }
- return foundOper;
- }
-
- string GetOperMessageName (OperationMessage msg, string operName)
- {
- if (msg.Name == null) return operName;
- else return msg.Name;
- }
-
- internal void GenerateServiceUrl (string location, CodeStatementCollection stms)
- {
- if (ImportInfo.AppSettingUrlKey == null || ImportInfo.AppSettingUrlKey == string.Empty) {
- if (location != null) {
- CodeExpression ce = new CodeFieldReferenceExpression (new CodeThisReferenceExpression(), "Url");
- CodeAssignStatement cas = new CodeAssignStatement (ce, new CodePrimitiveExpression (location));
- stms.Add (cas);
- }
- }
- else
- {
- CodeExpression prop = new CodePropertyReferenceExpression (new CodeTypeReferenceExpression ("System.Configuration.ConfigurationSettings"), "AppSettings");
- prop = new CodeIndexerExpression (prop, new CodePrimitiveExpression (ImportInfo.AppSettingUrlKey));
- stms.Add (new CodeVariableDeclarationStatement (typeof(string), "urlSetting", prop));
-
- CodeExpression urlSetting = new CodeVariableReferenceExpression ("urlSetting");
- CodeExpression thisUrl = new CodeFieldReferenceExpression (new CodeThisReferenceExpression(), "Url");
-
- CodeStatement[] trueStms = new CodeStatement [1];
- CodeExpression ce = urlSetting;
- CodeExpression cond = new CodeBinaryOperatorExpression (urlSetting, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression (null));
-
- if (ImportInfo.AppSettingBaseUrl != null)
- ce = new CodeMethodInvokeExpression (new CodeTypeReferenceExpression (typeof(string)), "Concat", ce, new CodePrimitiveExpression (ImportInfo.AppSettingBaseUrl));
- trueStms [0] = new CodeAssignStatement (thisUrl, ce);
-
- if (location != null) {
- CodeStatement[] falseStms = new CodeStatement [1];
- falseStms [0] = new CodeAssignStatement (thisUrl, new CodePrimitiveExpression (location));
- stms.Add (new CodeConditionStatement (cond, trueStms, falseStms));
- }
- else
- stms.Add (new CodeConditionStatement (cond, trueStms));
- }
- }
-
- void ClasifySchemas (ArrayList importInfo)
- {
- // I don't like this, but I could not find any other way of clasifying
- // schemas between encoded and literal.
-
- xmlSchemas = new XmlSchemas ();
- soapSchemas = new XmlSchemas ();
-
- foreach (ImportInfo info in importInfo)
- {
- foreach (Service service in info.ServiceDescription.Services)
- {
- foreach (Port port in service.Ports)
- {
- this.iinfo = info;
- this.port = port;
- binding = ServiceDescriptions.GetBinding (port.Binding);
- if (binding == null) continue;
- portType = ServiceDescriptions.GetPortType (binding.Type);
- if (portType == null) continue;
-
- foreach (OperationBinding oper in binding.Operations)
- {
- operationBinding = oper;
- operation = FindPortOperation ();
- if (operation == null) continue;
-
- foreach (OperationMessage omsg in operation.Messages)
- {
- Message msg = ServiceDescriptions.GetMessage (omsg.Message);
- if (msg == null) continue;
-
- if (omsg is OperationInput)
- inputMessage = msg;
- else
- outputMessage = msg;
- }
-
- if (GetMessageEncoding (oper.Input) == SoapBindingUse.Encoded)
- AddMessageSchema (soapSchemas, oper.Input, inputMessage);
- else
- AddMessageSchema (xmlSchemas, oper.Input, inputMessage);
-
- if (oper.Output != null) {
- if (GetMessageEncoding (oper.Output) == SoapBindingUse.Encoded)
- AddMessageSchema (soapSchemas, oper.Output, outputMessage);
- else
- AddMessageSchema (xmlSchemas, oper.Output, outputMessage);
- }
- }
- }
- }
- }
-
- XmlSchemas defaultList = xmlSchemas;
-
- if (xmlSchemas.Count == 0 && soapSchemas.Count > 0)
- defaultList = soapSchemas;
-
- // Schemas not referenced by any message
- foreach (XmlSchema sc in Schemas)
- {
- if (!soapSchemas.Contains (sc) && !xmlSchemas.Contains (sc)) {
- if (ImportsEncodedNamespace (sc))
- soapSchemas.Add (sc);
- else
- defaultList.Add (sc);
- }
- }
- }
-
- void AddMessageSchema (XmlSchemas schemas, MessageBinding mb, Message msg)
- {
- foreach (MessagePart part in msg.Parts)
- {
- if (part.Element != XmlQualifiedName.Empty)
- AddIncludingSchema (schemas, part.Element.Namespace);
- else if (part.Type != XmlQualifiedName.Empty)
- AddIncludingSchema (schemas, part.Type.Namespace);
- }
- SoapBodyBinding sbb = mb.Extensions.Find (typeof(SoapBodyBinding)) as SoapBodyBinding;
- if (sbb != null) AddIncludingSchema (schemas, sbb.Namespace);
- }
-
- void AddIncludingSchema (XmlSchemas list, string ns)
- {
- XmlSchema sc = Schemas [ns];
- if (sc == null || list.Contains (sc)) return;
- list.Add (sc);
- foreach (XmlSchemaObject ob in sc.Includes)
- {
- XmlSchemaImport import = ob as XmlSchemaImport;
- if (import != null) AddIncludingSchema (list, import.Namespace);
- }
- }
-
- SoapBindingUse GetMessageEncoding (MessageBinding mb)
- {
- SoapBodyBinding sbb = mb.Extensions.Find (typeof(SoapBodyBinding)) as SoapBodyBinding;
- if (sbb == null)
- {
- if (mb is InputBinding) return SoapBindingUse.Encoded;
- else return SoapBindingUse.Literal;
- }
- else
- if (sbb.Use == SoapBindingUse.Encoded) return SoapBindingUse.Encoded;
- else
- return SoapBindingUse.Literal;
- }
-
- bool ImportsEncodedNamespace (XmlSchema sc)
- {
- foreach (XmlSchemaObject ob in sc.Includes)
- {
- XmlSchemaImport import = ob as XmlSchemaImport;
- if (import.Namespace == SoapProtocolReflector.EncodingNamespace) return true;
- }
- return false;
- }
-
- #if NET_2_0
- void AddAsyncTypes ()
- {
- foreach (CodeTypeDeclaration type in asyncTypes)
- codeNamespace.Types.Add (type);
- asyncTypes.Clear ();
- }
- void AddAsyncMembers (string messageName, CodeMemberMethod method)
- {
- CodeThisReferenceExpression ethis = new CodeThisReferenceExpression();
- CodePrimitiveExpression enull = new CodePrimitiveExpression (null);
-
- CodeMemberField codeField = new CodeMemberField (typeof(System.Threading.SendOrPostCallback), messageName + "OperationCompleted");
- codeField.Attributes = MemberAttributes.Private;
- CodeTypeDeclaration.Members.Add (codeField);
-
- // Event arguments class
-
- string argsClassName = classNames.AddUnique (messageName + "CompletedEventArgs", null);
- CodeTypeDeclaration argsClass = new CodeTypeDeclaration (argsClassName);
- argsClass.BaseTypes.Add (new CodeTypeReference ("System.ComponentModel.AsyncCompletedEventArgs"));
- CodeMemberField resultsField = new CodeMemberField (typeof(object[]), "results");
- resultsField.Attributes = MemberAttributes.Private;
- argsClass.Members.Add (resultsField);
-
- CodeConstructor cc = new CodeConstructor ();
- cc.Attributes = MemberAttributes.Assembly;
- cc.Parameters.Add (new CodeParameterDeclarationExpression (typeof(object[]), "results"));
- cc.Parameters.Add (new CodeParameterDeclarationExpression (typeof(System.Exception), "exception"));
- cc.Parameters.Add (new CodeParameterDeclarationExpression (typeof(bool), "cancelled"));
- cc.Parameters.Add (new CodeParameterDeclarationExpression (typeof(object), "userState"));
- cc.BaseConstructorArgs.Add (new CodeVariableReferenceExpression ("exception"));
- cc.BaseConstructorArgs.Add (new CodeVariableReferenceExpression ("cancelled"));
- cc.BaseConstructorArgs.Add (new CodeVariableReferenceExpression ("userState"));
- CodeExpression thisResults = new CodeFieldReferenceExpression (ethis, "results");
- cc.Statements.Add (new CodeAssignStatement (thisResults, new CodeVariableReferenceExpression ("results")));
- argsClass.Members.Add (cc);
-
- int ind = 0;
-
- if (method.ReturnType.BaseType != "System.Void")
- argsClass.Members.Add (CreateArgsProperty (method.ReturnType, "Result", ind++));
-
- foreach (CodeParameterDeclarationExpression par in method.Parameters)
- {
- if (par.Direction == FieldDirection.Out || par.Direction == FieldDirection.Ref)
- argsClass.Members.Add (CreateArgsProperty (par.Type, par.Name, ind++));
- }
-
- bool needsArgsClass = (ind > 0);
- if (needsArgsClass)
- asyncTypes.Add (argsClass);
- else
- argsClassName = "System.ComponentModel.AsyncCompletedEventArgs";
-
- // Event delegate type
-
- CodeTypeDelegate delegateType = new CodeTypeDelegate (messageName + "CompletedEventHandler");
- delegateType.Parameters.Add (new CodeParameterDeclarationExpression (typeof(object), "sender"));
- delegateType.Parameters.Add (new CodeParameterDeclarationExpression (argsClassName, "args"));
-
- // Event member
-
- CodeMemberEvent codeEvent = new CodeMemberEvent ();
- codeEvent.Name = messageName + "Completed";
- codeEvent.Type = new CodeTypeReference (delegateType.Name);
- CodeTypeDeclaration.Members.Add (codeEvent);
-
- // Async method (without user state param)
-
- CodeMemberMethod am = new CodeMemberMethod ();
- am.Attributes = MemberAttributes.Public | MemberAttributes.Final;
- am.Name = method.Name + "Async";
- am.ReturnType = new CodeTypeReference (typeof(void));
- CodeMethodInvokeExpression inv;
- inv = new CodeMethodInvokeExpression (ethis, am.Name);
- am.Statements.Add (inv);
-
- // On...Completed method
-
- CodeMemberMethod onCompleted = new CodeMemberMethod ();
- onCompleted.Name = "On" + messageName + "Completed";
- onCompleted.Attributes = MemberAttributes.Private | MemberAttributes.Final;
- onCompleted.ReturnType = new CodeTypeReference (typeof(void));
- onCompleted.Parameters.Add (new CodeParameterDeclarationExpression (typeof(object), "arg"));
-
- CodeConditionStatement anIf = new CodeConditionStatement ();
-
- CodeExpression eventField = new CodeEventReferenceExpression (ethis, codeEvent.Name);
- anIf.Condition = new CodeBinaryOperatorExpression (eventField, CodeBinaryOperatorType.IdentityInequality, enull);
- CodeExpression castedArg = new CodeCastExpression (typeof(System.Web.Services.Protocols.InvokeCompletedEventArgs), new CodeVariableReferenceExpression ("arg"));
- CodeStatement invokeArgs = new CodeVariableDeclarationStatement (typeof(System.Web.Services.Protocols.InvokeCompletedEventArgs), "invokeArgs", castedArg);
- anIf.TrueStatements.Add (invokeArgs);
-
- CodeDelegateInvokeExpression delegateInvoke = new CodeDelegateInvokeExpression ();
- delegateInvoke.TargetObject = eventField;
- delegateInvoke.Parameters.Add (ethis);
- CodeObjectCreateExpression argsInstance = new CodeObjectCreateExpression (argsClassName);
- CodeExpression invokeArgsVar = new CodeVariableReferenceExpression ("invokeArgs");
- if (needsArgsClass) argsInstance.Parameters.Add (new CodeFieldReferenceExpression (invokeArgsVar, "Results"));
- argsInstance.Parameters.Add (new CodeFieldReferenceExpression (invokeArgsVar, "Error"));
- argsInstance.Parameters.Add (new CodeFieldReferenceExpression (invokeArgsVar, "Cancelled"));
- argsInstance.Parameters.Add (new CodeFieldReferenceExpression (invokeArgsVar, "UserState"));
- delegateInvoke.Parameters.Add (argsInstance);
- anIf.TrueStatements.Add (delegateInvoke);
-
- onCompleted.Statements.Add (anIf);
-
- // Async method
-
- CodeMemberMethod asyncMethod = new CodeMemberMethod ();
- asyncMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final;
- asyncMethod.Name = method.Name + "Async";
- asyncMethod.ReturnType = new CodeTypeReference (typeof(void));
-
- CodeExpression delegateField = new CodeFieldReferenceExpression (ethis, codeField.Name);
- anIf = new CodeConditionStatement ();
- anIf.Condition = new CodeBinaryOperatorExpression (delegateField, CodeBinaryOperatorType.IdentityEquality, enull);;
- CodeExpression delegateRef = new CodeMethodReferenceExpression (ethis, onCompleted.Name);
- CodeExpression newDelegate = new CodeObjectCreateExpression (typeof(System.Threading.SendOrPostCallback), delegateRef);
- CodeAssignStatement cas = new CodeAssignStatement (delegateField, newDelegate);
- anIf.TrueStatements.Add (cas);
- asyncMethod.Statements.Add (anIf);
-
- CodeArrayCreateExpression paramsArray = new CodeArrayCreateExpression (typeof(object));
-
- // Assign parameters
-
- CodeIdentifiers paramsIds = new CodeIdentifiers ();
-
- foreach (CodeParameterDeclarationExpression par in method.Parameters)
- {
- paramsIds.Add (par.Name, null);
- if (par.Direction == FieldDirection.In || par.Direction == FieldDirection.Ref) {
- CodeParameterDeclarationExpression inpar = new CodeParameterDeclarationExpression (par.Type, par.Name);
- am.Parameters.Add (inpar);
- asyncMethod.Parameters.Add (inpar);
- inv.Parameters.Add (new CodeVariableReferenceExpression (par.Name));
- paramsArray.Initializers.Add (new CodeVariableReferenceExpression (par.Name));
- }
- }
- inv.Parameters.Add (enull);
-
- string userStateName = paramsIds.AddUnique ("userState", null);
- asyncMethod.Parameters.Add (new CodeParameterDeclarationExpression (typeof(object), userStateName));
-
- CodeExpression userStateVar = new CodeVariableReferenceExpression (userStateName);
- asyncMethod.Statements.Add (BuildInvokeAsync (messageName, paramsArray, delegateField, userStateVar));
-
- CodeTypeDeclaration.Members.Add (am);
- CodeTypeDeclaration.Members.Add (asyncMethod);
- CodeTypeDeclaration.Members.Add (onCompleted);
-
- asyncTypes.Add (delegateType);
- }
-
- CodeMemberProperty CreateArgsProperty (CodeTypeReference type, string name, int ind)
- {
- CodeMemberProperty prop = new CodeMemberProperty ();
- prop.Attributes = MemberAttributes.Public | MemberAttributes.Final;
- prop.HasGet = true;
- prop.HasSet = false;
- prop.Name = name;
- prop.Type = type;
- CodeThisReferenceExpression ethis = new CodeThisReferenceExpression();
- CodeExpression thisResults = new CodeFieldReferenceExpression (ethis, "results");
- prop.GetStatements.Add (new CodeMethodInvokeExpression (ethis, "RaiseExceptionIfNecessary"));
- CodeArrayIndexerExpression arrValue = new CodeArrayIndexerExpression (thisResults, new CodePrimitiveExpression (ind));
- CodeExpression retval = new CodeCastExpression (type, arrValue);
- prop.GetStatements.Add (new CodeMethodReturnStatement (retval));
- return prop;
- }
-
- internal virtual CodeExpression BuildInvokeAsync (string messageName, CodeArrayCreateExpression paramsArray, CodeExpression delegateField, CodeExpression userStateVar)
- {
- CodeThisReferenceExpression ethis = new CodeThisReferenceExpression();
- CodeMethodInvokeExpression inv2 = new CodeMethodInvokeExpression (ethis, "InvokeAsync");
- inv2.Parameters.Add (new CodePrimitiveExpression (messageName));
- inv2.Parameters.Add (paramsArray);
- inv2.Parameters.Add (delegateField);
- inv2.Parameters.Add (userStateVar);
- return inv2;
- }
- #endif
-
- [MonoTODO]
- public void AddExtensionWarningComments (CodeCommentStatementCollection comments, ServiceDescriptionFormatExtensionCollection extensions)
- {
- throw new NotImplementedException ();
- }
- protected abstract CodeTypeDeclaration BeginClass ();
- protected virtual void BeginNamespace ()
- {
- }
- protected virtual void EndClass ()
- {
- }
- protected virtual void EndNamespace ()
- {
- }
- protected abstract CodeMemberMethod GenerateMethod ();
- protected abstract bool IsBindingSupported ();
- protected abstract bool IsOperationFlowSupported (OperationFlow flow);
-
- [MonoTODO]
- public Exception OperationBindingSyntaxException (string text)
- {
- throw new NotImplementedException ();
- }
- [MonoTODO]
- public Exception OperationSyntaxException (string text)
- {
- throw new NotImplementedException ();
- }
- public void UnsupportedBindingWarning (string text)
- {
- warnings |= ServiceDescriptionImportWarnings.UnsupportedBindingsIgnored;
- AddGlobalComments ("WARNING: Could not generate proxy for binding " + binding.Name + ". " + text);
- }
- public void UnsupportedOperationBindingWarning (string text)
- {
- warnings |= ServiceDescriptionImportWarnings.UnsupportedOperationsIgnored;
- AddGlobalComments ("WARNING: Could not generate operation " + OperationBinding.Name + ". " + text);
- }
- public void UnsupportedOperationWarning (string text)
- {
- warnings |= ServiceDescriptionImportWarnings.UnsupportedOperationsIgnored;
- AddGlobalComments ("WARNING: Could not generate operation " + OperationBinding.Name + ". " + text);
- }
- void AddGlobalComments (string comments)
- {
- codeNamespace.Comments.Add (new CodeCommentStatement (comments, false));
- }
- void AddComments (CodeTypeMember member, string comments)
- {
- if (comments == null || comments == "") member.Comments.Add (new CodeCommentStatement ("<remarks/>", true));
- else member.Comments.Add (new CodeCommentStatement ("<remarks>\n" + comments + "\n</remarks>", true));
- }
- void AddCodeType (CodeTypeDeclaration type, string comments)
- {
- AddComments (type, comments);
- codeNamespace.Types.Add (type);
- }
- internal void AddCustomAttribute (CodeTypeMember ctm, CodeAttributeDeclaration att, bool addIfNoParams)
- {
- if (att.Arguments.Count == 0 && !addIfNoParams) return;
-
- if (ctm.CustomAttributes == null) ctm.CustomAttributes = new CodeAttributeDeclarationCollection ();
- ctm.CustomAttributes.Add (att);
- }
- internal void AddCustomAttribute (CodeTypeMember ctm, string name, params CodeAttributeArgument[] args)
- {
- if (ctm.CustomAttributes == null) ctm.CustomAttributes = new CodeAttributeDeclarationCollection ();
- ctm.CustomAttributes.Add (new CodeAttributeDeclaration (name, args));
- }
- internal CodeAttributeArgument GetArg (string name, object value)
- {
- return new CodeAttributeArgument (name, new CodePrimitiveExpression(value));
- }
- internal CodeAttributeArgument GetEnumArg (string name, string enumType, string enumValue)
- {
- return new CodeAttributeArgument (name, new CodeFieldReferenceExpression (new CodeTypeReferenceExpression(enumType), enumValue));
- }
- internal CodeAttributeArgument GetArg (object value)
- {
- return new CodeAttributeArgument (new CodePrimitiveExpression(value));
- }
- internal CodeAttributeArgument GetTypeArg (string name, string typeName)
- {
- return new CodeAttributeArgument (name, new CodeTypeOfExpression(typeName));
- }
-
- #endregion
- }
- }
|