/******************************************************************************* * Copyright (c) 2015 Pivotal, 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, Inc. - initial API and implementation *******************************************************************************/ package org.springframework.ide.eclipse.boot.launch.util; import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationType; import org.eclipse.debug.core.ILaunchManager; import org.springframework.ide.eclipse.boot.core.BootActivator; import org.springframework.ide.eclipse.boot.launch.BootLaunchConfigurationDelegate; import org.springframework.ide.eclipse.boot.launch.devtools.BootDevtoolsClientLaunchConfigurationDelegate; import org.springsource.ide.eclipse.commons.frameworks.core.ExceptionUtil; import org.springsource.ide.eclipse.commons.frameworks.core.workspace.ProjectDeletionListenerManager; import org.springsource.ide.eclipse.commons.frameworks.core.workspace.ProjectDeletionListenerManager.ProjectDeletionListener; import org.springsource.ide.eclipse.commons.frameworks.core.util.JobUtil; /** * When projects are deleted, also deletes corresponding local launch configs. * * @author Kris De Volder */ public class BootLaunchConfDeleter { private ILaunchManager launchMan; private ProjectDeletionListenerManager listenerManager; private static final ISchedulingRule RULE = JobUtil.lightRule("LaunchConfDeleteRule"); private String[] TYPE_IDS = { BootLaunchConfigurationDelegate.TYPE_ID, BootDevtoolsClientLaunchConfigurationDelegate.TYPE_ID }; public BootLaunchConfDeleter(IWorkspace workspace, ILaunchManager launchMan) { this.launchMan = launchMan; this.listenerManager = new ProjectDeletionListenerManager(workspace, new ProjectDeletionListener() { @Override public void projectWasDeleted(IProject project) { handleDelete(project); } }); } private void handleDelete(IProject project) { final List<ILaunchConfiguration> confs = getDeletableLaunchConfigs(project); if (confs!=null && !confs.isEmpty()) { Job deleteJob = new Job("Delete launch configs for "+project.getName()) { @Override protected IStatus run(IProgressMonitor monitor) { try { for (ILaunchConfiguration c : confs) { c.delete(); } return Status.OK_STATUS; } catch (Exception e) { return ExceptionUtil.status(e); } } }; //what rule should we use here? Something less aggressive?? deleteJob.setRule(RULE); //In case many projects deleted in a burst... avoid concurrency issues. deleteJob.schedule(); } } private List<ILaunchConfiguration> getDeletableLaunchConfigs(IProject project) { List<ILaunchConfiguration> configs = new ArrayList<>(); for (String typeId : TYPE_IDS) { try { ILaunchConfigurationType type = launchMan.getLaunchConfigurationType(typeId); for (ILaunchConfiguration conf : launchMan.getLaunchConfigurations(type)) { if ( project.equals(BootLaunchConfigurationDelegate.getProject(conf)) && isDeletable(conf) ) { configs.add(conf); } } } catch (Exception e) { BootActivator.log(e); } } return configs; } private boolean isDeletable(ILaunchConfiguration conf) { return conf.exists() && conf.isLocal(); } public void dispose() { listenerManager.dispose(); } }