package com.codeaffine.extras.launch.internal.cleanup; import static com.codeaffine.extras.launch.internal.LaunchExtrasPlugin.PLUGIN_ID; import static java.util.Collections.addAll; import static java.util.Collections.synchronizedSet; import java.io.File; import java.util.ArrayList; import java.util.HashSet; import java.util.Objects; import java.util.Set; import java.util.stream.Stream; import org.eclipse.core.runtime.CoreException; import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationListener; import org.eclipse.debug.core.ILaunchConfigurationType; import org.eclipse.debug.core.ILaunchManager; import org.eclipse.debug.internal.ui.launchConfigurations.LaunchConfigurationsDialog; import org.eclipse.ui.statushandlers.StatusManager; import com.codeaffine.extras.launch.internal.util.LaunchAdapter; @SuppressWarnings("restriction") public class LaunchConfigCleaner { private final LaunchPreferences launchPreferences; private final ILaunchManager launchManager; private final Set<ILaunchConfiguration> cleanupLaunchConfigs; private final CleanupLaunchConfigListener cleanupLaunchConfigListener; private final CleanupLaunchListener cleanupLaunchListener; public LaunchConfigCleaner() { this( new LaunchPreferences() ); } public LaunchConfigCleaner( LaunchPreferences launchPreferences ) { this.launchPreferences = launchPreferences; this.launchManager = DebugPlugin.getDefault().getLaunchManager(); this.cleanupLaunchConfigs = synchronizedSet( new HashSet<>() ); this.cleanupLaunchConfigListener = new CleanupLaunchConfigListener(); this.cleanupLaunchListener = new CleanupLaunchListener(); } public void install() { launchManager.addLaunchConfigurationListener( cleanupLaunchConfigListener ); launchManager.addLaunchListener( cleanupLaunchListener ); } public void uninstall() { launchManager.removeLaunchConfigurationListener( cleanupLaunchConfigListener ); launchManager.removeLaunchListener( cleanupLaunchListener ); cleanupLaunchConfigs.clear(); } public void saveState( File file ) { ILaunchConfiguration[] launchConfigs = cleanupLaunchConfigs.toArray( new ILaunchConfiguration[ 0 ] ); new LaunchConfigCleanerState( launchManager, file ).save( launchConfigs ); } public void restoreState( File file ) { ILaunchConfiguration[] launchConfigs = new LaunchConfigCleanerState( launchManager, file ).restore(); addAll( cleanupLaunchConfigs, launchConfigs ); } private static void handleCoreException( CoreException exception ) { StatusManager.getManager().handle( exception, PLUGIN_ID ); } private class CleanupLaunchListener extends LaunchAdapter { @Override public void launchesTerminated( ILaunch[] launches ) { for( ILaunch launch : launches ) { launchTerminated( launch ); } } private void launchTerminated( ILaunch launch ) { ILaunchConfiguration terminatedLaunchConfig = launch.getLaunchConfiguration(); if( terminatedLaunchConfig != null ) { try { launchTerminated( terminatedLaunchConfig ); } catch( CoreException ce ) { handleCoreException( ce ); } } } private void launchTerminated( ILaunchConfiguration terminatedLaunchConfig ) throws CoreException { for( ILaunchConfiguration launchConfig : new ArrayList<>( cleanupLaunchConfigs ) ) { if( launchConfig.getType().equals( terminatedLaunchConfig.getType() ) && !isStoredInWorkspace( launchConfig ) && !launchConfig.equals( terminatedLaunchConfig ) ) { cleanupLaunchConfigs.remove( launchConfig ); launchConfig.delete(); } } } private boolean isStoredInWorkspace( ILaunchConfiguration launchConfig ) { return launchConfig.getFile() != null; } } private class CleanupLaunchConfigListener implements ILaunchConfigurationListener { @Override public void launchConfigurationAdded( ILaunchConfiguration launchConfig ) { try { if( launchPreferences.isCleanupGeneratedLaunchConfigs() && !isLaunchConfigsDialogOpen() && shouldCleanupLaunchConfig( launchConfig ) ) { cleanupLaunchConfigs.add( launchConfig ); } } catch( CoreException ce ) { handleCoreException( ce ); } } @Override public void launchConfigurationChanged( ILaunchConfiguration launchConfig ) { if( isLaunchConfigsDialogOpen() ) { cleanupLaunchConfigs.remove( launchConfig ); } } @Override public void launchConfigurationRemoved( ILaunchConfiguration launchConfig ) { cleanupLaunchConfigs.remove( launchConfig ); } private boolean shouldCleanupLaunchConfig( ILaunchConfiguration configuration ) throws CoreException { String typeId = configuration.getType().getIdentifier(); ILaunchConfigurationType[] types = getCleanupGenerateLaunchConfigTypes(); return Stream.of( types ).anyMatch( type -> Objects.equals( type.getIdentifier(), typeId ) ); } private ILaunchConfigurationType[] getCleanupGenerateLaunchConfigTypes() { String typeIds = launchPreferences.getCleanupGenerateLaunchConfigTypes(); return new LaunchConfigTypeSerializer( launchManager ).deserialize( typeIds ); } private boolean isLaunchConfigsDialogOpen() { return LaunchConfigurationsDialog.getCurrentlyVisibleLaunchConfigurationDialog() != null; } } }