/******************************************************************************
* Copyright (c) 2010-2013, Linagora
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Linagora - initial API and implementation
*******************************************************************************/
package com.ebmwebsourcing.petals.common.extensions.internal.provisional;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Enumeration;
import java.util.List;
import org.apache.cxf.tools.java2ws.JavaToWS;
import org.apache.cxf.tools.wsdlto.WSDLToJava;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.IStreamListener;
import org.eclipse.debug.core.Launch;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.core.model.IStreamMonitor;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.IVMRunner;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.launching.VMRunnerConfiguration;
import org.osgi.framework.Bundle;
import com.ebmwebsourcing.petals.common.extensions.PetalsCommonWsdlExtPlugin;
import com.ebmwebsourcing.petals.common.internal.provisional.preferences.PreferencesManager;
import com.ebmwebsourcing.petals.common.internal.provisional.utils.IoUtils;
import com.ebmwebsourcing.petals.common.internal.provisional.utils.JavaUtils;
import com.ebmwebsourcing.petals.common.internal.provisional.utils.StringUtils;
/**
* A set of utility methods for WSDL and based on an external library (e.g. CXF).
* @author Vincent Zurczak - EBM WebSourcing
*/
public class WsdlExtUtils {
/**
* Generates a WSDL from a class that is located inside a Java project.
* @param wsdlName
* @param className
* @param outputDirectoryName
* @param jp
* @return the WSDL file (may not exist in case of error)
* FIXME: do we need to capture this kind of error?
*/
public static File generateWsdlFile(
String wsdlName,
String className,
String outputDirectoryName,
IJavaProject jp ) {
List<String> classpath = JavaUtils.getClasspath( jp, true, true );
String[] classPathDirectories = new String[ classpath.size()];
return generateWsdlFile(
wsdlName,
outputDirectoryName,
className,
classpath.toArray( classPathDirectories ),
outputDirectoryName,
null,
null,
new NullProgressMonitor()); // TODO replace by a provided monitor
}
/**
* Generates a WSDL file from a class with a specified class path.
* @param wsdlName
* @param outputDestination
* @param className
* @param classPathDirectories
* @param buildDirectory
* @param endpointName
* @param serviceName
* @param monitor
* @return the WSDL file (may not exist in case of error)
* FIXME: do we need to capture this kind of error?
*/
public static File generateWsdlFile(
String wsdlName,
String outputDestination,
String className,
String[] classPathDirectories,
String buildDirectory,
String endpointName,
String serviceName,
IProgressMonitor monitor ) {
final boolean logCxf = PreferencesManager.logAllCXFTraces();
List<String> arguments = new ArrayList<String> ();
List<String> classpath = new ArrayList<String> ();
classpath.addAll( Arrays.asList( classPathDirectories ));
classpath.addAll( getCXFLibs());
arguments.add( "-wsdl" );
if( logCxf )
arguments.add( "-verbose" );
else
arguments.add( "-quiet" );
arguments.add( "-o" );
arguments.add( wsdlName );
if( serviceName != null ) {
arguments.add( "-servicename" );
arguments.add( serviceName );
}
if( endpointName != null ) {
arguments.add( "-portname" );
arguments.add( endpointName );
}
arguments.add( "-createxsdimports" );
arguments.add( "-d" ); //$NON-NLS-1$
arguments.add( outputDestination );
arguments.add(className);
final StringBuilder sb = new StringBuilder();
try {
// Run CXF in a separate process
IVMInstall vmInstall = JavaRuntime.getDefaultVMInstall();
IVMRunner vmRunner = vmInstall.getVMRunner( ILaunchManager.RUN_MODE );
VMRunnerConfiguration vmRunnerConfiguration = new VMRunnerConfiguration(
JavaToWS.class.getName(),
classpath.toArray( new String[ classpath.size()]));
vmRunnerConfiguration.setProgramArguments( arguments.toArray( new String[ arguments.size()]));
// Create the launch
final IStreamListener streamListener = new IStreamListener() {
@Override
public void streamAppended( String text, IStreamMonitor monitor ) {
if( ! StringUtils.isEmpty( text ))
sb.append( text + "\n" );
}
};
ILaunch launch = new Launch(null, ILaunchManager.RUN_MODE, null) {
@Override
public void addProcess( IProcess process ) {
super.addProcess( process );
try {
process.getStreamsProxy().getErrorStreamMonitor().addListener( streamListener );
process.getStreamsProxy().getOutputStreamMonitor().addListener( streamListener );
} catch( Exception e ) {
PetalsCommonWsdlExtPlugin.log( e, IStatus.WARNING );
}
}
};
// Start the execution
vmRunner.run( vmRunnerConfiguration, launch, monitor );
// Wait for the Java process to have completed its work
for( int i=0; i<10; i++ ) {
if( launch.isTerminated())
break;
Thread.sleep( 1000 );
}
} catch( Exception e ) {
PetalsCommonWsdlExtPlugin.log( e, IStatus.ERROR );
} finally {
if( logCxf ) {
Exception e = new Exception( sb.toString());
String msg = "CXF Logs for a Java to WSDL conversion.\n";
PetalsCommonWsdlExtPlugin.log( e, IStatus.INFO, msg );
}
}
return new File( outputDestination, wsdlName );
}
/**
* @return the CXF libraries
*/
private static Collection<? extends String> getCXFLibs() {
List<String> res = new ArrayList<String>();
Bundle cxfBundle = Platform.getBundle( "com.ebmwebsourcing.petals.libs.cxf" );
Enumeration<URL> cxfLibs = cxfBundle.findEntries( "lib", "*", false );
URL currentLib = null;
while( cxfLibs.hasMoreElements()) {
currentLib = cxfLibs.nextElement();
try {
URL url = FileLocator.toFileURL( currentLib );
if( ! url.toString().endsWith( ".jar" ))
continue;
File f = IoUtils.convertToFile( url.toString());
String path = f != null ? f.getAbsolutePath() : null;
if( path != null )
res.add( path );
else
PetalsCommonWsdlExtPlugin.log( "A CXF library could not be resolved as a file: " + url, IStatus.ERROR );
} catch( Exception ex ) {
PetalsCommonWsdlExtPlugin.log(ex, IStatus.ERROR);
}
}
return res;
}
/**
* Generates a Java interface from a WSDL definition.
* @param wsdlUri the WSDL URI.
* @param outputDestination the directory where the Java files must be generated
*/
public static void generateJavaCode( String wsdlUri, String outputDestination ) {
List<String> arguments = new ArrayList<String> ();
arguments.add( "-autoNameResolution" ); //$NON-NLS-1$
arguments.add( "-quiet" ); //$NON-NLS-1$
arguments.add( "-d" ); //$NON-NLS-1$
arguments.add( outputDestination );
arguments.add( wsdlUri );
String[] args = new String[ arguments.size()];
try {
// TODO in case of issue: replace with a VMRunner (cf generateWSDLFile)
WSDLToJava.main( arguments.toArray( args ));
} catch( Exception e ) {
PetalsCommonWsdlExtPlugin.log( e, IStatus.ERROR );
}
}
/**
* Generates a Java client for a Web Service.
* @param wsdlUri the WSDL URI.
* @param outputDestination the directory where the Java files must be generated
*/
public static void generateWebServiceClient( String wsdlUri, String outputDestination ) {
List<String> arguments = new ArrayList<String> ();
arguments.add( "-autoNameResolution" ); //$NON-NLS-1$
arguments.add( "-quiet" ); //$NON-NLS-1$
arguments.add( "-client" ); //$NON-NLS-1$
arguments.add( "-d" ); //$NON-NLS-1$
arguments.add( outputDestination );
arguments.add( wsdlUri );
String[] args = new String[ arguments.size()];
try {
// TODO in case of issue: replace with a VMRunner (cf generateWSDLFile)
WSDLToJava.main( arguments.toArray( args ));
} catch( Exception e ) {
PetalsCommonWsdlExtPlugin.log( e, IStatus.ERROR );
}
}
}