All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.codehaus.mojo.jaxws.WsImportMojo Maven / Gradle / Ivy

There is a newer version: 2.6.2
Show newest version
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
 *
 * Oracle licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *
 * This file incorporates work covered by the following copyright and
 * permission notice:
 *
 * Copyright 2006 Guillaume Nodet
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.codehaus.mojo.jaxws;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Formatter;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.settings.Proxy;
import org.apache.maven.settings.Settings;

/**
 * 
 * @author gnodet ([email protected])
 * @author dantran ([email protected])
 */
abstract class WsImportMojo
    extends AbstractJaxwsMojo
{

    private static final String STALE_FILE_PREFIX = ".";

    private static final String PATTERN = "[^\\s]+\\.wsdl$";

    /**
     * The package in which the source files will be generated.
     */
    @Parameter
    private String packageName;

    /**
     * Catalog file to resolve external entity references support TR9401, 
     * XCatalog, and OASIS XML Catalog format.
     */
    @Parameter
    private File catalog;

    /**
     * Set HTTP/HTTPS proxy. Format is [user[:password]@]proxyHost[:proxyPort].
     */
    @Parameter
    private String httpproxy;

    /**
     * Directory containing WSDL files.
     */
    @Parameter( defaultValue = "${project.basedir}/src/wsdl" )
    private File wsdlDirectory;

    /**
     * List of files to use for WSDLs. If not specified, all .wsdl
     * files in the wsdlDirectory will be used.
     */
    @Parameter
    protected List wsdlFiles;

    /**
     * List of external WSDL URLs to be compiled.
     */
    @Parameter
    private List wsdlUrls;

    /**
     * Directory containing binding files.
     */
    @Parameter( defaultValue = "${project.basedir}/src/jaxws" )
    protected File bindingDirectory;

    /**
     * List of files to use for bindings. If not specified, all .xml
     * files in the bindingDirectory will be used.
     */
    @Parameter
    protected List bindingFiles;

    /**
     * @WebService.wsdlLocation and @WebServiceClient.wsdlLocation value.
     * 
     * 

* Can end with asterisk in which case relative path of the WSDL will * be appended to the given wsdlLocation. *

* *

Example: *

     *  ...
     *  <configuration>
     *      <wsdlDirectory>src/mywsdls</wsdlDirectory>
     *      <wsdlFiles>
     *          <wsdlFile>a.wsdl</wsdlFile>
     *          <wsdlFile>b/b.wsdl</wsdlFile>
     *          <wsdlFile>${project.basedir}/src/mywsdls/c.wsdl</wsdlFile>
     *      </wsdlFiles>
     *      <wsdlLocation>http://example.com/mywebservices/*</wsdlLocation>
     *  </configuration>
     *  ...
     * 
* wsdlLocation for a.wsdl will be http://example.com/mywebservices/a.wsdl
* wsdlLocation for b/b.wsdl will be http://example.com/mywebservices/b/b.wsdl
* wsdlLocation for ${project.basedir}/src/mywsdls/c.wsdl will be file://absolute/path/to/c.wsdl *

* *

* Note: External binding files cannot be used if asterisk notation is in place. *

*/ @Parameter private String wsdlLocation; /** * Generate code as per the given JAXWS specification version. * Setting "2.0" will cause JAX-WS to generate artifacts * that run with JAX-WS 2.0 runtime. */ @Parameter private String target; /** * Suppress wsimport output. */ @Parameter( defaultValue = "false" ) private boolean quiet; /** * Local portion of service name for generated JWS implementation. * Implies genJWS=true. * * Note: It is a QName string, formatted as: "{" + Namespace URI + "}" + local part */ @Parameter private String implServiceName; /** * Local portion of port name for generated JWS implementation. * Implies genJWS=true. * * Note: It is a QName string, formatted as: "{" + Namespace URI + "}" + local part */ @Parameter private String implPortName; /** * Generate stubbed JWS implementation file. */ @Parameter( defaultValue = "false" ) private boolean genJWS; /** * Turn off compilation after code generation and let generated sources be * compiled by maven during compilation phase; keep is turned on with this option. */ @Parameter( defaultValue = "true" ) private boolean xnocompile; /** * Maps headers not bound to the request or response messages to Java method parameters. */ @Parameter( defaultValue = "false" ) private boolean xadditionalHeaders; /** * Turn on debug message. */ @Parameter( defaultValue = "false" ) private boolean xdebug; /** * Binding W3C EndpointReferenceType to Java. By default WsImport follows spec and does not bind * EndpointReferenceType to Java and uses the spec provided {@link javax.xml.ws.wsaddressing.W3CEndpointReference} */ @Parameter( defaultValue = "false" ) private boolean xnoAddressingDataBinding; /** * Specify the location of authorization file. */ @Parameter protected File xauthFile; /** * Disable the SSL Hostname verification while fetching WSDL(s). */ @Parameter( defaultValue = "false" ) private boolean xdisableSSLHostnameVerification; /** * If set, the generated Service classes will load the WSDL file from a URL generated from the base resource. */ @Parameter( defaultValue = "false" ) private boolean xuseBaseResourceAndURLToLoadWSDL; /** * Disable Authenticator used by JAX-WS RI, xauthfile will be ignored if set. */ @Parameter( defaultValue = "false" ) private boolean xdisableAuthenticator; /** * Specify optional XJC-specific parameters that should simply be passed to xjc * using -B option of WsImport command. *

* Multiple elements can be specified, and each token must be placed in its own list. *

*/ @Parameter private List xjcArgs; /** * The folder containing flag files used to determine if the output is stale. */ @Parameter( defaultValue = "${project.build.directory}/jaxws/stale" ) private File staleFile; /** */ @Parameter( defaultValue = "${settings}", readonly = true, required = true ) private Settings settings; protected abstract File getImplDestDir(); /** * Returns the dependencies that should be placed on the classpath for the classloader * to lookup wsdl files. */ protected abstract List getWSDLFileLookupClasspathElements(); @Override public void executeJaxws() throws MojoExecutionException { try { URL[] wsdls = getWSDLFiles(); if ( wsdls.length == 0 && ( wsdlUrls == null || wsdlUrls.isEmpty() ) ) { getLog().info( "No WSDLs are found to process, Specify at least one of the following parameters: " + "wsdlFiles, wsdlDirectory or wsdlUrls." ); return; } this.processWsdlViaUrls(); this.processLocalWsdlFiles( wsdls ); } catch ( MojoExecutionException e ) { throw e; } catch ( IOException e ) { throw new MojoExecutionException( e.getMessage(), e ); } } @Override protected String getMain() { return "com.sun.tools.ws.wscompile.WsimportTool"; } @Override protected String getToolName() { return "wsimport"; } @Override protected boolean isXnocompile() { return xnocompile; } private void processLocalWsdlFiles( URL[] wsdls ) throws MojoExecutionException, IOException { for ( URL u : wsdls ) { String url = u.toExternalForm(); if ( isOutputStale( url ) ) { getLog().info( "Processing: " + url ); String relPath = null; if ( "file".equals( u.getProtocol() ) ) { relPath = getRelativePath( new File( u.getPath() ) ); } ArrayList args = getWsImportArgs( relPath ); args.add( "\"" + url + "\"" ); getLog().info( "jaxws:wsimport args: " + args ); exec( args ); touchStaleFile( url ); } else { getLog().info( "Ignoring: " + url ); } addSourceRoot( getSourceDestDir().getAbsolutePath() ); } } /** * Process external wsdl */ private void processWsdlViaUrls() throws MojoExecutionException, IOException { for ( int i = 0; wsdlUrls != null && i < wsdlUrls.size(); i++ ) { String wsdlUrl = wsdlUrls.get( i ).toString(); if ( isOutputStale( wsdlUrl ) ) { getLog().info( "Processing: " + wsdlUrl ); ArrayList args = getWsImportArgs( null ); args.add( "\"" + wsdlUrl + "\"" ); getLog().info( "jaxws:wsimport args: " + args ); exec( args ); touchStaleFile( wsdlUrl ); } addSourceRoot( getSourceDestDir().getAbsolutePath() ); } } /** * Returns wsimport's command arguments as a list */ private ArrayList getWsImportArgs( String relativePath ) throws MojoExecutionException { ArrayList args = new ArrayList<>(); args.addAll( getCommonArgs() ); if ( httpproxy != null ) { args.add( "-httpproxy:" + httpproxy ); } else if ( settings != null ) { String proxyString = getActiveHttpProxy( settings ); if ( proxyString != null ) { args.add( "-httpproxy:" + proxyString ); } String nonProxyHostsString = getActiveNonProxyHosts( settings ); if ( nonProxyHostsString != null ) { addVmArg( "-Dhttp.nonProxyHosts=" + nonProxyHostsString.replace( "|", "^|" ) ); } } if ( packageName != null ) { args.add( "-p" ); args.add( packageName ); } if ( catalog != null ) { args.add( "-catalog" ); args.add( "'" + catalog.getAbsolutePath() + "'" ); } if ( wsdlLocation != null ) { if ( relativePath != null ) { args.add( "-wsdllocation" ); args.add( wsdlLocation.replaceAll( "\\*", relativePath ) ); } else if ( !wsdlLocation.contains( "*" ) ) { args.add( "-wsdllocation" ); args.add( wsdlLocation ); } } if ( target != null ) { args.add( "-target" ); args.add( target ); } if ( quiet ) { args.add( "-quiet" ); } if ( ( genJWS || implServiceName != null || implPortName != null ) && isArgSupported( "-generateJWS" ) ) { args.add( "-generateJWS" ); if ( implServiceName != null && isArgSupported( "-implServiceName" ) ) { args.add( "-implServiceName" ); args.add( implServiceName ); } if ( implPortName != null && isArgSupported( "-implPortName" ) ) { args.add( "-implPortName" ); args.add( implPortName ); } File implDestDir = getImplDestDir(); if ( !implDestDir.mkdirs() && !implDestDir.exists() ) { getLog().warn( "Cannot create directory: " + implDestDir.getAbsolutePath() ); } args.add( "-implDestDir" ); args.add( "'" + implDestDir.getAbsolutePath() + "'" ); if ( !project.getCompileSourceRoots().contains( implDestDir.getAbsolutePath() ) ) { project.addCompileSourceRoot( implDestDir.getAbsolutePath() ); } } if ( xdebug ) { args.add( "-Xdebug" ); } if ( xnoAddressingDataBinding ) { args.add( "-Xno-addressing-databinding" ); } if ( xadditionalHeaders ) { args.add( "-XadditionalHeaders" ); } if ( xauthFile != null ) { args.add( "-Xauthfile" ); args.add( xauthFile.getAbsolutePath() ); } if ( xdisableSSLHostnameVerification ) { args.add( "-XdisableSSLHostnameVerification" ); } if ( xuseBaseResourceAndURLToLoadWSDL ) { args.add( "-XuseBaseResourceAndURLToLoadWSDL" ); } if ( xdisableAuthenticator && isArgSupported( "-XdisableAuthenticator" ) ) { args.add( "-XdisableAuthenticator" ); } if ( xjcArgs != null ) { for ( String xjcArg : xjcArgs ) { if ( xjcArg.startsWith( "-" ) ) { args.add( "-B" + xjcArg ); } else { args.add( xjcArg ); } } } // Bindings File[] bindings = getBindingFiles(); if ( bindings.length > 0 && wsdlLocation != null && wsdlLocation.contains( "*" ) ) { throw new MojoExecutionException( "External binding file(s) can not be bound to more WSDL files (" + wsdlLocation + ")\n" + "Please use either inline binding(s) or multiple execution tags." ); } for ( File binding : bindings ) { args.add( "-b" ); args.add( "'" + binding.toURI() + "'" ); } return args; } /** * Returns a file array of xml files to translate to object models. * * @return An array of schema files to be parsed by the schema compiler. */ public final File[] getBindingFiles() { File[] bindings; if ( bindingFiles != null ) { bindings = new File[bindingFiles.size()]; for ( int i = 0; i < bindingFiles.size(); ++i ) { String schemaName = bindingFiles.get( i ); File file = new File( schemaName ); if ( !file.isAbsolute() ) { file = new File( bindingDirectory, schemaName ); } bindings[i] = file; } } else { getLog().debug( "The binding Directory is " + bindingDirectory ); bindings = bindingDirectory.listFiles( XML_FILE_FILTER ); if ( bindings == null ) { bindings = new File[0]; } } return bindings; } /** * Returns an array of wsdl files to translate to object models. * * @return An array of schema files to be parsed by the schema compiler. */ private URL[] getWSDLFiles() throws MojoExecutionException { List files = new ArrayList<>(); List classpathElements = getWSDLFileLookupClasspathElements(); List urlCpath = new ArrayList<>( classpathElements.size() ); for ( String el : classpathElements ) { try { URL u = new File( el ).toURI().toURL(); urlCpath.add( u ); } catch ( MalformedURLException e ) { throw new MojoExecutionException( "Error while retrieving list of WSDL files to process", e ); } } try ( URLClassLoader loader = new URLClassLoader( urlCpath.toArray( new URL[0] ) ) ) { if ( wsdlFiles != null ) { for ( String wsdlFileName : wsdlFiles ) { File wsdl = new File( wsdlFileName ); URL toAdd = null; if ( !wsdl.isAbsolute() ) { wsdl = new File( wsdlDirectory, wsdlFileName ); } if ( !wsdl.exists() ) { toAdd = loader.getResource( wsdlFileName ); } else { try { toAdd = wsdl.toURI().toURL(); } catch ( MalformedURLException ex ) { getLog().error( ex ); } } getLog().debug( "The wsdl File is '" + wsdlFileName + "' from '" + toAdd + "'" ); if ( toAdd != null ) { files.add( toAdd ); } else { throw new MojoExecutionException( "'" + wsdlFileName + "' not found." ); } } } else { getLog().debug( "The wsdl Directory is " + wsdlDirectory ); if ( wsdlDirectory.exists() ) { File[] wsdls = wsdlDirectory.listFiles( WSDL_FILE_FILTER ); for ( File wsdl : wsdls ) { files.add( wsdl.toURI().toURL() ); } } else { URI rel = project.getBasedir().toURI().relativize( wsdlDirectory.toURI() ); String dir = rel.getPath(); URL u = loader.getResource( dir ); if ( u == null ) { dir = "WEB-INF/wsdl/"; u = loader.getResource( dir ); } if ( u == null ) { dir = "META-INF/wsdl/"; u = loader.getResource( dir ); } if ( !( u == null || !"jar".equalsIgnoreCase( u.getProtocol() ) ) ) { String path = u.getPath(); Pattern p = Pattern.compile( dir.replace( File.separatorChar, '/' ) + PATTERN, Pattern.CASE_INSENSITIVE ); try ( JarFile jarFile = new JarFile( path.substring( 5, path.indexOf( "!/" ) ) ) ) { Enumeration jes = jarFile.entries(); while ( jes.hasMoreElements() ) { JarEntry je = jes.nextElement(); Matcher m = p.matcher( je.getName() ); if ( m.matches() ) { String s = "jar:" + path.substring( 0, path.indexOf( "!/" ) + 2 ) + je.getName(); files.add( new URL( s ) ); } } } catch ( IOException ex ) { getLog().error( ex ); } } } } } catch ( MojoExecutionException e ) { throw e; } catch ( Exception e ) { throw new MojoExecutionException( "Error while retrieving list of WSDL files to process", e ); } return files.toArray( new URL[0] ); } /** * A class used to look up .xml documents from a given directory. */ private static final FileFilter XML_FILE_FILTER = f -> f.getName().endsWith( ".xml" ); /** * A class used to look up .wsdl documents from a given directory. */ private static final FileFilter WSDL_FILE_FILTER = f -> f.getName().endsWith( ".wsdl" ); private String getRelativePath( File f ) { if ( wsdlFiles != null ) { for ( String s : wsdlFiles ) { String path = f.getPath().replace( File.separatorChar, '/' ); if ( path.endsWith( s ) && path.length() != s.length() ) { return s; } } } else if ( wsdlDirectory != null && wsdlDirectory.exists() ) { File[] wsdls = wsdlDirectory.listFiles( WSDL_FILE_FILTER ); for ( File wsdl : wsdls ) { String path = f.getPath().replace( File.separatorChar, '/' ); if ( path.endsWith( wsdl.getName() ) ) { return wsdl.getName(); } } } return null; } /** * Returns true if given WSDL resource or any binding file is newer than the staleFlag file. * * @return True if wsdl files have been modified since the last build. */ private boolean isOutputStale( String resource ) { File[] sourceBindings = getBindingFiles(); File stFile = new File( staleFile, STALE_FILE_PREFIX + getHash( resource ) ); boolean stale = !stFile.exists(); if ( !stale ) { getLog().debug( "Stale flag file exists, comparing to wsdls and bindings." ); long staleMod = stFile.lastModified(); try { // resource can be URL URL sourceWsdl = new URL( resource ); if ( sourceWsdl.openConnection().getLastModified() > staleMod ) { getLog().debug( resource + " is newer than the stale flag file." ); stale = true; } } catch ( MalformedURLException mue ) { // or a file File sourceWsdl = new File( resource ); if ( sourceWsdl.lastModified() > staleMod ) { getLog().debug( resource + " is newer than the stale flag file." ); stale = true; } } catch ( IOException ioe ) { // possible error while opening connection getLog().error( ioe ); } for ( File sourceBinding : sourceBindings ) { if ( sourceBinding.lastModified() > staleMod ) { getLog().debug( sourceBinding.getName() + " is newer than the stale flag file." ); stale = true; } } } return stale; } private void touchStaleFile( String resource ) throws IOException { File stFile = new File( staleFile, STALE_FILE_PREFIX + getHash( resource ) ); if ( !stFile.exists() ) { File staleDir = stFile.getParentFile(); if ( !staleDir.mkdirs() && !staleDir.exists() ) { getLog().warn( "Cannot create directory: " + staleDir.getAbsolutePath() ); } if ( !stFile.createNewFile() ) { getLog().warn( "Cannot create file: " + stFile.getAbsolutePath() ); } getLog().debug( "Stale flag file created.[" + stFile.getAbsolutePath() + "]" ); } else { if ( !stFile.setLastModified( System.currentTimeMillis() ) ) { getLog().warn( "Stale file has not been updated!" ); } } } private String getHash( String s ) { try ( Formatter formatter = new Formatter() ) { MessageDigest md = MessageDigest.getInstance( "SHA" ); for ( byte b : md.digest( s.getBytes( "UTF-8" ) ) ) { formatter.format( "%02x", b ); } return formatter.toString(); } catch ( UnsupportedEncodingException ex ) { getLog().debug( ex.getMessage(), ex ); } catch ( NoSuchAlgorithmException ex ) { getLog().debug( ex.getMessage(), ex ); } // fallback to some default getLog().warn( "Could not compute hash for " + s + ". Using fallback method." ); return s.substring( s.lastIndexOf( '/' ) ).replaceAll( "\\.", "-" ); } /** * @return proxy string as [user[:password]@]proxyHost[:proxyPort] or null */ static String getActiveHttpProxy( Settings s ) { String retVal = null; for ( Proxy p : s.getProxies() ) { if ( p.isActive() && "http".equals( p.getProtocol() ) ) { StringBuilder sb = new StringBuilder(); String user = p.getUsername(); String pwd = p.getPassword(); if ( user != null ) { sb.append( user ); if ( pwd != null ) { sb.append( ":" ); sb.append( pwd ); } sb.append( "@" ); } sb.append( p.getHost() ); sb.append( ":" ); sb.append( p.getPort() ); retVal = sb.toString().trim(); break; } } return retVal; } static String getActiveNonProxyHosts( Settings s ) { String retVal = null; for ( Proxy p : s.getProxies() ) { if ( p.isActive() && "http".equals( p.getProtocol() ) ) { retVal = p.getNonProxyHosts(); break; } } return retVal; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy