1 |
|
/* -*- csharp -*- mode please |
2 |
|
* |
3 |
|
* C# Webservice to DGMX conversion |
4 |
|
* |
5 |
|
* Copyright (C) 2001, 2003 Southern Storm Software, Pty Ltd. |
6 |
|
* |
7 |
|
* This program is free software; you can redistribute it and/or modify |
8 |
|
* it under the terms of the GNU General Public License as published by |
9 |
|
* the Free Software Foundation; either version 2 of the License, or |
10 |
|
* (at your option) any later version. |
11 |
|
* |
12 |
|
* This program is distributed in the hope that it will be useful, |
13 |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 |
|
* GNU General Public License for more details. |
16 |
|
* |
17 |
|
* You should have received a copy of the GNU General Public License |
18 |
|
* along with this program; if not, write to the Free Software |
19 |
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
20 |
|
* |
21 |
|
* Authors: |
22 |
|
* Adam Ballai |
23 |
|
* Chris Smith |
24 |
|
* Nicolai P Guba |
25 |
|
* |
26 |
|
* $Revision$ |
27 |
|
*/ |
28 |
|
|
29 |
|
using System; |
30 |
|
using System.Reflection; |
31 |
|
using System.Web; |
32 |
|
using System.Web.Services; |
33 |
|
using DotGNU.XmlRpc; |
34 |
|
using System.Xml; |
35 |
|
using System.Text; |
36 |
|
using System.IO; |
37 |
|
|
38 |
|
public class Options |
39 |
|
{ |
40 |
|
private bool verbose = false; |
41 |
|
private bool help = false; |
42 |
|
|
43 |
|
public bool Verbose |
44 |
|
{ |
45 |
|
set { |
46 |
|
verbose = value; |
47 |
|
} |
48 |
|
get { |
49 |
|
return verbose; |
50 |
|
} |
51 |
|
} |
52 |
|
|
53 |
|
public bool Help |
54 |
|
{ |
55 |
|
set { |
56 |
|
help = value; |
57 |
|
} |
58 |
|
get { |
59 |
|
return help; |
60 |
|
} |
61 |
|
} |
62 |
|
} |
63 |
|
|
64 |
|
public class CSWS2Dgmx |
65 |
|
{ |
66 |
|
private XmlTextWriter writer; |
67 |
|
private String inputFile; |
68 |
|
private Options opt = new Options(); |
69 |
|
|
70 |
|
|
71 |
|
internal String type_mapping( Type cs_type ) |
72 |
|
{ |
73 |
|
String type; |
74 |
|
|
75 |
|
type = "unsupported"; |
76 |
|
|
77 |
|
switch( (type = cs_type.ToString()) ) |
78 |
|
{ |
79 |
|
case "System.String": type = "string"; break; |
80 |
|
case "System.Int32" : type = "int"; break; |
81 |
|
case "System.Int64" : /* unsupported */ break; |
82 |
|
case "System.Double": type = "double"; break; |
83 |
|
case "System.Single": type = "double"; break; |
84 |
|
case "System.Bool" : type = "boolean"; break; |
85 |
|
|
86 |
|
default: break; |
87 |
|
|
88 |
|
} |
89 |
|
return type; |
90 |
|
} |
91 |
|
|
92 |
|
internal int ProcessMethod(Attribute attr, |
93 |
|
MethodInfo method) |
94 |
|
{ |
95 |
|
int count = 0; |
96 |
|
|
97 |
|
if( opt.Verbose ) { |
98 |
|
Console.Write( "[{0}] ", method.Name ); |
99 |
|
} |
100 |
|
|
101 |
|
// Arrrgh arrrgh arRRRRRRRGHHHHHHHHH... the Writer has a concept |
102 |
|
// of indentation but absulutely NO clue about newlines. |
103 |
|
// Nooooooooooo! npg |
104 |
|
writer.WriteStartElement("method"); |
105 |
|
writer.WriteAttributeString("name", method.Name); |
106 |
|
writer.WriteAttributeString("common", ((WebMethodAttribute)attr).Method); |
107 |
|
writer.WriteStartElement("description"); |
108 |
|
writer.WriteString(((WebMethodAttribute)attr).Description); |
109 |
|
writer.WriteEndElement(); |
110 |
|
writer.WriteStartElement("interface"); |
111 |
|
writer.WriteStartElement("parameters"); |
112 |
|
|
113 |
|
|
114 |
|
ParameterInfo []pinfos=method.GetParameters(); |
115 |
|
|
116 |
|
foreach(ParameterInfo pinfo in pinfos) { |
117 |
|
writer.WriteStartElement("parameter"); |
118 |
|
writer.WriteAttributeString("order", pinfo.Position.ToString()); |
119 |
|
writer.WriteAttributeString("name", pinfo.Name); |
120 |
|
writer.WriteAttributeString("type", type_mapping(pinfo.ParameterType)); |
121 |
|
writer.WriteEndElement(); // end parameter |
122 |
|
} |
123 |
|
writer.WriteEndElement(); // end parameters |
124 |
|
|
125 |
|
writer.WriteStartElement("return"); |
126 |
|
writer.WriteAttributeString("type", |
127 |
|
type_mapping(method.ReturnType)); |
128 |
|
writer.WriteEndElement(); // end return |
129 |
|
|
130 |
|
writer.WriteEndElement(); // end interface |
131 |
|
writer.WriteEndElement(); // end method |
132 |
|
|
133 |
|
count++; |
134 |
|
return count; |
135 |
|
} |
136 |
|
|
137 |
|
|
138 |
|
internal WebServiceAttribute GetServiceAttribute(Type type) |
139 |
|
{ |
140 |
|
Attribute[] attrs = Attribute.GetCustomAttributes(type |
141 |
|
,typeof(WebServiceAttribute) |
142 |
|
,false); |
143 |
|
if(attrs==null) |
144 |
|
{ |
145 |
|
return null; |
146 |
|
} |
147 |
|
if(attrs.Length==1) |
148 |
|
{ |
149 |
|
return (WebServiceAttribute)attrs[0]; |
150 |
|
} |
151 |
|
return null; |
152 |
|
} |
153 |
|
|
154 |
|
internal WebMethodAttribute GetAttribute(MethodInfo method) |
155 |
|
{ |
156 |
|
Attribute[] attrs = Attribute.GetCustomAttributes( method |
157 |
|
,typeof(WebMethodAttribute) |
158 |
|
,false); |
159 |
|
if(attrs==null) |
160 |
|
{ |
161 |
|
return null; |
162 |
|
} |
163 |
|
if(attrs.Length==1) |
164 |
|
{ |
165 |
|
return (WebMethodAttribute)attrs[0]; |
166 |
|
} |
167 |
|
return null; |
168 |
|
} |
169 |
|
|
170 |
|
|
171 |
|
internal int ProcessType(Type type) |
172 |
|
{ |
173 |
|
String desc; |
174 |
|
String ns; |
175 |
|
int count = 0; |
176 |
|
|
177 |
|
Attribute attr = GetServiceAttribute(type); |
178 |
|
if(attr!=null) |
179 |
|
{ |
180 |
|
desc = ((WebServiceAttribute)attr).Description; |
181 |
|
ns = ((WebServiceAttribute)attr).Namespace; |
182 |
|
if(ns == null) { ns = "http://tempuri.org"; }; |
183 |
|
} |
184 |
|
|
185 |
|
if( opt.Verbose ) { |
186 |
|
Console.Write( "Processing {0}: ", type.ToString() ); |
187 |
|
} |
188 |
|
|
189 |
|
writer.WriteStartElement("class"); |
190 |
|
writer.WriteAttributeString("name", type.ToString()); |
191 |
|
writer.WriteStartElement("description"); |
192 |
|
writer.WriteString(desc); |
193 |
|
writer.WriteEndElement(); |
194 |
|
writer.WriteStartElement("namespace"); |
195 |
|
writer.WriteString(ns); |
196 |
|
writer.WriteEndElement(); |
197 |
|
|
198 |
|
|
199 |
|
//MethodInfo []methods = type.GetMethods( BindingFlags.Public |
200 |
|
// | BindingFlags.Static); |
201 |
|
MethodInfo []methods = type.GetMethods(); |
202 |
|
foreach(MethodInfo method in methods) |
203 |
|
{ |
204 |
|
Attribute attr = GetAttribute(method); |
205 |
|
if(attr!=null) |
206 |
|
{ |
207 |
|
count += ProcessMethod(attr,method); |
208 |
|
} |
209 |
|
} |
210 |
|
|
211 |
|
writer.WriteEndElement(); // end class |
212 |
|
if( opt.Verbose ) { |
213 |
|
Console.WriteLine(""); |
214 |
|
} |
215 |
|
|
216 |
|
return count; |
217 |
|
} |
218 |
|
|
219 |
|
internal void CreateOwnership( ) |
220 |
|
{ |
221 |
|
writer.WriteStartElement("ID"); |
222 |
|
writer.WriteAttributeString("type","SHA1"); |
223 |
|
writer.WriteString("ca50913940cccac9dc69e258a3381f40cfad6607"); |
224 |
|
writer.WriteEndElement(); |
225 |
|
writer.WriteStartElement("owner"); |
226 |
|
writer.WriteStartElement("name"); |
227 |
|
writer.WriteString("Chris Smith"); |
228 |
|
writer.WriteEndElement(); |
229 |
|
writer.WriteStartElement("publicKey"); |
230 |
|
writer.WriteAttributeString("type","RSA"); |
231 |
|
writer.WriteString("\n-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDnR7nAKavHmmj7BqSmrsCliOA1\ngvBfArAEp1p24sT+8zEoWKQdhe9byEUcNDfdhYik7xcAqGqzVksYSf/wQQC6ie6t\nFrc+hwam28yT17juNTBWDkJ01GWzbGCJePeUdTw3hbOVrm+iznvTaQP+QxxLX5sW\n1KqmxEYMabC67Eq9NQIDAQAB\n-----END PUBLIC KEY-----\n"); |
232 |
|
writer.WriteEndElement(); // end publicKey |
233 |
|
writer.WriteStartElement("creationDate"); |
234 |
|
writer.WriteString("04-12-2002T21:20:02"); |
235 |
|
writer.WriteEndElement(); // end creationDate |
236 |
|
writer.WriteEndElement(); // end owner |
237 |
|
} |
238 |
|
|
239 |
|
internal void CreateCertification( ) |
240 |
|
{ |
241 |
|
writer.WriteStartElement("certification"); |
242 |
|
writer.WriteEndElement(); // end certification |
243 |
|
} |
244 |
|
|
245 |
|
internal int ProcessDll(String dllName) |
246 |
|
{ |
247 |
|
int done = 0; |
248 |
|
|
249 |
|
dllName = Path.GetFullPath(dllName); |
250 |
|
String prefix = Path.GetFileNameWithoutExtension(dllName); |
251 |
|
FileStream fs = new FileStream( prefix + ".dgmx", FileMode.Create ); |
252 |
|
|
253 |
|
writer = new XmlTextWriter( fs, Encoding.ASCII ); |
254 |
|
writer.Formatting = System.Xml.Formatting.Indented; // arrgh the indented output from that writer is awwwful |
255 |
|
|
256 |
|
if( opt.Verbose ) { |
257 |
|
Console.WriteLine( "Scanning assembly '{0}'", dllName ); |
258 |
|
} |
259 |
|
|
260 |
|
Assembly ass = Assembly.LoadFrom(dllName); |
261 |
|
writer.WriteStartDocument(); |
262 |
|
writer.WriteStartElement("container"); |
263 |
|
writer.WriteAttributeString("name", prefix); |
264 |
|
writer.WriteAttributeString("language", "C#"); |
265 |
|
|
266 |
|
CreateOwnership(); |
267 |
|
CreateCertification(); |
268 |
|
|
269 |
|
Type[] types=ass.GetTypes(); |
270 |
|
|
271 |
|
foreach(Type type in types) { |
272 |
|
if(type.ToString()!="<Module>") done += ProcessType(type); |
273 |
|
} |
274 |
|
|
275 |
|
writer.WriteEndElement(); |
276 |
|
|
277 |
|
writer.Flush(); |
278 |
|
writer.Close(); |
279 |
|
|
280 |
|
if( opt.Verbose ) { |
281 |
|
Console.WriteLine( "\n{0} exported methods found.", done ); |
282 |
|
Console.WriteLine( "Output written to {0}", prefix+".dgmx" ); |
283 |
|
} |
284 |
|
|
285 |
|
return done; |
286 |
|
} |
287 |
|
|
288 |
|
internal void printHelp () |
289 |
|
{ |
290 |
|
Console.WriteLine( "Usage: csdgmx [OPTION]... FILENAME.DLL"); |
291 |
|
Console.WriteLine( "Generates a Webservice Description file Webservice FILENAME.DLL"); |
292 |
|
Console.WriteLine(); |
293 |
|
Console.WriteLine( " -v verbose output"); |
294 |
|
Console.WriteLine( " -h print help and exit"); |
295 |
|
Console.WriteLine(); |
296 |
|
Console.WriteLine( "Report bugs to <developers@dotgnu.org>"); |
297 |
|
} |
298 |
|
|
299 |
|
internal void MainLoop() |
300 |
|
{ |
301 |
|
int done; |
302 |
|
|
303 |
|
if( opt.Help ) { |
304 |
|
printHelp(); |
305 |
|
return; |
306 |
|
} |
307 |
|
|
308 |
|
if( opt.Verbose ) { |
309 |
|
Console.WriteLine( "DotGNU Execution Environment" ); |
310 |
|
Console.WriteLine( "Client Generation tool - (c)2003 netFluid Technology Ltd" ); |
311 |
|
Console.WriteLine( "And (c)2003 Adam Ballai, Cannibutter Software"); |
312 |
|
Console.WriteLine( "And (c)2003 Nicolai P Guba, dotGNU Project"); |
313 |
|
Console.WriteLine( "\nThis software comes with ABSOLUTELY NO WARRANTY. This is free software," ); |
314 |
|
Console.WriteLine( "and you are welcome to modify and redistribute it under the GPL licence.\n"); |
315 |
|
} |
316 |
|
|
317 |
|
try { |
318 |
|
if( inputFile != null ) { |
319 |
|
|
320 |
|
done = ProcessDll( inputFile ); |
321 |
|
if( done == 0 ) { |
322 |
|
Console.WriteLine( "No Exportable information found!!!" ); |
323 |
|
} |
324 |
|
} |
325 |
|
else { |
326 |
|
Console.WriteLine( "No input file given: Please supply the DLL of a WebService" ); |
327 |
|
} |
328 |
|
} |
329 |
|
catch (FileNotFoundException e) { |
330 |
|
Console.WriteLine( "{0}: File Not Found", inputFile ); |
331 |
|
} |
332 |
|
} |
333 |
|
|
334 |
|
internal void ProcessArgs(String []args) |
335 |
|
{ |
336 |
|
foreach(String arg in args) { |
337 |
|
// Check for command line parameters here (is there a getopt for |
338 |
|
// c# ????) |
339 |
|
switch (arg) { |
340 |
|
case "-v": |
341 |
|
opt.Verbose = true; |
342 |
|
break; |
343 |
|
|
344 |
|
case "-h": |
345 |
|
opt.Help = true; |
346 |
|
break; |
347 |
|
|
348 |
|
default: |
349 |
|
if( arg.EndsWith( ".dll" ) ) { |
350 |
|
inputFile = arg; |
351 |
|
} |
352 |
|
else { |
353 |
|
Console.WriteLine( "{0}: Invalid argument or file name", arg); |
354 |
|
} |
355 |
|
break; |
356 |
|
} |
357 |
|
} |
358 |
|
} |
359 |
|
|
360 |
|
public static void Main(String []args) |
361 |
|
{ |
362 |
|
CSWS2Dgmx dd = new CSWS2Dgmx(); |
363 |
|
dd.ProcessArgs(args); |
364 |
|
dd.MainLoop(); |
365 |
|
} |
366 |
|
} |