1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.codehaus.mojo.jaxws;
18
19 import java.io.File;
20 import java.io.FileFilter;
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.List;
24
25 import org.apache.maven.plugin.MojoExecutionException;
26
27 import com.sun.tools.ws.wscompile.WsimportTool;
28
29 /**
30 * <p>
31 * A Maven 2 plugin which parses wsdl and binding files and produces a corresponding object model based on the JAXWS
32 * WsImport parsing engine.
33 * </p>
34 *
35 * @goal wsimport
36 * @phase generate-sources
37 * @requiresDependencyResolution
38 * @description JAXWS 2.x Plugin.
39 * @author gnodet <gnodet@apache.org>
40 * @author dantran <dantran@apache.org>
41 * @version $Id: WsImportMojo.java 3169 2007-01-22 02:51:29Z dantran $
42 */
43 public class WsImportMojo
44 extends AbstractJaxwsMojo
45 {
46
47 /**
48 * The package in which the source files will be generated.
49 *
50 * @parameter
51 */
52 private String packageName;
53
54 /**
55 * Catalog file to resolve external entity references support TR9401,
56 * XCatalog, and OASIS XML Catalog format.
57 *
58 * @parameter
59 */
60 private File catalog;
61
62 /**
63 * Set HTTP/HTTPS proxy. Format is [user[:password]@]proxyHost[:proxyPort]
64 *
65 * @parameter
66 */
67 private String httpproxy;
68
69 /**
70 * Directory containing wsdl files.
71 *
72 * @parameter default-value="${basedir}/src/wsdl"
73 */
74 private File wsdlDirectory;
75
76 /**
77 * List of files to use for wsdls. If not specified, all .wsdl files
78 * in the wsdlDirectory will be used.
79 *
80 * @parameter
81 */
82 protected List wsdlFiles;
83
84 /**
85 * List of external wsdl urls.
86 *
87 * @parameter
88 */
89 private List wsdlUrls;
90
91 /**
92 * Directory containing binding files.
93 *
94 * @parameter default-value="${basedir}/src/jaxws"
95 */
96 protected File bindingDirectory;
97
98 /**
99 * List of files to use for bindings.If not specified, all .xml files
100 * in the bindingDirectory will be used.
101 *
102 * @parameter
103 */
104 protected List bindingFiles;
105
106 /**
107 * @WebService.wsdlLocation and
108 * @WebServiceClient.wsdlLocation value.
109 *
110 * @parameter
111 */
112 private String wsdlLocation;
113
114 /**
115 * Generate code as per the given JAXWS specification version.
116 * Version 2.0 will generate compliant code for JAXWS 2.0 spec
117 * @parameter
118 */
119 private String target;
120
121 /**
122 * Specify where to place generated source files, keep is turned on with this option.
123 *
124 * @parameter default-value="${project.build.directory}/jaxws/wsimport/java"
125 */
126 protected File sourceDestDir;
127
128 /**
129 * The location of the flag file used to determine if the output is stale.
130 * @parameter default-value="${project.build.directory}/jaxws/stale/.staleFlag"
131 */
132 private File staleFile;
133
134 public void execute()
135 throws MojoExecutionException
136 {
137
138
139 ClassLoader parent = this.getClass().getClassLoader();
140 String originalSystemClasspath = this.initClassLoader( parent );
141
142 try
143 {
144
145 sourceDestDir.mkdirs();
146 destDir.mkdirs();
147
148 this.processWsdlViaUrls();
149
150 this.processLocalWsdlFiles();
151
152
153
154 project.addCompileSourceRoot( sourceDestDir.getAbsolutePath() );
155
156 }
157 catch ( MojoExecutionException e )
158 {
159 throw e;
160 }
161 catch ( Exception e )
162 {
163 throw new MojoExecutionException( e.getMessage(), e );
164 }
165 finally
166 {
167
168 Thread.currentThread().setContextClassLoader( parent );
169 System.setProperty( "java.class.path", originalSystemClasspath );
170 }
171
172 }
173
174 /**
175 *
176 * @throws MojoExecutionException
177 * @throws IOException
178 */
179 private void processLocalWsdlFiles()
180 throws MojoExecutionException, IOException
181 {
182
183 if ( isOutputStale() )
184 {
185 File[] wsdls = getWSDLFiles();
186 for ( int i = 0; i < wsdls.length; i++ )
187 {
188 getLog().info( "Processing: " + wsdls[i].getAbsolutePath() );
189 ArrayList<String> args = getWsImportArgs();
190 args.add( wsdls[i].getAbsolutePath() );
191 getLog().info( "jaxws:wsimport args: " + args );
192 wsImport( args );
193
194 }
195 touchStaleFile();
196 }
197
198 }
199
200 /**
201 * process external wsdl
202 * @throws MojoExecutionException
203 */
204 private void processWsdlViaUrls()
205 throws MojoExecutionException
206 {
207
208
209 for ( int i = 0; wsdlUrls != null && i < wsdlUrls.size(); i++ )
210 {
211 String wsdlUrl = wsdlUrls.get( i ).toString();
212
213 getLog().info( "Processing: " + wsdlUrl );
214 ArrayList<String> args = getWsImportArgs();
215 args.add( wsdlUrl );
216 getLog().info( "jaxws:wsimport args: " + args );
217 wsImport( args );
218 }
219 }
220
221 /**
222 * Invoke wsimport compiler
223 * @param args
224 * @throws MojoExecutionException
225 */
226 private void wsImport( ArrayList<String> args )
227 throws MojoExecutionException
228 {
229 WsimportTool compTool = new WsimportTool( System.out );
230 if ( !compTool.run( args.toArray( new String[args.size()] ) ) )
231 {
232 throw new MojoExecutionException( "Error executing: wsimport " + args );
233 }
234 }
235
236 /**
237 *
238 * @return wsimport's command arguments
239 * @throws MojoExecutionException
240 */
241 private ArrayList<String> getWsImportArgs()
242 throws MojoExecutionException
243 {
244 ArrayList<String> args = new ArrayList<String>();
245
246 args.add( "-s" );
247 args.add( sourceDestDir.getAbsolutePath() );
248
249 args.add( "-d" );
250 args.add( destDir.getAbsolutePath() );
251
252 if ( verbose )
253 {
254 args.add( "-verbose" );
255 }
256
257 if ( httpproxy != null )
258 {
259 args.add( "-httpproxy" );
260 args.add( httpproxy );
261 }
262
263 if ( packageName != null )
264 {
265 args.add( "-p" );
266 args.add( packageName );
267 }
268
269 if ( catalog != null )
270 {
271 args.add( "-catalog" );
272 args.add( catalog.getAbsolutePath() );
273 }
274
275 if ( wsdlLocation != null )
276 {
277 args.add( "-wsdllocation" );
278 args.add( wsdlLocation );
279 }
280
281 if ( target != null )
282 {
283 args.add( "-target" );
284 args.add( target );
285 }
286
287 if ( extension )
288 {
289 args.add( "-extension" );
290 }
291
292
293 File bindings[] = getBindingFiles();
294 for ( int i = 0; i < bindings.length; i++ )
295 {
296 args.add( "-b" );
297 args.add( bindings[i].getAbsolutePath() );
298 }
299
300 getLog().debug( "jaxws:wsimport args: " + args );
301
302 return args;
303 }
304
305 /**
306 * Returns a file array of xml files to translate to object models.
307 *
308 * @return An array of schema files to be parsed by the schema compiler.
309 */
310 public final File[] getBindingFiles()
311 {
312 File [] bindings;
313
314 if ( bindingFiles != null )
315 {
316 bindings = new File[bindingFiles.size()];
317 for ( int i = 0 ; i < bindingFiles.size(); ++i )
318 {
319 String schemaName = (String) bindingFiles.get( i );
320 bindings[i] = new File( bindingDirectory, schemaName );
321 }
322 }
323 else
324 {
325 getLog().debug( "The binding Directory is " + bindingDirectory );
326 bindings = bindingDirectory.listFiles( new XMLFile() );
327 if ( bindings == null )
328 {
329 bindings = new File[0];
330 }
331 }
332
333 return bindings;
334 }
335
336 /**
337 * Returns a file array of wsdl files to translate to object models.
338 *
339 * @return An array of schema files to be parsed by the schema compiler.
340 */
341 public final File[] getWSDLFiles()
342 {
343 File [] files;
344
345 if ( wsdlFiles != null )
346 {
347 files = new File[ wsdlFiles.size() ];
348 for ( int i = 0 ; i < wsdlFiles.size(); ++i )
349 {
350 String schemaName = (String) wsdlFiles.get( i );
351 files[i] = new File( wsdlDirectory, schemaName ) ;
352 }
353 }
354 else
355 {
356 getLog().debug( "The wsdl Directory is " + wsdlDirectory );
357 files = wsdlDirectory.listFiles( new WSDLFile() );
358 if ( files == null )
359 {
360 files = new File[0];
361 }
362 }
363
364 return files;
365 }
366
367 /**
368 * A class used to look up .xml documents from a given directory.
369 */
370 private final class XMLFile
371 implements FileFilter
372 {
373 /**
374 * Returns true if the file ends with an xml extension.
375 *
376 * @param file
377 * The filed being reviewed by the filter.
378 * @return true if an xml file.
379 */
380 public boolean accept( final java.io.File file )
381 {
382 return file.getName().endsWith( ".xml" );
383 }
384 }
385
386 /**
387 * A class used to look up .wsdl documents from a given directory.
388 */
389 private final class WSDLFile
390 implements FileFilter
391 {
392
393 /**
394 * Returns true if the file ends with a wsdl extension.
395 *
396 * @param file
397 * The filed being reviewed by the filter.
398 * @return true if an wsdl file.
399 */
400 public boolean accept( final java.io.File file )
401 {
402 return file.getName().endsWith( ".wsdl" );
403 }
404
405 }
406
407 /**
408 * Returns true of any one of the files in the WSDL/XJB array are more new than the <code>staleFlag</code> file.
409 *
410 * @return True if wsdl files have been modified since the last build.
411 */
412 private boolean isOutputStale()
413 {
414 File[] sourceWsdls = getWSDLFiles();
415 File[] sourceBindings = getBindingFiles();
416 boolean stale = !staleFile.exists();
417 if ( !stale )
418 {
419 getLog().debug( "Stale flag file exists, comparing to wsdls and bindings." );
420 long staleMod = staleFile.lastModified();
421
422 for ( int i = 0; i < sourceWsdls.length; i++ )
423 {
424 if ( sourceWsdls[i].lastModified() > staleMod )
425 {
426 getLog().debug( sourceWsdls[i].getName() + " is newer than the stale flag file." );
427 stale = true;
428 }
429 }
430
431 for ( int i = 0; i < sourceBindings.length; i++ )
432 {
433 if ( sourceBindings[i].lastModified() > staleMod )
434 {
435 getLog().debug( sourceBindings[i].getName() + " is newer than the stale flag file." );
436 stale = true;
437 }
438 }
439 }
440 return stale;
441 }
442
443 private void touchStaleFile()
444 throws IOException
445 {
446 if ( !staleFile.exists() )
447 {
448 staleFile.getParentFile().mkdirs();
449 staleFile.createNewFile();
450 getLog().debug( "Stale flag file created." );
451 }
452 else
453 {
454 staleFile.setLastModified( System.currentTimeMillis() );
455 }
456 }
457
458 }