/*******************************************************************************
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
*******************************************************************************/
package com.liferay.ide.core.util;
import com.liferay.ide.core.LiferayRuntimeClasspathEntry;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IDebugEventSetListener;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.JavaRuntime;
/**
* @author Greg Amerson
* @author Simon Jiang
*/
public class LaunchHelper implements IDebugEventSetListener
{
protected String[] launchArgs = new String[0];
protected boolean launchCaptureInConsole = true;
protected String launchConfigTypeId;
protected boolean launchInBackground = true;
protected boolean launchIsPrivate = true;
protected boolean launchSync = true;
protected String mainClass;
protected String mode = ILaunchManager.RUN_MODE;
protected ILaunch runningLaunch;
public LaunchHelper()
{
}
public LaunchHelper( String launchConfigTypeId )
{
this.launchConfigTypeId = launchConfigTypeId;
}
public ILaunchConfigurationWorkingCopy createLaunchConfiguration() throws CoreException
{
ILaunchManager manager = DebugPlugin.getDefault().getLaunchManager();
ILaunchConfigurationType type = manager.getLaunchConfigurationType( this.launchConfigTypeId );
String name =
DebugPlugin.getDefault().getLaunchManager().generateLaunchConfigurationName(
getNewLaunchConfigurationName() );
ILaunchConfigurationWorkingCopy launchConfig = type.newInstance( null, name );
launchConfig.setAttribute( "org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND", isLaunchInBackground() ); //$NON-NLS-1$
launchConfig.setAttribute( "org.eclipse.debug.ui.ATTR_CAPTURE_IN_CONSOLE", isLaunchCaptureInConsole() ); //$NON-NLS-1$
launchConfig.setAttribute( "org.eclipse.debug.ui.ATTR_PRIVATE", isLaunchIsPrivate() ); //$NON-NLS-1$
IRuntimeClasspathEntry[] classpath = getClasspath( launchConfig );
List<String> mementos = new ArrayList<String>( classpath.length );
for( int i = 0; i < classpath.length; i++ )
{
IRuntimeClasspathEntry entry = classpath[i];
mementos.add( entry.getMemento() );
}
launchConfig.setAttribute( IJavaLaunchConfigurationConstants.ATTR_DEFAULT_CLASSPATH, false );
launchConfig.setAttribute( IJavaLaunchConfigurationConstants.ATTR_CLASSPATH, mementos );
if( getMainClass() != null )
{
launchConfig.setAttribute( IJavaLaunchConfigurationConstants.ATTR_MAIN_TYPE_NAME, getMainClass() );
}
if( launchArgs != null && launchArgs.length > 0 )
{
StringBuilder sb = new StringBuilder();
for( int i = 0; i < launchArgs.length; i++ )
{
sb.append( "\"" + launchArgs[i] + "\" " ); //$NON-NLS-1$ //$NON-NLS-2$
}
launchConfig.setAttribute( IJavaLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS, sb.toString() );
}
return launchConfig;
}
public String[] getLaunchArgs()
{
return launchArgs;
}
public String getMainClass()
{
return mainClass;
}
public String getMode()
{
return mode;
}
@Override
public void handleDebugEvents( DebugEvent[] events )
{
for( DebugEvent event : events )
{
if( event.getSource() instanceof IProcess )
{
if( ( (IProcess) event.getSource() ).getLaunch().equals( this.runningLaunch ) &&
event.getKind() == DebugEvent.TERMINATE )
{
synchronized( this )
{
DebugPlugin.getDefault().removeDebugEventListener( this );
// launchRunning = false;
}
}
}
}
}
public boolean isLaunchCaptureInConsole()
{
return launchCaptureInConsole;
}
public boolean isLaunchInBackground()
{
return launchInBackground;
}
public boolean isLaunchIsPrivate()
{
return launchIsPrivate;
}
public boolean isLaunchRunning()
{
return this.runningLaunch != null && !this.runningLaunch.isTerminated() &&
!this.runningLaunch.getProcesses()[0].isTerminated();
}
public boolean isLaunchSync()
{
return this.launchSync;
}
public int launch( final ILaunchConfiguration config, final String mode, IProgressMonitor monitor ) throws CoreException
{
if( config == null )
{
throw new IllegalArgumentException( "Launch config cannot be null" ); //$NON-NLS-1$
}
if( isLaunchSync() )
{
DebugPlugin.getDefault().addDebugEventListener( this );
}
final ILaunch launch = config.launch( mode, new NullProgressMonitor() );
final IProcess process = launch.getProcesses()[0];
if( isLaunchSync() )
{
runningLaunch = launch;
try
{
while( isLaunchRunning() )
{
if( monitor != null && monitor.isCanceled() && !launch.isTerminated() )
{
process.terminate();
launch.terminate();
}
else
{
Thread.sleep( 100 );
}
}
}
catch( InterruptedException e )
{
runningLaunch.terminate();
}
finally
{
runningLaunch = null;
}
}
return isLaunchSync() ? process.getExitValue() : 0;
}
public int launch( IProgressMonitor monitor ) throws CoreException
{
final ILaunchConfigurationWorkingCopy config = createLaunchConfiguration();
return launch( config, mode, monitor );
}
public void setLaunchArgs( String[] launchArgs )
{
this.launchArgs = launchArgs;
}
public void setLaunchCaptureInConsole( boolean launchCaptureInConsole )
{
this.launchCaptureInConsole = launchCaptureInConsole;
}
public void setLaunchInBackground( boolean launchInBackground )
{
this.launchInBackground = launchInBackground;
}
public void setLaunchIsPrivate( boolean launchIsPrivate )
{
this.launchIsPrivate = launchIsPrivate;
}
public void setLaunchSync( boolean sync )
{
this.launchSync = sync;
}
public void setMainClass( String mainClass )
{
this.mainClass = mainClass;
}
public void setMode( String mode )
{
this.mode = mode;
}
protected void addUserEntries( RuntimeClasspathModel model ) throws CoreException
{
}
protected IRuntimeClasspathEntry[] getClasspath( ILaunchConfigurationWorkingCopy config ) throws CoreException
{
RuntimeClasspathModel model = new RuntimeClasspathModel( config );
config.setAttribute(
IJavaLaunchConfigurationConstants.ATTR_CLASSPATH_PROVIDER, getClasspathProviderAttributeValue() );
config.setAttribute( IJavaLaunchConfigurationConstants.ATTR_DEFAULT_CLASSPATH, true );
IRuntimeClasspathEntry[] defaultEntries = JavaRuntime.computeUnresolvedRuntimeClasspath( config );
IRuntimeClasspathEntry entry;
for( int i = 0; i < defaultEntries.length; i++ )
{
entry = defaultEntries[i];
switch( entry.getClasspathProperty() )
{
case IRuntimeClasspathEntry.USER_CLASSES:
model.addEntry( RuntimeClasspathModel.USER, entry );
break;
default:
break;
}
}
addUserEntries( model );
return getClasspathEntries( model );
}
protected IRuntimeClasspathEntry[] getClasspathEntries( RuntimeClasspathModel model )
{
// IClasspathEntry[] boot = model.getEntries( RuntimeClasspathModel.BOOTSTRAP, model.getConfig() );
IClasspathEntry[] user = model.getEntries( RuntimeClasspathModel.USER, model.getConfig() );
List<IRuntimeClasspathEntry> entries = new ArrayList<IRuntimeClasspathEntry>(); //boot.length + user.length );
// IClasspathEntry bootEntry;
IRuntimeClasspathEntry entry;
// for( int i = 0; i < boot.length; i++ )
// {
// bootEntry = boot[i];
//
// entry = null;
//
// if( bootEntry instanceof IRuntimeClasspathEntry )
// {
// entry = (IRuntimeClasspathEntry) boot[i];
// }
//
// if( entry != null )
// {
// if( entry.getClasspathProperty() == IRuntimeClasspathEntry.USER_CLASSES )
// {
// entry.setClasspathProperty( IRuntimeClasspathEntry.BOOTSTRAP_CLASSES );
// }
//
// entries.add( entry );
// }
// }
IClasspathEntry userEntry;
for( int i = 0; i < user.length; i++ )
{
userEntry = user[i];
entry = null;
if( userEntry instanceof IRuntimeClasspathEntry )
{
entry = (IRuntimeClasspathEntry) user[i];
}
else if( userEntry instanceof IClasspathEntry )
{
entry = new LiferayRuntimeClasspathEntry( userEntry );
}
if( entry != null )
{
entry.setClasspathProperty( IRuntimeClasspathEntry.USER_CLASSES );
entries.add( entry );
}
}
return entries.toArray( new IRuntimeClasspathEntry[entries.size()] );
}
protected String getClasspathProviderAttributeValue()
{
return null;
}
protected IVMInstall getDefaultVMInstall( ILaunchConfiguration config )
{
IVMInstall defaultVMInstall;
try
{
defaultVMInstall = JavaRuntime.computeVMInstall( config );
}
catch( CoreException e )
{
// core exception thrown for non-Java project
defaultVMInstall = JavaRuntime.getDefaultVMInstall();
}
return defaultVMInstall;
}
protected String getNewLaunchConfigurationName()
{
return this.getClass().getName();
}
}