1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 package org.codehaus.mojo.jaxws;
38
39 import java.io.File;
40 import java.io.FileFilter;
41 import java.io.IOException;
42 import java.io.UnsupportedEncodingException;
43 import java.net.MalformedURLException;
44 import java.net.URI;
45 import java.net.URL;
46 import java.net.URLClassLoader;
47 import java.security.MessageDigest;
48 import java.security.NoSuchAlgorithmException;
49 import java.util.ArrayList;
50 import java.util.Enumeration;
51 import java.util.Formatter;
52 import java.util.List;
53 import java.util.jar.JarEntry;
54 import java.util.jar.JarFile;
55 import java.util.regex.Matcher;
56 import java.util.regex.Pattern;
57
58 import org.apache.maven.plugin.MojoExecutionException;
59 import org.apache.maven.plugins.annotations.Parameter;
60 import org.apache.maven.settings.Proxy;
61 import org.apache.maven.settings.Settings;
62
63
64
65
66
67
68 abstract class WsImportMojo
69 extends AbstractJaxwsMojo
70 {
71
72 private static final String STALE_FILE_PREFIX = ".";
73
74 private static final String PATTERN = "[^\\s]+\\.wsdl$";
75
76
77
78
79 @Parameter
80 private String packageName;
81
82
83
84
85
86 @Parameter
87 private File catalog;
88
89
90
91
92 @Parameter
93 private String httpproxy;
94
95
96
97
98 @Parameter( defaultValue = "${project.basedir}/src/wsdl" )
99 private File wsdlDirectory;
100
101
102
103
104
105 @Parameter
106 protected List<String> wsdlFiles;
107
108
109
110
111 @Parameter
112 private List<?> wsdlUrls;
113
114
115
116
117 @Parameter( defaultValue = "${project.basedir}/src/jaxws" )
118 protected File bindingDirectory;
119
120
121
122
123
124 @Parameter
125 protected List<String> bindingFiles;
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158 @Parameter
159 private String wsdlLocation;
160
161
162
163
164
165
166 @Parameter
167 private String target;
168
169
170
171
172 @Parameter( defaultValue = "false" )
173 private boolean quiet;
174
175
176
177
178
179
180
181 @Parameter
182 private String implServiceName;
183
184
185
186
187
188
189
190 @Parameter
191 private String implPortName;
192
193
194
195
196 @Parameter( defaultValue = "false" )
197 private boolean genJWS;
198
199
200
201
202
203 @Parameter( defaultValue = "true" )
204 private boolean xnocompile;
205
206
207
208
209 @Parameter( defaultValue = "false" )
210 private boolean xadditionalHeaders;
211
212
213
214
215 @Parameter( defaultValue = "false" )
216 private boolean xdebug;
217
218
219
220
221
222 @Parameter( defaultValue = "false" )
223 private boolean xnoAddressingDataBinding;
224
225
226
227
228 @Parameter
229 protected File xauthFile;
230
231
232
233
234 @Parameter( defaultValue = "false" )
235 private boolean xdisableSSLHostnameVerification;
236
237
238
239
240 @Parameter( defaultValue = "false" )
241 private boolean xuseBaseResourceAndURLToLoadWSDL;
242
243
244
245
246 @Parameter( defaultValue = "false" )
247 private boolean xdisableAuthenticator;
248
249
250
251
252
253
254
255
256 @Parameter
257 private List<String> xjcArgs;
258
259
260
261
262 @Parameter( defaultValue = "${project.build.directory}/jaxws/stale" )
263 private File staleFile;
264
265
266
267 @Parameter( defaultValue = "${settings}", readonly = true, required = true )
268 private Settings settings;
269
270 protected abstract File getImplDestDir();
271
272
273
274
275
276 protected abstract List<String> getWSDLFileLookupClasspathElements();
277
278 @Override
279 public void executeJaxws()
280 throws MojoExecutionException
281 {
282 try
283 {
284 URL[] wsdls = getWSDLFiles();
285 if ( wsdls.length == 0 && ( wsdlUrls == null || wsdlUrls.isEmpty() ) )
286 {
287 getLog().info( "No WSDLs are found to process, Specify at least one of the following parameters: "
288 + "wsdlFiles, wsdlDirectory or wsdlUrls." );
289 return;
290 }
291 this.processWsdlViaUrls();
292 this.processLocalWsdlFiles( wsdls );
293 }
294 catch ( MojoExecutionException e )
295 {
296 throw e;
297 }
298 catch ( IOException e )
299 {
300 throw new MojoExecutionException( e.getMessage(), e );
301 }
302 }
303
304 @Override
305 protected String getMain()
306 {
307 return "com.sun.tools.ws.wscompile.WsimportTool";
308 }
309
310 @Override
311 protected String getToolName()
312 {
313 return "wsimport";
314 }
315
316 @Override
317 protected boolean isXnocompile()
318 {
319 return xnocompile;
320 }
321
322 private void processLocalWsdlFiles( URL[] wsdls )
323 throws MojoExecutionException, IOException
324 {
325 for ( URL u : wsdls )
326 {
327 String url = u.toExternalForm();
328 if ( isOutputStale( url ) )
329 {
330 getLog().info( "Processing: " + url );
331 String relPath = null;
332 if ( "file".equals( u.getProtocol() ) )
333 {
334 relPath = getRelativePath( new File( u.getPath() ) );
335 }
336 ArrayList<String> args = getWsImportArgs( relPath );
337 args.add( "\"" + url + "\"" );
338 getLog().info( "jaxws:wsimport args: " + args );
339 exec( args );
340 touchStaleFile( url );
341 }
342 else
343 {
344 getLog().info( "Ignoring: " + url );
345 }
346 addSourceRoot( getSourceDestDir().getAbsolutePath() );
347 }
348 }
349
350
351
352
353 private void processWsdlViaUrls()
354 throws MojoExecutionException, IOException
355 {
356 for ( int i = 0; wsdlUrls != null && i < wsdlUrls.size(); i++ )
357 {
358 String wsdlUrl = wsdlUrls.get( i ).toString();
359 if ( isOutputStale( wsdlUrl ) )
360 {
361 getLog().info( "Processing: " + wsdlUrl );
362 ArrayList<String> args = getWsImportArgs( null );
363 args.add( "\"" + wsdlUrl + "\"" );
364 getLog().info( "jaxws:wsimport args: " + args );
365 exec( args );
366 touchStaleFile( wsdlUrl );
367 }
368 addSourceRoot( getSourceDestDir().getAbsolutePath() );
369 }
370 }
371
372
373
374
375 private ArrayList<String> getWsImportArgs( String relativePath )
376 throws MojoExecutionException
377 {
378 ArrayList<String> args = new ArrayList<>();
379 args.addAll( getCommonArgs() );
380
381 if ( httpproxy != null )
382 {
383 args.add( "-httpproxy:" + httpproxy );
384 }
385 else if ( settings != null )
386 {
387 String proxyString = getActiveHttpProxy( settings );
388 if ( proxyString != null )
389 {
390 args.add( "-httpproxy:" + proxyString );
391 }
392
393 String nonProxyHostsString = getActiveNonProxyHosts( settings );
394 if ( nonProxyHostsString != null )
395 {
396 addVmArg( "-Dhttp.nonProxyHosts=" + nonProxyHostsString.replace( "|", "^|" ) );
397 }
398 }
399
400 if ( packageName != null )
401 {
402 args.add( "-p" );
403 args.add( packageName );
404 }
405
406 if ( catalog != null )
407 {
408 args.add( "-catalog" );
409 args.add( "'" + catalog.getAbsolutePath() + "'" );
410 }
411
412 if ( wsdlLocation != null )
413 {
414 if ( relativePath != null )
415 {
416 args.add( "-wsdllocation" );
417 args.add( wsdlLocation.replaceAll( "\\*", relativePath ) );
418 }
419 else if ( !wsdlLocation.contains( "*" ) )
420 {
421 args.add( "-wsdllocation" );
422 args.add( wsdlLocation );
423 }
424 }
425
426 if ( target != null )
427 {
428 args.add( "-target" );
429 args.add( target );
430 }
431
432 if ( quiet )
433 {
434 args.add( "-quiet" );
435 }
436
437 if ( ( genJWS || implServiceName != null || implPortName != null ) && isArgSupported( "-generateJWS" ) )
438 {
439 args.add( "-generateJWS" );
440 if ( implServiceName != null && isArgSupported( "-implServiceName" ) )
441 {
442 args.add( "-implServiceName" );
443 args.add( implServiceName );
444 }
445 if ( implPortName != null && isArgSupported( "-implPortName" ) )
446 {
447 args.add( "-implPortName" );
448 args.add( implPortName );
449 }
450 File implDestDir = getImplDestDir();
451 if ( !implDestDir.mkdirs() && !implDestDir.exists() )
452 {
453 getLog().warn( "Cannot create directory: " + implDestDir.getAbsolutePath() );
454 }
455 args.add( "-implDestDir" );
456 args.add( "'" + implDestDir.getAbsolutePath() + "'" );
457 if ( !project.getCompileSourceRoots().contains( implDestDir.getAbsolutePath() ) )
458 {
459 project.addCompileSourceRoot( implDestDir.getAbsolutePath() );
460 }
461 }
462
463 if ( xdebug )
464 {
465 args.add( "-Xdebug" );
466 }
467
468 if ( xnoAddressingDataBinding )
469 {
470 args.add( "-Xno-addressing-databinding" );
471 }
472
473 if ( xadditionalHeaders )
474 {
475 args.add( "-XadditionalHeaders" );
476 }
477
478 if ( xauthFile != null )
479 {
480 args.add( "-Xauthfile" );
481 args.add( xauthFile.getAbsolutePath() );
482 }
483
484 if ( xdisableSSLHostnameVerification )
485 {
486 args.add( "-XdisableSSLHostnameVerification" );
487 }
488 if ( xuseBaseResourceAndURLToLoadWSDL )
489 {
490 args.add( "-XuseBaseResourceAndURLToLoadWSDL" );
491 }
492 if ( xdisableAuthenticator && isArgSupported( "-XdisableAuthenticator" ) )
493 {
494 args.add( "-XdisableAuthenticator" );
495 }
496
497 if ( xjcArgs != null )
498 {
499 for ( String xjcArg : xjcArgs )
500 {
501 if ( xjcArg.startsWith( "-" ) )
502 {
503 args.add( "-B" + xjcArg );
504 }
505 else
506 {
507 args.add( xjcArg );
508 }
509 }
510 }
511
512
513 File[] bindings = getBindingFiles();
514 if ( bindings.length > 0 && wsdlLocation != null && wsdlLocation.contains( "*" ) )
515 {
516 throw new MojoExecutionException( "External binding file(s) can not be bound to more WSDL files ("
517 + wsdlLocation + ")\n" + "Please use either inline binding(s) or multiple execution tags." );
518 }
519 for ( File binding : bindings )
520 {
521 args.add( "-b" );
522 args.add( "'" + binding.toURI() + "'" );
523 }
524
525 return args;
526 }
527
528
529
530
531
532
533 public final File[] getBindingFiles()
534 {
535 File[] bindings;
536
537 if ( bindingFiles != null )
538 {
539 bindings = new File[bindingFiles.size()];
540 for ( int i = 0; i < bindingFiles.size(); ++i )
541 {
542 String schemaName = bindingFiles.get( i );
543 File file = new File( schemaName );
544 if ( !file.isAbsolute() )
545 {
546 file = new File( bindingDirectory, schemaName );
547 }
548 bindings[i] = file;
549 }
550 }
551 else
552 {
553 getLog().debug( "The binding Directory is " + bindingDirectory );
554 bindings = bindingDirectory.listFiles( XML_FILE_FILTER );
555 if ( bindings == null )
556 {
557 bindings = new File[0];
558 }
559 }
560 return bindings;
561 }
562
563
564
565
566
567
568 private URL[] getWSDLFiles()
569 throws MojoExecutionException
570 {
571 List<URL> files = new ArrayList<>();
572
573 List<String> classpathElements = getWSDLFileLookupClasspathElements();
574 List<URL> urlCpath = new ArrayList<>( classpathElements.size() );
575 for ( String el : classpathElements )
576 {
577 try
578 {
579 URL u = new File( el ).toURI().toURL();
580 urlCpath.add( u );
581 }
582 catch ( MalformedURLException e )
583 {
584 throw new MojoExecutionException( "Error while retrieving list of WSDL files to process", e );
585 }
586 }
587
588 try ( URLClassLoader loader = new URLClassLoader( urlCpath.toArray( new URL[0] ) ) )
589 {
590 if ( wsdlFiles != null )
591 {
592 for ( String wsdlFileName : wsdlFiles )
593 {
594 File wsdl = new File( wsdlFileName );
595 URL toAdd = null;
596 if ( !wsdl.isAbsolute() )
597 {
598 wsdl = new File( wsdlDirectory, wsdlFileName );
599 }
600 if ( !wsdl.exists() )
601 {
602 toAdd = loader.getResource( wsdlFileName );
603 }
604 else
605 {
606 try
607 {
608 toAdd = wsdl.toURI().toURL();
609 }
610 catch ( MalformedURLException ex )
611 {
612 getLog().error( ex );
613 }
614 }
615 getLog().debug( "The wsdl File is '" + wsdlFileName + "' from '" + toAdd + "'" );
616 if ( toAdd != null )
617 {
618 files.add( toAdd );
619 }
620 else
621 {
622 throw new MojoExecutionException( "'" + wsdlFileName + "' not found." );
623 }
624 }
625 }
626 else
627 {
628 getLog().debug( "The wsdl Directory is " + wsdlDirectory );
629 if ( wsdlDirectory.exists() )
630 {
631 File[] wsdls = wsdlDirectory.listFiles( WSDL_FILE_FILTER );
632 for ( File wsdl : wsdls )
633 {
634 files.add( wsdl.toURI().toURL() );
635 }
636 }
637 else
638 {
639 URI rel = project.getBasedir().toURI().relativize( wsdlDirectory.toURI() );
640 String dir = rel.getPath();
641 URL u = loader.getResource( dir );
642 if ( u == null )
643 {
644 dir = "WEB-INF/wsdl/";
645 u = loader.getResource( dir );
646 }
647 if ( u == null )
648 {
649 dir = "META-INF/wsdl/";
650 u = loader.getResource( dir );
651 }
652 if ( !( u == null || !"jar".equalsIgnoreCase( u.getProtocol() ) ) )
653 {
654 String path = u.getPath();
655 Pattern p = Pattern.compile( dir.replace( File.separatorChar, '/' ) + PATTERN,
656 Pattern.CASE_INSENSITIVE );
657 try ( JarFile jarFile = new JarFile( path.substring( 5, path.indexOf( "!/" ) ) ) )
658 {
659 Enumeration<JarEntry> jes = jarFile.entries();
660 while ( jes.hasMoreElements() )
661 {
662 JarEntry je = jes.nextElement();
663 Matcher m = p.matcher( je.getName() );
664 if ( m.matches() )
665 {
666 String s = "jar:" + path.substring( 0, path.indexOf( "!/" ) + 2 ) + je.getName();
667 files.add( new URL( s ) );
668 }
669 }
670 }
671 catch ( IOException ex )
672 {
673 getLog().error( ex );
674 }
675 }
676 }
677 }
678 }
679 catch ( MojoExecutionException e )
680 {
681 throw e;
682 }
683 catch ( Exception e )
684 {
685 throw new MojoExecutionException( "Error while retrieving list of WSDL files to process", e );
686 }
687
688 return files.toArray( new URL[0] );
689 }
690
691
692
693
694 private static final FileFilter XML_FILE_FILTER = f -> f.getName().endsWith( ".xml" );
695
696
697
698
699 private static final FileFilter WSDL_FILE_FILTER = f -> f.getName().endsWith( ".wsdl" );
700
701 private String getRelativePath( File f )
702 {
703 if ( wsdlFiles != null )
704 {
705 for ( String s : wsdlFiles )
706 {
707 String path = f.getPath().replace( File.separatorChar, '/' );
708 if ( path.endsWith( s ) && path.length() != s.length() )
709 {
710 return s;
711 }
712 }
713 }
714 else if ( wsdlDirectory != null && wsdlDirectory.exists() )
715 {
716 File[] wsdls = wsdlDirectory.listFiles( WSDL_FILE_FILTER );
717 for ( File wsdl : wsdls )
718 {
719 String path = f.getPath().replace( File.separatorChar, '/' );
720 if ( path.endsWith( wsdl.getName() ) )
721 {
722 return wsdl.getName();
723 }
724 }
725 }
726 return null;
727 }
728
729
730
731
732
733
734 private boolean isOutputStale( String resource )
735 {
736 File[] sourceBindings = getBindingFiles();
737 File stFile = new File( staleFile, STALE_FILE_PREFIX + getHash( resource ) );
738 boolean stale = !stFile.exists();
739 if ( !stale )
740 {
741 getLog().debug( "Stale flag file exists, comparing to wsdls and bindings." );
742 long staleMod = stFile.lastModified();
743
744 try
745 {
746
747 URL sourceWsdl = new URL( resource );
748 if ( sourceWsdl.openConnection().getLastModified() > staleMod )
749 {
750 getLog().debug( resource + " is newer than the stale flag file." );
751 stale = true;
752 }
753 }
754 catch ( MalformedURLException mue )
755 {
756
757 File sourceWsdl = new File( resource );
758 if ( sourceWsdl.lastModified() > staleMod )
759 {
760 getLog().debug( resource + " is newer than the stale flag file." );
761 stale = true;
762 }
763 }
764 catch ( IOException ioe )
765 {
766
767 getLog().error( ioe );
768 }
769
770 for ( File sourceBinding : sourceBindings )
771 {
772 if ( sourceBinding.lastModified() > staleMod )
773 {
774 getLog().debug( sourceBinding.getName() + " is newer than the stale flag file." );
775 stale = true;
776 }
777 }
778 }
779 return stale;
780 }
781
782 private void touchStaleFile( String resource )
783 throws IOException
784 {
785 File stFile = new File( staleFile, STALE_FILE_PREFIX + getHash( resource ) );
786 if ( !stFile.exists() )
787 {
788 File staleDir = stFile.getParentFile();
789 if ( !staleDir.mkdirs() && !staleDir.exists() )
790 {
791 getLog().warn( "Cannot create directory: " + staleDir.getAbsolutePath() );
792 }
793 if ( !stFile.createNewFile() )
794 {
795 getLog().warn( "Cannot create file: " + stFile.getAbsolutePath() );
796 }
797 getLog().debug( "Stale flag file created.[" + stFile.getAbsolutePath() + "]" );
798 }
799 else
800 {
801 if ( !stFile.setLastModified( System.currentTimeMillis() ) )
802 {
803 getLog().warn( "Stale file has not been updated!" );
804 }
805 }
806 }
807
808 private String getHash( String s )
809 {
810 try ( Formatter formatter = new Formatter() )
811 {
812 MessageDigest md = MessageDigest.getInstance( "SHA" );
813 for ( byte b : md.digest( s.getBytes( "UTF-8" ) ) )
814 {
815 formatter.format( "%02x", b );
816 }
817 return formatter.toString();
818 }
819 catch ( UnsupportedEncodingException ex )
820 {
821 getLog().debug( ex.getMessage(), ex );
822 }
823 catch ( NoSuchAlgorithmException ex )
824 {
825 getLog().debug( ex.getMessage(), ex );
826 }
827
828
829 getLog().warn( "Could not compute hash for " + s + ". Using fallback method." );
830 return s.substring( s.lastIndexOf( '/' ) ).replaceAll( "\\.", "-" );
831 }
832
833
834
835
836 static String getActiveHttpProxy( Settings s )
837 {
838 String retVal = null;
839 for ( Proxy p : s.getProxies() )
840 {
841 if ( p.isActive() && "http".equals( p.getProtocol() ) )
842 {
843 StringBuilder sb = new StringBuilder();
844 String user = p.getUsername();
845 String pwd = p.getPassword();
846 if ( user != null )
847 {
848 sb.append( user );
849 if ( pwd != null )
850 {
851 sb.append( ":" );
852 sb.append( pwd );
853 }
854 sb.append( "@" );
855 }
856 sb.append( p.getHost() );
857 sb.append( ":" );
858 sb.append( p.getPort() );
859 retVal = sb.toString().trim();
860 break;
861 }
862 }
863 return retVal;
864 }
865
866 static String getActiveNonProxyHosts( Settings s )
867 {
868 String retVal = null;
869 for ( Proxy p : s.getProxies() )
870 {
871 if ( p.isActive() && "http".equals( p.getProtocol() ) )
872 {
873 retVal = p.getNonProxyHosts();
874 break;
875 }
876 }
877 return retVal;
878 }
879 }