2 // System.Web.Services.Description.ProtocolImporter.cs
5 // Tim Coleman (tim@timcoleman.com)
6 // Lluis Sanchez Gual (lluis@ximian.com)
8 // Copyright (C) Tim Coleman, 2002
13 using System.Web.Services;
14 using System.Web.Services.Protocols;
15 using System.Xml.Serialization;
17 using System.Collections;
18 using System.Configuration;
20 namespace System.Web.Services.Description {
21 public abstract class ProtocolImporter {
27 CodeIdentifiers classNames;
28 CodeNamespace codeNamespace;
29 CodeCompileUnit codeCompileUnit;
30 CodeTypeDeclaration codeTypeDeclaration;
34 OperationBinding operationBinding;
35 Message outputMessage;
40 ServiceDescriptionImportWarnings warnings = (ServiceDescriptionImportWarnings)0;
41 ServiceDescriptionImporter descriptionImporter;
48 protected ProtocolImporter ()
52 #endregion // Constructors
57 public XmlSchemas AbstractSchemas {
58 get { return descriptionImporter.Schemas; }
61 public Binding Binding {
62 get { return binding; }
65 public string ClassName {
66 get { return className; }
69 public CodeIdentifiers ClassNames {
70 get { return classNames; }
73 public CodeNamespace CodeNamespace {
74 get { return codeNamespace; }
77 public CodeTypeDeclaration CodeTypeDeclaration {
78 get { return codeTypeDeclaration; }
82 public XmlSchemas ConcreteSchemas {
83 get { return descriptionImporter.Schemas; }
86 public Message InputMessage {
87 get { return inputMessage; }
90 public string MethodName {
91 get { return methodName; }
94 public Operation Operation {
95 get { return operation; }
98 public OperationBinding OperationBinding {
99 get { return operationBinding; }
102 public Message OutputMessage {
103 get { return outputMessage; }
110 public PortType PortType {
111 get { return portType; }
114 public abstract string ProtocolName {
118 public XmlSchemas Schemas {
119 get { return descriptionImporter.Schemas; }
122 public Service Service {
123 get { return service; }
126 public ServiceDescriptionCollection ServiceDescriptions {
127 get { return descriptionImporter.ServiceDescriptions; }
130 public ServiceDescriptionImportStyle Style {
131 get { return descriptionImporter.Style; }
134 public ServiceDescriptionImportWarnings Warnings {
135 get { return warnings; }
136 set { warnings = value; }
139 internal ImportInfo ImportInfo
141 get { return iinfo; }
144 #endregion // Properties
148 internal bool Import (ServiceDescriptionImporter descriptionImporter, CodeNamespace codeNamespace, CodeCompileUnit codeCompileUnit, ArrayList importInfo)
150 this.descriptionImporter = descriptionImporter;
151 this.classNames = new CodeIdentifiers();;
152 this.codeNamespace = codeNamespace;
153 this.codeCompileUnit = codeCompileUnit;
155 warnings = (ServiceDescriptionImportWarnings) 0;
161 foreach (ImportInfo info in importInfo)
163 foreach (Service service in info.ServiceDescription.Services)
165 this.service = service;
166 foreach (Port port in service.Ports)
170 binding = ServiceDescriptions.GetBinding (port.Binding);
171 if (!IsBindingSupported ()) continue;
174 ImportPortBinding ();
184 void ImportPortBinding ()
186 if (service.Ports.Count > 1) className = port.Name;
187 else className = service.Name;
189 className = classNames.AddUnique (CodeIdentifier.MakeValid (className), port);
193 portType = ServiceDescriptions.GetPortType (binding.Type);
194 if (portType == null) throw new Exception ("Port type not found: " + binding.Type);
196 CodeTypeDeclaration codeClass = BeginClass ();
197 codeTypeDeclaration = codeClass;
198 AddCodeType (codeClass, port.Documentation);
199 codeClass.Attributes = MemberAttributes.Public;
201 if (service.Documentation != null && service.Documentation != "")
202 AddComments (codeClass, service.Documentation);
204 CodeAttributeDeclaration att = new CodeAttributeDeclaration ("System.Diagnostics.DebuggerStepThroughAttribute");
205 AddCustomAttribute (codeClass, att, true);
207 att = new CodeAttributeDeclaration ("System.ComponentModel.DesignerCategoryAttribute");
208 att.Arguments.Add (GetArg ("code"));
209 AddCustomAttribute (codeClass, att, true);
211 if (binding.Operations.Count == 0) {
212 warnings |= ServiceDescriptionImportWarnings.NoMethodsGenerated;
216 foreach (OperationBinding oper in binding.Operations)
218 operationBinding = oper;
219 operation = FindPortOperation ();
220 if (operation == null) throw new Exception ("Operation " + operationBinding.Name + " not found in portType " + PortType.Name);
222 foreach (OperationMessage omsg in operation.Messages)
224 Message msg = ServiceDescriptions.GetMessage (omsg.Message);
225 if (msg == null) throw new Exception ("Message not found: " + omsg.Message);
227 if (omsg is OperationInput)
233 CodeMemberMethod method = GenerateMethod ();
237 methodName = method.Name;
238 if (operation.Documentation != null && operation.Documentation != "")
239 AddComments (method, operation.Documentation);
247 warnings |= ServiceDescriptionImportWarnings.NoCodeGenerated;
248 UnsupportedBindingWarning (ex.Message);
252 Operation FindPortOperation ()
254 string inMessage = (operationBinding.Input.Name != "") ? operationBinding.Input.Name : operationBinding.Name;
255 string outMessage = (operationBinding.Output.Name != "") ? operationBinding.Output.Name : operationBinding.Name;
256 string operName = operationBinding.Name;
258 foreach (Operation oper in PortType.Operations)
260 if (oper.Name == operName)
263 foreach (OperationMessage omsg in oper.Messages)
265 if (omsg is OperationInput && GetOperMessageName (omsg, operName) == inMessage) hits++;
266 if (omsg is OperationOutput && GetOperMessageName (omsg, operName) == outMessage) hits++;
268 if (hits == 2) return oper;
274 string GetOperMessageName (OperationMessage msg, string operName)
276 if (msg.Name == null) return operName;
277 else return msg.Name;
280 internal string GetServiceUrl (string location)
282 if (ImportInfo.AppSettingUrlKey == null || ImportInfo.AppSettingUrlKey == string.Empty)
287 if (Style == ServiceDescriptionImportStyle.Server) throw new InvalidOperationException ("Cannot set appSettingUrlKey if Style is Server");
288 url = ConfigurationSettings.AppSettings [ImportInfo.AppSettingUrlKey];
289 if (ImportInfo.AppSettingBaseUrl != null && ImportInfo.AppSettingBaseUrl != string.Empty)
290 url += "/" + ImportInfo.AppSettingBaseUrl + "/" + location;
297 public void AddExtensionWarningComments (CodeCommentStatementCollection comments, ServiceDescriptionFormatExtensionCollection extensions)
299 throw new NotImplementedException ();
302 protected abstract CodeTypeDeclaration BeginClass ();
304 protected virtual void BeginNamespace ()
308 protected virtual void EndClass ()
312 protected virtual void EndNamespace ()
316 protected abstract CodeMemberMethod GenerateMethod ();
317 protected abstract bool IsBindingSupported ();
318 protected abstract bool IsOperationFlowSupported (OperationFlow flow);
321 public Exception OperationBindingSyntaxException (string text)
323 throw new NotImplementedException ();
327 public Exception OperationSyntaxException (string text)
329 throw new NotImplementedException ();
332 public void UnsupportedBindingWarning (string text)
334 AddGlobalComments ("WARNING: Could not generate proxy for binding " + binding.Name + ". " + text);
337 public void UnsupportedOperationBindingWarning (string text)
339 AddGlobalComments ("WARNING: Could not generate operation " + OperationBinding.Name + ". " + text);
342 public void UnsupportedOperationWarning (string text)
344 AddGlobalComments ("WARNING: Could not generate operation " + OperationBinding.Name + ". " + text);
347 void AddGlobalComments (string comments)
349 codeNamespace.Comments.Add (new CodeCommentStatement (comments, false));
352 void AddComments (CodeTypeMember member, string comments)
354 if (comments == null || comments == "") member.Comments.Add (new CodeCommentStatement ("<remarks/>", true));
355 else member.Comments.Add (new CodeCommentStatement ("<remarks>\n" + comments + "\n</remarks>", true));
358 void AddCodeType (CodeTypeDeclaration type, string comments)
360 AddComments (type, comments);
361 codeNamespace.Types.Add (type);
364 internal void AddCustomAttribute (CodeTypeMember ctm, CodeAttributeDeclaration att, bool addIfNoParams)
366 if (att.Arguments.Count == 0 && !addIfNoParams) return;
368 if (ctm.CustomAttributes == null) ctm.CustomAttributes = new CodeAttributeDeclarationCollection ();
369 ctm.CustomAttributes.Add (att);
372 internal void AddCustomAttribute (CodeTypeMember ctm, string name, params CodeAttributeArgument[] args)
374 if (ctm.CustomAttributes == null) ctm.CustomAttributes = new CodeAttributeDeclarationCollection ();
375 ctm.CustomAttributes.Add (new CodeAttributeDeclaration (name, args));
378 internal CodeAttributeArgument GetArg (string name, object value)
380 return new CodeAttributeArgument (name, new CodePrimitiveExpression(value));
383 internal CodeAttributeArgument GetEnumArg (string name, string enumType, string enumValue)
385 return new CodeAttributeArgument (name, new CodeFieldReferenceExpression (new CodeTypeReferenceExpression(enumType), enumValue));
388 internal CodeAttributeArgument GetArg (object value)
390 return new CodeAttributeArgument (new CodePrimitiveExpression(value));
393 internal CodeAttributeArgument GetTypeArg (string name, string typeName)
395 return new CodeAttributeArgument (name, new CodeTypeOfExpression(typeName));