KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > taskdefs > optional > dotnet > WsdlToDotnet


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */

18 package org.apache.tools.ant.taskdefs.optional.dotnet;
19
20 import java.io.File JavaDoc;
21 import java.util.Vector JavaDoc;
22 import java.util.Iterator JavaDoc;
23 import java.net.MalformedURLException JavaDoc;
24
25 import org.apache.tools.ant.BuildException;
26 import org.apache.tools.ant.Project;
27 import org.apache.tools.ant.Task;
28 import org.apache.tools.ant.types.EnumeratedAttribute;
29 import org.apache.tools.ant.taskdefs.condition.Os;
30 import org.apache.tools.ant.util.FileUtils;
31
32 /**
33  * Converts a WSDL file or URL resource into a .NET language.
34  *
35  * Why add a wrapper to the MS WSDL tool?
36  * So that you can verify that your web services, be they written with Axis or
37  *anyone else's SOAP toolkit, work with .NET clients.
38  *
39  *This task is dependency aware when using a file as a source and destination;
40  *so if you &lt;get&gt; the file (with <code>usetimestamp="true"</code>) then
41  *you only rebuild stuff when the WSDL file is changed. Of course,
42  *if the server generates a new timestamp every time you ask for the WSDL,
43  *this is not enough...use the &lt;filesmatch&gt; &lt;condition&gt; to
44  *to byte for byte comparison against a cached WSDL file then make
45  *the target conditional on that test failing.
46
47  * See "Creating an XML Web Service Proxy", "wsdl.exe" docs in
48  * the framework SDK documentation
49  * @version 0.5
50  * @ant.task category="dotnet"
51  * @since Ant 1.5
52  */

53
54 public class WsdlToDotnet extends Task {
55
56     /**
57      * used for timestamp checking
58      */

59     private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();
60
61     /**
62      * name of output file (required)
63      */

64     private File JavaDoc destFile = null;
65
66     /**
67      * language; defaults to C#
68      */

69     private String JavaDoc language = "CS";
70
71     /**
72      * flag set to true to generate server side skeleton
73      */

74     private boolean server = false;
75
76     /**
77      * namespace
78      */

79     private String JavaDoc namespace = null;
80
81     /**
82      * flag to control action on execution trouble
83      */

84     private boolean failOnError = true;
85
86     // CheckStyle:VisibilityModifier OFF - bc
87
/**
88      * any extra command options?
89      */

90     protected String JavaDoc extraOptions = null;
91
92     // CheckStyle:VisibilityModifier ON
93

94
95     /**
96      * protocol string. Exact value set depends on SOAP stack version.
97      * @since Ant 1.7
98      */

99     private String JavaDoc protocol = null;
100
101     /**
102      * should errors come in an IDE format. This
103      * is WSE only.
104      * @since Ant 1.7
105      */

106     private boolean ideErrors = false;
107
108     /**
109      * filesets of file to compile
110      * @since Ant 1.7
111      */

112     private Vector JavaDoc schemas = new Vector JavaDoc();
113
114     /**
115      * our WSDL file.
116      * @since ant1.7
117      */

118     private Schema wsdl = new Schema();
119
120     /**
121      * compiler
122      * @since ant1.7
123      */

124     private Compiler JavaDoc compiler = null;
125
126     /**
127      * error message: dest file is a directory
128      */

129     public static final String JavaDoc ERROR_DEST_FILE_IS_DIR = "destination file is a directory";
130
131     /**
132      * error message: no dest file
133      */

134     public static final String JavaDoc ERROR_NO_DEST_FILE = "destination file must be specified";
135
136     /**
137      * Name of the file to generate. Required
138      * @param destFile filename
139      */

140     public void setDestFile(File JavaDoc destFile) {
141         this.destFile = destFile;
142     }
143
144     /**
145      * Sets the URL to fetch. Fetching is by wsdl.exe; Ant proxy settings
146      * are ignored; either url or srcFile is required.
147      * @param url url to save
148      */

149
150     public void setUrl(String JavaDoc url) {
151         wsdl.setUrl(url);
152     }
153
154     /**
155      * The local WSDL file to parse; either url or srcFile is required.
156      * @param srcFile WSDL file
157      */

158     public void setSrcFile(File JavaDoc srcFile) {
159         wsdl.setFile(srcFile);
160     }
161
162     /**
163      * set the language; one of "CS", "JS", or "VB"
164      * optional, default is CS for C# source
165      * @param language language to generate
166      */

167     public void setLanguage(String JavaDoc language) {
168         this.language = language;
169     }
170
171     /**
172      * flag to enable server side code generation;
173      * optional, default=false
174      * @param server server-side flag
175      */

176
177     public void setServer(boolean server) {
178         this.server = server;
179     }
180
181     /**
182      * namespace to place the source in.
183      * optional; default ""
184      * @param namespace new namespace
185      */

186     public void setNamespace(String JavaDoc namespace) {
187         this.namespace = namespace;
188     }
189
190     /**
191      * Whether or not a failure should halt the build.
192      * Optional - default is <code>true</code>.
193      * @param failOnError new failure option
194      */

195     public void setFailOnError(boolean failOnError) {
196         this.failOnError = failOnError;
197     }
198
199     /**
200      * Any extra WSDL.EXE options which aren't explicitly
201      * supported by the ant wrapper task; optional
202      *
203      *@param extraOptions The new ExtraOptions value
204      */

205     public void setExtraOptions(String JavaDoc extraOptions) {
206         this.extraOptions = extraOptions;
207     }
208
209     /**
210      * Defines wether errors are machine parseable.
211      * Optional, default=true
212      *
213      * @since Ant 1.7
214      * @param ideErrors a <code>boolean</code> value.
215      */

216     public void setIdeErrors(boolean ideErrors) {
217         this.ideErrors = ideErrors;
218     }
219
220     /**
221      * what protocol to use. SOAP, SOAP1.2, HttpPost and HttpGet
222      * are the base options. Different version and implementations may.
223      * offer different options.
224      * @since Ant 1.7
225      *
226      * @param protocol the protocol to use.
227      */

228     public void setProtocol(String JavaDoc protocol) {
229         this.protocol = protocol;
230     }
231
232     /**
233      * add a new source schema to the compilation
234      * @since Ant 1.7
235      *
236      * @param source a nested schema element.
237      */

238     public void addSchema(Schema source) {
239         schemas.add(source);
240     }
241
242     /**
243      * flag to trigger turning a filename into a file:url
244      * ignored for the mono compiler.
245      * @param b a <code>boolean</code> value.
246      */

247     public void setMakeURL(boolean b) {
248         wsdl.setMakeURL(b);
249     }
250
251     /**
252      * identify the compiler
253      * @since Ant 1.7
254      * @param compiler the enumerated value.
255      */

256     public void setCompiler(Compiler JavaDoc compiler) {
257         this.compiler = compiler;
258     }
259
260     /**
261      * validation code
262      * @throws BuildException if validation failed
263      */

264     protected void validate()
265             throws BuildException {
266         if (destFile == null) {
267             throw new BuildException(ERROR_NO_DEST_FILE);
268         }
269         if (destFile.isDirectory()) {
270             throw new BuildException(
271                     ERROR_DEST_FILE_IS_DIR);
272         }
273         wsdl.validate();
274     }
275
276     /**
277      * do the work by building the command line and then calling it
278      *
279      *@throws BuildException if validation or execution failed
280      */

281     public void execute()
282              throws BuildException {
283         log("This task is deprecated and will be removed in a future version\n"
284             + "of Ant. It is now part of the .NET Antlib:\n"
285             + "http://ant.apache.org/antlibs/dotnet/index.html",
286             Project.MSG_WARN);
287
288         if (compiler == null) {
289             compiler = Compiler.createDefaultCompiler();
290         }
291         validate();
292         NetCommand command = new NetCommand(this,
293                 "WSDL",
294                 compiler.getCommand());
295         command.setFailOnError(failOnError);
296         //fill in args
297
compiler.applyExtraArgs(command);
298         command.addArgument("/nologo");
299         command.addArgument("/out:" + destFile);
300         command.addArgument("/language:", language);
301         if (server) {
302             command.addArgument("/server");
303         }
304         command.addArgument("/namespace:", namespace);
305         if (protocol != null) {
306             command.addArgument("/protocol:" + protocol);
307         }
308         if (ideErrors) {
309             command.addArgument("/parsableErrors");
310         }
311         command.addArgument(extraOptions);
312
313         //set source and rebuild options
314
boolean rebuild = true;
315         long destLastModified = -1;
316
317         //rebuild unless the dest file is newer than the source file
318
if (destFile.exists()) {
319             destLastModified = destFile.lastModified();
320             rebuild = isRebuildNeeded(wsdl, destLastModified);
321         }
322         String JavaDoc path;
323         //mark for a rebuild if the dest file is newer
324
path = wsdl.evaluate();
325         if (!compiler.supportsAbsoluteFiles() && wsdl.getFile() != null) {
326             // Mono 1.0's wsdl doesn't deal with absolute paths
327
File JavaDoc f = wsdl.getFile();
328             command.setDirectory(f.getParentFile());
329             path = f.getName();
330         }
331         command.addArgument(path);
332         //add in any extra files.
333
//this is an error in mono, but we do not warn on it as they may fix that outside
334
//the ant build cycle.
335
Iterator JavaDoc it = schemas.iterator();
336         while (it.hasNext()) {
337             Schema schema = (Schema) it.next();
338             //mark for a rebuild if we are newer
339
rebuild |= isRebuildNeeded(schema, destLastModified);
340             command.addArgument(schema.evaluate());
341         }
342         //conditionally compile
343
if (rebuild) {
344             command.runCommand();
345         }
346     }
347
348     /**
349      * checks for a schema being out of data
350      * @param schema url/file
351      * @param destLastModified timestamp, -1 for no dest
352      * @return true if a rebuild is needed.
353      */

354     private boolean isRebuildNeeded(Schema schema, long destLastModified) {
355         if (destLastModified == -1) {
356             return true;
357         }
358         return !FILE_UTILS.isUpToDate(schema.getTimestamp(), destLastModified);
359     }
360
361
362     /**
363      * nested schema class
364      * Only supported on NET until mono add multi-URL handling on the command line
365      */

366     public static class Schema {
367         private File JavaDoc file;
368         private String JavaDoc url;
369         private boolean makeURL = false;
370
371         // Errors
372
/** One of file or url must be set */
373         public static final String JavaDoc ERROR_NONE_DECLARED = "One of file and url must be set";
374         /** Only one of file or url */
375         public static final String JavaDoc ERROR_BOTH_DECLARED = "Only one of file or url can be set";
376         /** Not found */
377         public static final String JavaDoc ERROR_FILE_NOT_FOUND = "Not found: ";
378         /** File is a directory */
379         public static final String JavaDoc ERROR_FILE_IS_DIR = "File is a directory: ";
380         /** Could not URL convert */
381         public static final String JavaDoc ERROR_NO_URL_CONVERT = "Could not URL convert ";
382
383         /**
384          * validate the schema
385          */

386         public void validate() {
387
388             if (file != null) {
389                 if (!file.exists()) {
390                     throw new BuildException(ERROR_FILE_NOT_FOUND + file.toString());
391                 }
392                 if (file.isDirectory()) {
393                     throw new BuildException(ERROR_FILE_IS_DIR + file.toString());
394                 }
395             }
396             if (file != null && url != null) {
397                 throw new BuildException(ERROR_BOTH_DECLARED);
398             }
399             if (file == null && url == null) {
400                 throw new BuildException(ERROR_NONE_DECLARED);
401             }
402         }
403
404         /**
405          * Validate our settings.
406          * @return either the URL or the full file path
407          */

408         public String JavaDoc evaluate() {
409             validate();
410             if (url != null) {
411                 return getUrl();
412             }
413             if (makeURL) {
414                 try {
415                     return file.toURL().toExternalForm();
416                 } catch (MalformedURLException JavaDoc e) {
417                     throw new BuildException(ERROR_NO_URL_CONVERT + file);
418                 }
419             }
420             return file.toString();
421         }
422
423         /**
424          * Get the file.
425          * @return the file used.
426          */

427         public File JavaDoc getFile() {
428             return file;
429         }
430
431         /**
432          * name of a file to use as a source of WSDL or XSD data
433          * @param file the file to use.
434          */

435         public void setFile(File JavaDoc file) {
436             this.file = file;
437         }
438
439         /**
440          * Get the url.
441          * @return the URL of the resource.
442          */

443         public String JavaDoc getUrl() {
444             return url;
445         }
446
447         /**
448          * url of a resource.
449          * URLs have no timestamp checking, and are not validated
450          * @param url the URL string to use.
451          */

452         public void setUrl(String JavaDoc url) {
453             this.url = url;
454         }
455
456         /**
457          * Get the makeURL attribute.
458          * @return the attribute.
459          */

460         public boolean isMakeURL() {
461             return makeURL;
462         }
463
464         /**
465          * flag to request that a file is turned into an absolute file: URL
466          * before being passed to the WSDL compiler
467          * @param makeURL a <code>boolean</code> value.
468          */

469         public void setMakeURL(boolean makeURL) {
470             this.makeURL = makeURL;
471         }
472
473         /**
474          * Gets the file timestamp.
475          * @return the timestamp of a file, or -1 for a URL (meaning we do not know its age)
476          */

477         public long getTimestamp() {
478             if (file != null) {
479                 return file.lastModified();
480             } else {
481                 return -1;
482             }
483         }
484     }
485
486     /**
487      * The enumerated values for our compiler
488      */

489     public static class Compiler extends EnumeratedAttribute {
490
491         /** microsoft */
492         public static final String JavaDoc COMPILER_MS = "microsoft";
493         /** mono */
494         public static final String JavaDoc COMPILER_MONO = "mono";
495         /** microsoft-on-mono */
496         public static final String JavaDoc COMPILER_MS_ON_MONO = "microsoft-on-mono";
497         // CheckStyle:VisibilityModifier OFF - bc
498
/** the index to string mappings */
499         String JavaDoc[] compilers = {
500             COMPILER_MS,
501             COMPILER_MONO,
502             COMPILER_MS_ON_MONO
503         };
504
505         /** WSDL */
506         public static final String JavaDoc EXE_WSDL = "wsdl";
507         /** MONO */
508         public static final String JavaDoc EXE_MONO = "mono";
509         /**
510          * programs to run
511          */

512         String JavaDoc[] compilerExecutables = {
513             EXE_WSDL,
514             EXE_WSDL,
515             EXE_MONO
516         };
517
518
519         /**
520          * extra things
521          */

522         String JavaDoc[][] extraCompilerArgs = {
523             {},
524             {},
525             {EXE_WSDL + ".exe"}
526         };
527
528         boolean[] absoluteFiles = {
529             true,
530             false,
531             true
532         };
533
534         // CheckStyle:VisibilityModifier ON
535
/**
536          * This is the only method a subclass needs to implement.
537          *
538          * @return an array holding all possible values of the enumeration.
539          * The order of elements must be fixed so that <tt>indexOfValue(String)</tt>
540          * always return the same index for the same value.
541          */

542         public String JavaDoc[] getValues() {
543             return compilers;
544         }
545
546         /**
547          * Create the default compiler for this platform.
548          * @return the default compiler
549          */

550         public static Compiler JavaDoc createDefaultCompiler() {
551             Compiler JavaDoc c = new Compiler JavaDoc();
552             String JavaDoc compilerName;
553             compilerName = Os.isFamily("windows") ? COMPILER_MS : COMPILER_MONO;
554             c.setValue(compilerName);
555             return c;
556         }
557
558         /**
559          * return the command to run
560          * @return the command
561          */

562         public String JavaDoc getCommand() {
563             return compilerExecutables[getIndex()];
564         }
565
566         /**
567          * return any extra arguments for the compiler
568          * @return extra compiler arguments
569          */

570         public String JavaDoc[] getExtraArgs() {
571             return extraCompilerArgs[getIndex()];
572         }
573
574         /**
575          * Get where the current value supports absolute files.
576          * @return true if the compiler does supports absolute files.
577          */

578         public boolean supportsAbsoluteFiles() {
579             return absoluteFiles[getIndex()];
580         }
581
582         /**
583          * apply any extra arguments of this class
584          * @param command the command to apply the arguments to.
585          */

586         public void applyExtraArgs(NetCommand command) {
587             String JavaDoc[] args = getExtraArgs();
588             for (int i = 0; i < args.length; i++) {
589                command.addArgument(args[i]);
590             }
591         }
592
593     }
594
595 }
596
Popular Tags