3 using System
.CodeDom
.Compiler
;
5 using System
.Reflection
;
6 using System
.ServiceModel
;
7 using System
.ServiceModel
.Channels
;
8 using System
.ServiceModel
.Description
;
9 using System
.ServiceModel
.Dispatcher
;
10 using System
.Collections
.ObjectModel
;
12 using System
.Xml
.Schema
;
13 using System
.Xml
.Serialization
;
14 using System
.Web
.Services
;
15 using System
.Web
.Services
.Discovery
;
17 using System
.Collections
.Generic
;
18 using System
.Runtime
.Serialization
;
20 using WSServiceDescrition
= System
.Web
.Services
.Description
.ServiceDescription
;
22 namespace Mono
.ServiceContractTool
26 public static void Main (string [] args
)
28 new Driver ().Run (args
);
31 CommandLineOptions co
= new CommandLineOptions ();
32 ServiceContractGenerator generator
;
33 CodeDomProvider code_provider
;
35 void Run (string [] args
)
37 co
.ProcessArgs (args
);
48 if (co
.Help
|| co
.RemainingArguments
.Count
== 0) {
55 CodeCompileUnit ccu
= new CodeCompileUnit ();
56 CodeNamespace cns
= new CodeNamespace (co
.Namespace
);
57 ccu
.Namespaces
.Add (cns
);
59 generator
= new ServiceContractGenerator (ccu
);
60 generator
.Options
= GetGenerationOption ();
61 generator
.Options
|=ServiceContractGenerationOptions
.ChannelInterface
;
63 code_provider
= GetCodeProvider ();
64 MetadataSet metadata
= null;
66 // For now only assemblyPath is supported.
67 foreach (string arg
in co
.RemainingArguments
) {
69 if (Uri
.TryCreate (arg
, UriKind
.Absolute
, out uri
)) {
70 metadata
= ResolveWithDisco (arg
);
72 metadata
= ResolveWithWSMex (arg
);
77 FileInfo fi
= new FileInfo (arg
);
79 switch (fi
.Extension
) {
82 GenerateContractType (fi
.FullName
);
85 throw new NotSupportedException ("Not supported file extension: " + fi
.Extension
);
92 List
<IWsdlImportExtension
> list
= new List
<IWsdlImportExtension
> ();
93 list
.Add (new TransportBindingElementImporter ());
94 //list.Add (new DataContractSerializerMessageContractImporter ());
95 list
.Add (new XmlSerializerMessageContractImporter ());
97 //WsdlImporter importer = new WsdlImporter (metadata, null, list);
98 WsdlImporter importer
= new WsdlImporter (metadata
);
99 //ServiceEndpointCollection endpoints = importer.ImportAllEndpoints ();
101 Console
.WriteLine ("Generating files..");
102 /*foreach (ServiceEndpoint se in endpoints)
103 generator.GenerateServiceContractType (se.Contract);*/
105 Collection
<ContractDescription
> contracts
= importer
.ImportAllContracts ();
106 foreach (ContractDescription cd
in contracts
) {
107 if (co
.GenerateMoonlightProxy
) {
108 var moonctx
= new MoonlightChannelBaseContext ();
109 cd
.Behaviors
.Add (new MoonlightChannelBaseContractExtension (moonctx
, co
.GenerateMonoTouchProxy
));
110 foreach (var od
in cd
.Operations
)
111 od
.Behaviors
.Add (new MoonlightChannelBaseOperationExtension (moonctx
, co
.GenerateMonoTouchProxy
));
112 generator
.GenerateServiceContractType (cd
);
116 generator
.GenerateServiceContractType (cd
);
119 /*if (cns.Types.Count == 0) {
120 Console.Error.WriteLine ("Argument assemblies have no types.");
121 Environment.Exit (1);
124 //FIXME: Generate .config
126 Console
.WriteLine (GetOutputFilename ());
127 using (TextWriter w
= File
.CreateText (GetOutputFilename ())) {
128 code_provider
.GenerateCodeFromCompileUnit (ccu
, w
, null);
132 MetadataSet
ResolveWithDisco (string url
)
134 DiscoveryClientProtocol prot
= null;
135 Console
.WriteLine ("\nAttempting to download metadata from '{0}' using DISCO..", url
);
137 prot
= new DiscoveryClientProtocol ();
138 prot
.DiscoverAny (url
);
140 } catch (Exception e
) {
141 Console
.WriteLine ("Disco failed for the url '{0}' with exception :\n {1}", url
, e
.Message
);
145 if (prot
.References
.Count
> 0)
147 Console
.WriteLine ("Disco found documents at the following URLs:");
148 foreach (DiscoveryReference refe
in prot
.References
.Values
)
150 if (refe
is ContractReference
) Console
.Write ("- WSDL document at ");
151 else if (refe
is DiscoveryDocumentReference
) Console
.Write ("- DISCO document at ");
152 else Console
.Write ("- Xml Schema at ");
153 Console
.WriteLine (refe
.Url
);
156 Console
.WriteLine ("Disco didn't find any document at the specified URL");
160 MetadataSet metadata
= new MetadataSet ();
161 foreach (object o
in prot
.Documents
.Values
) {
162 if (o
is WSServiceDescrition
) {
163 metadata
.MetadataSections
.Add (
164 new MetadataSection (MetadataSection
.ServiceDescriptionDialect
, "", (WSServiceDescrition
) o
));
166 if (o
is XmlSchema
) {
167 metadata
.MetadataSections
.Add (
168 new MetadataSection (MetadataSection
.XmlSchemaDialect
, "", (XmlSchema
) o
));
175 MetadataSet
ResolveWithWSMex (string url
)
177 MetadataSet metadata
= null;
179 MetadataExchangeClient client
= new MetadataExchangeClient (new EndpointAddress (url
));
181 Console
.WriteLine ("\nAttempting to download metadata from {0} using WS-MetadataExchange..", url
);
182 metadata
= client
.GetMetadata ();
183 } catch (InvalidOperationException e
) {
184 //MetadataExchangeClient wraps exceptions, thrown while
185 //fetching the metadata, in an InvalidOperationException
187 if (e
.InnerException
== null)
190 msg
= e
.InnerException
.ToString ();
192 Console
.WriteLine ("WS-MetadataExchange query failed for the url '{0}' with exception :\n {1}",
199 CodeDomProvider
GetCodeProvider ()
201 switch (co
.Language
) {
204 return new Microsoft
.CSharp
.CSharpCodeProvider ();
206 return new Microsoft
.VisualBasic
.VBCodeProvider ();
208 throw new NotSupportedException ();
212 void GenerateContractType (string file
)
214 Assembly ass
= Assembly
.LoadFile (file
);
215 foreach (Module m
in ass
.GetModules ())
216 foreach (Type t
in m
.GetTypes ())
220 void ProcessType (Type type
)
222 object [] a
= type
.GetCustomAttributes (
223 typeof (ServiceContractAttribute
), true);
225 generator
.GenerateServiceContractType (
226 ContractDescription
.GetContract (type
));
229 ServiceContractGenerationOptions
GetGenerationOption ()
231 ServiceContractGenerationOptions go
=
232 ServiceContractGenerationOptions
.ClientClass
;
233 if (co
.GenerateAsync
)
234 go
|= ServiceContractGenerationOptions
.AsynchronousMethods
;
235 if (co
.ChannelInterface
)
236 go
|= ServiceContractGenerationOptions
.ChannelInterface
;
237 if (co
.GenerateTypesAsInternal
)
238 go
|= ServiceContractGenerationOptions
.InternalTypes
;
239 if (co
.GenerateProxy
)
240 go
|= ServiceContractGenerationOptions
.ClientClass
;
241 if (co
.GenerateTypedMessages
)
242 go
|= ServiceContractGenerationOptions
.TypedMessages
;
243 if ((co
.TargetClientVersion35
&& co
.GenerateAsync
) || co
.GenerateMoonlightProxy
)
244 go
|= ServiceContractGenerationOptions
.EventBasedAsynchronousMethods
;
249 string GetOutputFilename ()
251 if (co
.OutputFilename
!= null)
252 return co
.OutputFilename
;
253 return "output." + code_provider
.FileExtension
;