1. /*
  2. * Copyright 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. */
  17. package org.apache.tools.ant.taskdefs.optional.dotnet;
  18. import java.io.File;
  19. import org.apache.tools.ant.BuildException;
  20. import org.apache.tools.ant.Task;
  21. /**
  22. * Converts a WSDL file or URL resource into a .NET language.
  23. *
  24. * Why add a wrapper to the MS WSDL tool?
  25. * So that you can verify that your web services, be they written with Axis or
  26. *anyone else's SOAP toolkit, work with .NET clients.
  27. *
  28. *This task is dependency aware when using a file as a source and destination;
  29. *so if you <get> the file (with <code>usetimestamp="true"</code>) then
  30. *you only rebuild stuff when the WSDL file is changed. Of course,
  31. *if the server generates a new timestamp every time you ask for the WSDL,
  32. *this is not enough...use the <filesmatch> <condition> to
  33. *to byte for byte comparison against a cached WSDL file then make
  34. *the target conditional on that test failing.
  35. * See "Creating an XML Web Service Proxy", "wsdl.exe" docs in
  36. * the framework SDK documentation
  37. * @version 0.5
  38. * @ant.task category="dotnet"
  39. * @since Ant 1.5
  40. */
  41. public class WsdlToDotnet extends Task {
  42. /**
  43. * name of output file (required)
  44. */
  45. private File destFile = null;
  46. /**
  47. * url to retrieve
  48. */
  49. private String url = null;
  50. /**
  51. * name of source file
  52. */
  53. private File srcFile = null;
  54. /**
  55. * language; defaults to C#
  56. */
  57. private String language = "CS";
  58. /**
  59. * flag set to true to generate server side skeleton
  60. */
  61. private boolean server = false;
  62. /**
  63. * namespace
  64. */
  65. private String namespace = null;
  66. /**
  67. * flag to control action on execution trouble
  68. */
  69. private boolean failOnError = true;
  70. /**
  71. * any extra command options?
  72. */
  73. protected String extraOptions = null;
  74. /**
  75. * Name of the file to generate. Required
  76. * @param destFile filename
  77. */
  78. public void setDestFile(File destFile) {
  79. this.destFile = destFile;
  80. }
  81. /**
  82. * Sets the URL to fetch. Fetching is by wsdl.exe; Ant proxy settings
  83. * are ignored; either url or srcFile is required.
  84. * @param url url to save
  85. */
  86. public void setUrl(String url) {
  87. this.url = url;
  88. }
  89. /**
  90. * The local WSDL file to parse; either url or srcFile is required.
  91. * @param srcFile name of WSDL file
  92. */
  93. public void setSrcFile(File srcFile) {
  94. this.srcFile = srcFile;
  95. }
  96. /**
  97. * set the language; one of "CS", "JS", or "VB"
  98. * optional, default is CS for C# source
  99. * @param language language to generate
  100. */
  101. public void setLanguage(String language) {
  102. this.language = language;
  103. }
  104. /**
  105. * flag to enable server side code generation;
  106. * optional, default=false
  107. * @param server server-side flag
  108. */
  109. public void setServer(boolean server) {
  110. this.server = server;
  111. }
  112. /**
  113. * namespace to place the source in.
  114. * optional; default ""
  115. * @param namespace new namespace
  116. */
  117. public void setNamespace(String namespace) {
  118. this.namespace = namespace;
  119. }
  120. /**
  121. * Whether or not a failure should halt the build.
  122. * Optional - default is <code>true</code>.
  123. * @param failOnError new failure option
  124. */
  125. public void setFailOnError(boolean failOnError) {
  126. this.failOnError = failOnError;
  127. }
  128. /**
  129. * Any extra WSDL.EXE options which aren't explicitly
  130. * supported by the ant wrapper task; optional
  131. *
  132. *@param extraOptions The new ExtraOptions value
  133. */
  134. public void setExtraOptions(String extraOptions) {
  135. this.extraOptions = extraOptions;
  136. }
  137. /**
  138. * validation code
  139. * @throws BuildException if validation failed
  140. */
  141. protected void validate()
  142. throws BuildException {
  143. if (destFile == null) {
  144. throw new BuildException("destination file must be specified");
  145. }
  146. if (destFile.isDirectory()) {
  147. throw new BuildException(
  148. "destination file is a directory");
  149. }
  150. if (url != null && srcFile != null) {
  151. throw new BuildException(
  152. "you can not specify both a source file and a URL");
  153. }
  154. if (url == null && srcFile == null) {
  155. throw new BuildException(
  156. "you must specify either a source file or a URL");
  157. }
  158. if (srcFile != null) {
  159. if (!srcFile.exists()) {
  160. throw new BuildException(
  161. "source file does not exist");
  162. }
  163. if (srcFile.isDirectory()) {
  164. throw new BuildException(
  165. "source file is a directory");
  166. }
  167. }
  168. }
  169. /**
  170. * do the work by building the command line and then calling it
  171. *
  172. *@throws BuildException if validation or execution failed
  173. */
  174. public void execute()
  175. throws BuildException {
  176. validate();
  177. NetCommand command = new NetCommand(this, "WSDL", "wsdl");
  178. command.setFailOnError(failOnError);
  179. //fill in args
  180. command.addArgument("/nologo");
  181. command.addArgument("/out:" + destFile);
  182. command.addArgument("/language:", language);
  183. if (server) {
  184. command.addArgument("/server");
  185. }
  186. command.addArgument("/namespace:", namespace);
  187. command.addArgument(extraOptions);
  188. //set source and rebuild options
  189. boolean rebuild = true;
  190. if (srcFile != null) {
  191. command.addArgument(srcFile.toString());
  192. //rebuild unless the dest file is newer than the source file
  193. if (srcFile.exists() && destFile.exists()
  194. && srcFile.lastModified() <= destFile.lastModified()) {
  195. rebuild = false;
  196. }
  197. } else {
  198. //no source file? must be a url, which has no dependency
  199. //handling
  200. rebuild = true;
  201. command.addArgument(url);
  202. }
  203. if (rebuild) {
  204. command.runCommand();
  205. }
  206. }
  207. }