/*******************************************************************************
* Copyright (c) 2013 Pivotal Software, Inc.
* 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:
* Pivotal Software, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.eclipse.boot.launch.util;
import static org.springsource.ide.eclipse.commons.ui.launch.LaunchUtils.whenTerminated;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.springframework.ide.eclipse.boot.core.BootActivator;
import org.springframework.ide.eclipse.boot.launch.BootLaunchConfigurationDelegate;
import com.google.common.collect.ImmutableSet;
/**
* @author Kris De Volder
*/
public class BootLaunchUtils {
/**
* Boot aware launch termination. Tries to use JMX lifecycle managment bean if available.
*/
public static void terminate(Iterable<ILaunch> launches) {
//TODO: this terminates launches sequentially. It would be better to try to terminate all of them
// in parallel and then wait for completion of each operation.
for (ILaunch l : launches) {
try {
terminate(l);
} catch (Exception e) {
BootActivator.log(e);
}
}
}
/**
* Boot aware launch termination. Tries to use JMX lifecycle managment bean if available.
*/
public static void terminate(ILaunch l) throws DebugException, CoreException {
ILaunchConfiguration conf = l.getLaunchConfiguration();
// try {
if (conf!=null
&& conf.getType().getIdentifier().equals(BootLaunchConfigurationDelegate.TYPE_ID)
&& BootLaunchConfigurationDelegate.canUseLifeCycle(conf)
) {
SpringApplicationLifeCycleClientManager clientMgr = new SpringApplicationLifeCycleClientManager(l);
SpringApplicationLifecycleClient client = clientMgr.getLifeCycleClient();
try {
if (client!=null) {
client.stop();
whenTerminated(l).get(BootLaunchConfigurationDelegate.getTerminationTimeoutAsLong(l), TimeUnit.MILLISECONDS);
return; //Success
}
} catch (Exception e) {
//Nice termination failed. We'll ignore the exception and allow fallback to kick in.
//BootActivator.log(e);
} finally {
clientMgr.disposeClient();
}
}
// Fallback to default implementation if 'nice termination' not available.
l.terminate();
// } catch (Exception e) {
// BootActivator.log(e);
// }
}
public static IProject getProject(ILaunch launch) {
ILaunchConfiguration conf = launch.getLaunchConfiguration();
if (conf!=null) {
return BootLaunchConfigurationDelegate.getProject(conf);
}
return null;
}
public static boolean isBootLaunch(ILaunch l) {
try {
ILaunchConfiguration conf = l.getLaunchConfiguration();
if (conf!=null) {
String type = conf.getType().getIdentifier();
return BootLaunchConfigurationDelegate.TYPE_ID.equals(type);
}
} catch (Exception e) {
BootActivator.log(e);
}
return false;
}
public static boolean isDebugging(ILaunch launch) {
return ILaunchManager.DEBUG_MODE.equals(launch.getLaunchMode());
}
public static List<ILaunch> getLaunches(ILaunchConfiguration c) {
return getLaunches(ImmutableSet.of(c));
}
public static List<ILaunch> getLaunches(Set<ILaunchConfiguration> configs) {
ILaunch[] all = DebugPlugin.getDefault().getLaunchManager().getLaunches();
ArrayList<ILaunch> selected = new ArrayList<>();
for (ILaunch l : all) {
ILaunchConfiguration lConf = l.getLaunchConfiguration();
if (lConf!=null && configs.contains(lConf)) {
selected.add(l);
}
//This weird stuff below is for ngrok support in the boot dash which creates working copys that are really
// used as a kind of 'temporary proxy' for its original LaunchConfiguration.
while (lConf instanceof ILaunchConfigurationWorkingCopy) {
lConf = ((ILaunchConfigurationWorkingCopy) lConf).getOriginal();
if (configs.contains(lConf)) {
selected.add(l);
}
}
}
return selected;
}
}