KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > axis > tools > ant > wsdl > Wsdl2javaAntTask


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

16 package org.apache.axis.tools.ant.wsdl;
17
18 import java.io.File JavaDoc;
19 import java.io.IOException JavaDoc;
20 import java.net.Authenticator JavaDoc;
21 import java.util.ArrayList JavaDoc;
22 import java.util.HashMap JavaDoc;
23 import java.util.List JavaDoc;
24
25 import org.apache.axis.constants.Scope;
26 import org.apache.axis.utils.DefaultAuthenticator;
27 import org.apache.axis.utils.ClassUtils;
28 import org.apache.axis.wsdl.toJava.Emitter;
29 import org.apache.axis.wsdl.toJava.FactoryProperty;
30 import org.apache.axis.wsdl.toJava.NamespaceSelector;
31 import org.apache.tools.ant.BuildException;
32 import org.apache.tools.ant.Project;
33 import org.apache.tools.ant.Task;
34 import org.apache.tools.ant.AntClassLoader;
35 import org.apache.tools.ant.types.Path;
36 import org.apache.tools.ant.types.CommandlineJava;
37 import org.apache.tools.ant.types.Environment;
38
39 /*
40  * IMPORTANT: see Java2WsdlAntTask on how to javadoc this task and rebuild
41  * the task documentation afterwards
42  *
43  */

44
45 /**
46  * Create Java classes from local or remote WSDL.
47  * Mappings from namespaces to packages can be provided as nested <mapping>
48  * elements.
49  * <p>
50  * Proxy settings are taken from the java runtime settings of http.ProxyHost,
51  * http.ProxyPort, etc. The Ant task &lt;setProxy&gt; can set these.
52  * As well as the nested mapping elements, this task uses the file
53  * <tt>NStoPkg.properties</tt> in the project base directory
54  * for namespace mapping
55  * <p>
56  * This task does no dependency checking; files are generated whether they
57  * need to be or not. The exception to this is the Impl class, which is
58  * not overwritten if it exists. This is a safety measure. However, all other
59  * classes are generated overwriting anything that exists.
60  * <p>
61  * The safe way to use this task is to have it generate the java source in
62  * a build directory, then have a &lt;copy&gt task selectively copy the
63  * files you need into a safe location. Again, copying into the source tree
64  * is dangerous, but a separate build/src tree is safe. Then include this
65  * separate tree in the &lt;javac&gt; task's src attribute to include it in the
66  * build. Implement your own implementation classes of the server stub and the
67  * test cases using the generated templates.
68  * If you want to add methods to autogenerated data types, consider subclassing
69  * them, or write helper classes.
70  * <p>
71  * Tip: if you &lt;get&gt; the wsdl, and use the &lt;filesmatch&gt; condition
72  * to compare the fetched wsdl with a catched copy, you can make the target that
73  * calls the axis-wsd2ljava task conditional on the WSDL having changed. This stops
74  * spurious code regeneration and follow-on rebuilds across the java source tree.
75  * @ant.task category="axis" name="axis-wsdl2java"
76  * @author Davanum Srinivas (dims@yahoo.com)
77  * @author steve loughran
78  */

79 public class Wsdl2javaAntTask extends Task
80 {
81     private boolean verbose = false;
82     private boolean debug = false;
83     private boolean quiet = false;
84     private boolean server = false;
85     private boolean skeletonDeploy = false;
86     private boolean testCase = false;
87     private boolean noImports = false;
88     private boolean all = false;
89     private boolean helperGen = false;
90     private boolean noWrapped = false;
91     private boolean allowInvalidURL = false;
92     private String JavaDoc factory = null;
93     private HashMap JavaDoc namespaceMap = new HashMap JavaDoc();
94     private String JavaDoc output = ".";
95     private String JavaDoc protocolHandlerPkgs = "";
96     private String JavaDoc deployScope = "";
97     private String JavaDoc url = "";
98     private String JavaDoc typeMappingVersion = "1.2";
99     private long timeout = 45000;
100     private File JavaDoc namespaceMappingFile = null;
101     private MappingSet mappings = new MappingSet();
102     private String JavaDoc username = null;
103     private String JavaDoc password = null;
104     private Path classpath = null;
105     private List JavaDoc nsIncludes = new ArrayList JavaDoc();
106     private List JavaDoc nsExcludes = new ArrayList JavaDoc();
107     private List JavaDoc properties = new ArrayList JavaDoc();
108     private String JavaDoc implementationClassName = null;
109     private CommandlineJava commandline = new CommandlineJava();
110
111     /**
112      * do we print a stack trace when something goes wrong?
113      */

114     private boolean printStackTraceOnFailure = true;
115     /**
116      * what action to take when there was a failure and the source was some
117      * URL
118      */

119     private boolean failOnNetworkErrors = false;
120
121     private boolean wrapArrays = false;
122
123     public Wsdl2javaAntTask() {
124     }
125
126     /**
127      * validation code
128      * @throws BuildException if validation failed
129      */

130     protected void validate()
131             throws BuildException {
132         if (url == null || url.length() == 0) {
133             throw new BuildException("No url specified");
134         }
135         if (timeout < -1) {
136             throw new BuildException("negative timeout supplied");
137         }
138         File JavaDoc outdir = new File JavaDoc(output);
139         if (!outdir.isDirectory() || !outdir.exists()) {
140             throw new BuildException("output directory is not valid");
141         }
142         if (quiet) {
143             if (verbose) {
144                 throw new BuildException("quiet and verbose options are " +
145                                          "exclusive");
146             }
147             if (debug) {
148                 throw new BuildException("quiet and debug options are " +
149                                          "exclusive");
150             }
151         }
152     }
153
154     /**
155      * trace out parameters
156      * @param logLevel to log at
157      * @see org.apache.tools.ant.Project#log
158      */

159     public void traceParams(int logLevel) {
160         log("Running Wsdl2javaAntTask with parameters:", logLevel);
161         log("\tverbose:" + verbose, logLevel);
162         log("\tdebug:" + debug, logLevel);
163         log("\tquiet:" + quiet, logLevel);
164         log("\tserver-side:" + server, logLevel);
165         log("\tskeletonDeploy:" + skeletonDeploy, logLevel);
166         log("\thelperGen:" + helperGen, logLevel);
167         log("\tfactory:" + factory, logLevel);
168         log("\tnsIncludes:" + nsIncludes, logLevel);
169         log("\tnsExcludes:" + nsExcludes, logLevel);
170         log("\tfactoryProps:" + properties, logLevel);
171         log("\ttestCase:" + testCase, logLevel);
172         log("\tnoImports:" + noImports, logLevel);
173         log("\tNStoPkg:" + namespaceMap, logLevel);
174         log("\toutput:" + output, logLevel);
175         log("\tprotocolHandlerPkgs:" + protocolHandlerPkgs, logLevel);
176         log("\tdeployScope:" + deployScope, logLevel);
177         log("\tURL:" + url, logLevel);
178         log("\tall:" + all, logLevel);
179         log("\ttypeMappingVersion:" + typeMappingVersion, logLevel);
180         log("\ttimeout:" + timeout, logLevel);
181         log("\tfailOnNetworkErrors:" + failOnNetworkErrors, logLevel);
182         log("\tprintStackTraceOnFailure:" + printStackTraceOnFailure, logLevel);
183         log("\tnamespaceMappingFile:" + namespaceMappingFile, logLevel);
184         log("\tusername:" + username, logLevel);
185         log("\t:password" + password, logLevel);
186         log("\t:noWrapped" + noWrapped, logLevel);
187         log("\t:allowInvalidURL" + allowInvalidURL, logLevel);
188         log("\t:implementationClassName" + implementationClassName, logLevel);
189         log("\t:classpath" + classpath, logLevel);
190         traceNetworkSettings(logLevel);
191     }
192
193     /**
194      * The method executing the task
195      * @throws BuildException if validation or execution failed
196      */

197     public void execute() throws BuildException {
198         //before we get any further, if the user didnt spec a namespace mapping
199
//file, we load in the default
200

201         traceParams(Project.MSG_VERBOSE);
202         validate();
203         CommandlineJava.SysProperties sysProperties =
204                 commandline.getSystemProperties();
205         if (sysProperties != null) {
206             sysProperties.setSystem();
207         }
208         
209         try {
210             // Instantiate the emitter
211
Emitter emitter = createEmitter();
212
213             //extract the scope
214
Scope scope = Scope.getScope(deployScope, null);
215             if (scope != null) {
216                 emitter.setScope(scope);
217             } else if (deployScope.length() == 0
218                     || "none".equalsIgnoreCase(deployScope)) {
219                 /* leave default (null, or not-explicit) */;
220             } else {
221                 log("Unrecognized scope: " + deployScope + ". Ignoring it.", Project.MSG_VERBOSE);
222             }
223
224             //do the mappings, with namespaces mapped as the key
225
mappings.execute(this, namespaceMap, false);
226             if (!namespaceMap.isEmpty()) {
227                 emitter.setNamespaceMap(namespaceMap);
228             }
229             emitter.setTestCaseWanted(testCase);
230             emitter.setHelperWanted(helperGen);
231             if (factory != null) {
232                 emitter.setFactory(factory);
233             }
234             emitter.setNamespaceIncludes(nsIncludes);
235             emitter.setNamespaceExcludes(nsExcludes);
236             emitter.setProperties(properties);
237             emitter.setImports(!noImports);
238             emitter.setAllWanted(all);
239             emitter.setOutputDir(output);
240             emitter.setServerSide(server);
241             emitter.setSkeletonWanted(skeletonDeploy);
242             emitter.setVerbose(verbose);
243             emitter.setDebug(debug);
244             emitter.setQuiet(quiet);
245             emitter.setTypeMappingVersion(typeMappingVersion);
246             emitter.setNowrap(noWrapped);
247             emitter.setAllowInvalidURL(allowInvalidURL);
248             emitter.setWrapArrays(wrapArrays);
249             if (namespaceMappingFile != null) {
250                 emitter.setNStoPkg(namespaceMappingFile.toString());
251             }
252             emitter.setTimeout(timeout);
253             emitter.setImplementationClassName(implementationClassName);
254
255             Authenticator.setDefault(new DefaultAuthenticator(username, password));
256             if (classpath != null) {
257                 AntClassLoader cl = new AntClassLoader(
258                         getClass().getClassLoader(),
259                         getProject(),
260                         classpath,
261                         false);
262                 log("Using CLASSPATH " + cl.getClasspath(),
263                         Project.MSG_VERBOSE);
264                 ClassUtils.setDefaultClassLoader(cl);
265             }
266
267             try {
268                 if(url.indexOf(':') == -1)
269                     url = getProject().resolveFile(url).getAbsolutePath();
270             } catch (Throwable JavaDoc t){
271             }
272             
273             log("WSDL2Java " + url, Project.MSG_INFO);
274             try {
275                 emitter.run(url);
276             } catch (Throwable JavaDoc e) {
277                 if (url.startsWith("http://")) {
278                     // What we have is either a network error or invalid XML -
279
// the latter most likely an HTML error page. This makes
280
// it impossible to continue with the test, so we stop here
281
if (!failOnNetworkErrors) {
282                         // test mode, issue a warning, and return without
283
//reporting a fatal error.
284
log(e.toString(), Project.MSG_WARN);
285                         return;
286                     } else {
287                         //in 'consumer' mode, bail out with the URL
288
throw new BuildException("Could not build " + url, e);
289                     }
290                 } else {
291                     throw e;
292                 }
293             }
294         } catch (BuildException b) {
295             //we rethrow this immediately; but need to catch it to stop it being
296
//mistaken for a throwable.
297
throw b;
298         } catch (Throwable JavaDoc t) {
299             if (printStackTraceOnFailure) {
300                 traceParams(Project.MSG_INFO);
301                 t.printStackTrace();
302             }
303             //now throw an exception that includes the error text of the caught exception.
304
throw new BuildException("WSDL processing error for "
305                     + url +" :\n "+t.getMessage() , t);
306         } finally {
307             if (sysProperties != null) {
308                 sysProperties.restoreSystem();
309             }
310         }
311
312     }
313
314     /**
315      * flag for verbose output; default=false
316      *
317      *@param verbose The new verbose value
318      */

319     public void setVerbose(boolean verbose) {
320         this.verbose = verbose;
321     }
322
323     /**
324      * flag for debug output; default=false
325      *
326      *@param debug The new debug value
327      */

328     public void setDebug(boolean debug) {
329         this.debug = debug;
330     }
331
332     /**
333      * flag for quiet output; default=false
334      *
335      *@param quiet The new quiet value
336      */

337     public void setQuiet(boolean quiet) {
338         this.quiet = quiet;
339     }
340
341     /**
342      * emit server-side bindings for web service; default=false
343      */

344     public void setServerSide(boolean parameter) {
345         this.server = parameter;
346     }
347
348     /**
349      * deploy skeleton (true) or implementation (false) in deploy.wsdd.
350      * Default is false. Assumes server-side="true".
351      */

352     public void setSkeletonDeploy(boolean parameter) {
353         this.skeletonDeploy = parameter;
354     }
355
356     /**
357      * flag for automatic Junit testcase generation
358      * default is false
359      */

360     public void setTestCase(boolean parameter) {
361         this.testCase = parameter;
362     }
363
364     /**
365      * Turn on/off Helper class generation;
366      * default is false
367      */

368     public void setHelperGen(boolean parameter) {
369         this.helperGen = parameter;
370     }
371
372     /**
373      * name of the Java2WSDLFactory class for
374      * extending WSDL generation functions
375      */

376     public void setFactory(String JavaDoc parameter) {
377         this.factory = parameter;
378     }
379
380     /**
381      * only generate code for the immediate WSDL document,
382      * and not imports; default=false;
383      */

384     public void setNoImports(boolean parameter) {
385         this.noImports = parameter;
386     }
387
388     /**
389      * output directory for emitted files
390      */

391     public void setOutput(File JavaDoc parameter) throws BuildException {
392         try {
393             this.output = parameter.getCanonicalPath();
394         } catch (IOException JavaDoc ioe) {
395             throw new BuildException(ioe);
396         }
397     }
398
399     /**
400      * append any protocol handler pkgs specified with the task
401      */

402     public void setProtocolHandlerPkgs(String JavaDoc handlerPkgs) {
403         String JavaDoc currentPkgs = System.getProperty("java.protocol.handler.pkgs");
404         String JavaDoc newPkgs = null;
405
406         if (currentPkgs == null)
407             newPkgs = handlerPkgs;
408         else
409         // append to the existing list
410
newPkgs = currentPkgs + "|" + handlerPkgs;
411
412         System.setProperty("java.protocol.handler.pkgs", newPkgs);
413     }
414
415     /**
416      * add scope to deploy.xml: "Application", "Request", "Session"
417      * optional;
418      */

419     public void setDeployScope(String JavaDoc scope) {
420         this.deployScope = scope;
421     }
422 /*
423     //unused till we can somehow get ant to be case insensitive when handling enums
424     public void setDeployScope(DeployScopeEnum scope) {
425         this.deployScope = scope.getValue();
426     }
427 */

428     /**
429      * URL to fetch and generate WSDL for.
430      * Can be remote or a local file.
431      */

432     public void setURL(String JavaDoc parameter) {
433         this.url = parameter;
434     }
435
436     /**
437      * flag to generate code for all elements, even unreferenced ones
438      * default=false;
439      */

440     public void setAll(boolean parameter) {
441         this.all = parameter;
442     }
443
444     /**
445      * the default type mapping registry to use. Either 1.1 or 1.2.
446      * Default is 1.1
447      * @param parameter new version
448      */

449     public void setTypeMappingVersion(TypeMappingVersionEnum parameter) {
450         this.typeMappingVersion = parameter.getValue();
451     }
452
453     /**
454      * timeout in milliseconds for URL retrieval; default is 45 seconds.
455      * Set this to -1 to disable timeouts altogether: other negative values
456      * are not allowed)
457      */

458     public void setTimeout(long parameter) {
459         this.timeout = parameter;
460     }
461
462     /**
463      * add a mapping of namespaces to packages
464      */

465     public void addMapping(NamespaceMapping mapping) {
466         mappings.addMapping(mapping);
467     }
468
469     /**
470      * add a mapping of namespaces to packages
471      */

472     public void addMappingSet(MappingSet mappingset) {
473         mappings.addMappingSet(mappingset);
474     }
475
476     /**
477      * set the mapping file. This is a properties file of
478      * package=namespace order. Optional, default is to look for
479      * a file called NStoPkg.properties in the project directory.
480      * @param namespaceMappingFile
481      */

482     public void setNamespaceMappingFile(File JavaDoc namespaceMappingFile) {
483         this.namespaceMappingFile = namespaceMappingFile;
484     }
485
486     /**
487      * valid deploy scopes for the task
488      */

489     /*
490     public static class DeployScopeEnum extends EnumeratedAttribute {
491         public String[] getValues() {
492             return new String[]{"Application", "Request", "Session","none"};
493         }
494
495     }
496     */

497
498     /**
499      * should the task fail the build if there is a network error?
500      * optional: defaults to false
501      * @param failOnNetworkErrors
502      */

503     public void setFailOnNetworkErrors(boolean failOnNetworkErrors) {
504         this.failOnNetworkErrors = failOnNetworkErrors;
505     }
506
507     /**
508      * should we print a stack trace on failure?
509      * Optional, default=true.
510      * @param printStackTraceOnFailure
511      */

512     public void setPrintStackTraceOnFailure(boolean printStackTraceOnFailure) {
513         this.printStackTraceOnFailure = printStackTraceOnFailure;
514     }
515
516     /**
517      * set any username required for BASIC authenticated access to the WSDL;
518      * optional.
519      * @param username
520      */

521     public void setUsername(String JavaDoc username) {
522         this.username = username;
523     }
524
525     /**
526      * set any password required for BASIC authenticated access to the WSDL;
527      * optional; only used if username is set
528      * @param password
529      * @see #username
530      */

531     public void setPassword(String JavaDoc password) {
532         this.password = password;
533     }
534
535     /**
536      * Set the noWrapped flag.
537      * @param noWrapped
538      */

539     public void setNoWrapped(boolean noWrapped) {
540         this.noWrapped = noWrapped;
541     }
542
543     /**
544      * Set the allowInvalidURL flag.
545      */

546     public void setAllowInvalidUrl(boolean b) {
547         this.allowInvalidURL = b;
548     }
549
550     /**
551      * Set the name of the class implementing the web service.
552      * This is especially useful when exporting a java class
553      * as a web service using Java2WSDL followed by WSDL2Java.
554      *
555      * @param implementationClassName
556      */

557     public void setImplementationClassName(String JavaDoc implementationClassName) {
558         this.implementationClassName = implementationClassName;
559     }
560
561
562     /**
563      * Set the wrap arrays flag - if true this will make new classes
564      * like "ArrayOfString" for literal "wrapped" arrays. Otherwise it
565      * will use "String []" and generate appropriate metadata.
566      *
567      * @param wrapArrays
568      */

569     public void setWrapArrays(boolean wrapArrays) {
570         this.wrapArrays = wrapArrays;
571     }
572
573     /**
574      * set the classpath
575      * @return
576      */

577     public Path createClasspath() {
578         if (classpath == null) {
579             classpath = new Path(getProject());
580         }
581         return classpath.createPath();
582     }
583
584     /** Adds an additional namespace to the list to be included
585      * in source code generation.
586      */

587     public NamespaceSelector createNsInclude() {
588         NamespaceSelector selector = new NamespaceSelector();
589         nsIncludes.add(selector);
590         return selector;
591     }
592
593     /** Adds an additional namespace to the list to be excluded
594      * from source code generation.
595      */

596     public NamespaceSelector createNsExclude() {
597         NamespaceSelector selector = new NamespaceSelector();
598         nsExcludes.add(selector);
599         return selector;
600     }
601
602     /** Adds a property name/value pair for specialized
603      * JavaGeneratorFactories.
604      */

605     public FactoryProperty createProperty() {
606         FactoryProperty property = new FactoryProperty();
607         properties.add(property);
608         return property;
609     }
610
611     /** This factory method makes it easier to extend this Ant task
612      * with a custom Emitter, if necessary.
613      */

614     protected Emitter createEmitter() {
615         return new Emitter();
616     }
617
618     protected NamespaceSelector createSelector() {
619         return new NamespaceSelector();
620     }
621
622     private void traceSystemSetting(String JavaDoc setting, int logLevel) {
623         String JavaDoc value = System.getProperty(setting);
624         log("\t" + setting + "=" + value, logLevel);
625     }
626
627     private void traceNetworkSettings(int logLevel) {
628         traceSystemSetting("http.proxyHost", logLevel);
629         traceSystemSetting("http.proxyPort", logLevel);
630         traceSystemSetting("http.proxyUser", logLevel);
631         traceSystemSetting("http.proxyPassword", logLevel);
632         traceSystemSetting("socks.proxyHost", logLevel);
633         traceSystemSetting("socks.proxyPort", logLevel);
634     }
635
636     /**
637      * Adds a system property that tests can access.
638      * @param sysp environment variable to add
639      */

640     public void addSysproperty(Environment.Variable sysp) {
641         commandline.addSysproperty(sysp);
642     }
643 }
644
645
Popular Tags