Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/apache/axis/tools/ant/wsdl/Wsdl2javaAntTask.java


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;
19  import java.io.IOException;
20  import java.net.Authenticator;
21  import java.util.ArrayList;
22  import java.util.HashMap;
23  import java.util.List;
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 factory = null;
93      private HashMap namespaceMap = new HashMap();
94      private String output = ".";
95      private String protocolHandlerPkgs = "";
96      private String deployScope = "";
97      private String url = "";
98      private String typeMappingVersion = "1.2";
99      private long timeout = 45000;
100     private File namespaceMappingFile = null;
101     private MappingSet mappings = new MappingSet();
102     private String username = null;
103     private String password = null;
104     private Path classpath = null;
105     private List nsIncludes = new ArrayList();
106     private List nsExcludes = new ArrayList();
107     private List properties = new ArrayList();
108   private String 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 outdir = new File(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 t){
271             }
272             
273             log("WSDL2Java " + url, Project.MSG_INFO);
274             try {
275                 emitter.run(url);
276             } catch (Throwable 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 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 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 parameter) throws BuildException {
392         try {
393             this.output = parameter.getCanonicalPath();
394         } catch (IOException 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 handlerPkgs) {
403         String currentPkgs = System.getProperty("java.protocol.handler.pkgs");
404         String 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 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 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 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 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 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 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 setting, int logLevel) {
623         String 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