Skip to main content
aboutsummaryrefslogblamecommitdiffstats
blob: 1c0c8ccd9f3dc3777b9e4f46897f0570e6acd641 (plain) (tree)
1
2
3
4
5
6
7
8
9
                                                                                
                                                       
                                                                   
                                                                        
                                                           
                                            
  

                                                       
                                                                                                   
                                                                                 

                               


                           




                                               
 
                                                 
                                                











                                                                       



                      
                                                                                                                                                   
 





                                                      
                                                                            









                                                          
                                                                      










                                                         
 


                                             

                                                    
           
                                                          
                                                      
                                       

                                               
 








                                                                              
                                                                                                      
                                                     
                                          
                             
                                        

                                                                        
         
 
           
                                          
           
                                         
                                                                     
         
 
           
                                        
           
                                            

                                                                        
 


                                                                      
                 
                                       
                                                          



                                                     
                                                                




                                                                              




                                     
                 
                                       
                                                                                       






                                                 
                 
                                              
                                                    
                                                         


                            
 
           

                                      
                 
                                          
                                                                                     
         
 


                                                     
          

                                    
                                                  
                                  

         


                                          
                 
                                                  

                                
 


                                                        
                 
                                                                    
                                         
         



                                                                      
                 
                                       


                                                                                
                                                          



                                                      
                                                                



                                                                                  





                                                                   
                 
                                                       

                                                                                                                                                           
                                                                                   
                                                                            


                                                           

















                                                                                     












                                                                    
                                    
                               
                 


                                                              
                 
                                                 




                                       
                 
                                       

                             
 
           

                                                
                 






                                                              
                 

                                                            
                                                                     
                 
                                            




                                            
                 



                                                
                                            




                                         
                 
                                                 
                                                                           
         
 


                                                         
          

                                        
                                                         
                                
         



                                                    
                 
                                                         

                                                                   
                                                   




                                                               
 


                                                       
                 
                                                            




                                                                

         


                                            
                 
                                                  

                                                                 
                                                   




                                                             
 


                                               
                 
                                                     




                                                              

         

                                                   
          









                                                                    
 






                                                           

                                                                                                                    



                 








                                                                                                                      
                                      
         
 
           

                                     
                 


                                                                                     
 
           
                                                                    
                                                                    
      

                                                                        
                 
                                        











                                                                              
                     




                                                                     
                 
                                                        

















                                                                        
               
      

                                                                         
                 
                                         











                                                                                

                                                                                   

         


                                                                                                    
                 

                                                   

                                                                      
                                                                                   




                                      
          








                                                                                                  
                 





                                                                                                    
                 



                                                   
          

                                                                        
          

                                                                                                                                         
                 


                                                                                           
                                                       






                                                                                                                                           
                 
                                                                                     

                        
          

                                                                             
          

                                                                                                                                           
                 


                                                                                    
                                                      




                                              


                                                                                                                    
                 



















                                                                                    


                                                                                   
                                      
                 
                                                   
                                                    
                                        
                 

                                                                
                                                            
                 

                                                 

 
 
 
/*******************************************************************************
 * Copyright (c) 2000, 2015 IBM Corporation and others.
 * 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:
 *     IBM Corporation - initial API and implementation
 *     Pawel Piech - Bug 82003: The IDisconnect implementation by Launch module is too restrictive.
 *******************************************************************************/
package org.eclipse.debug.core;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.PlatformObject;

import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IDisconnect;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.core.model.ISourceLocator;
import org.eclipse.debug.internal.core.DebugCoreMessages;
import org.eclipse.debug.internal.core.LaunchManager;

/**
 * A launch is the result of launching a debug session
 * and/or one or more system processes. This class provides
 * a public implementation of <code>ILaunch</code> for client
 * use.
 * <p>
 * Clients may instantiate this class. Clients may subclass this class.
 * </p>
 * @see ILaunch
 * @see ILaunchManager
 */
public class Launch extends PlatformObject implements ILaunch, IDisconnect, ILaunchListener, ILaunchConfigurationListener, IDebugEventSetListener {

	/**
	 * The debug targets associated with this
	 * launch (the primary target is the first one
	 * in this collection), or empty if
	 * there are no debug targets.
	 */
	private List<IDebugTarget> fTargets = new ArrayList<IDebugTarget>();

	/**
	 * The configuration that was launched, or null.
	 */
	private ILaunchConfiguration fConfiguration= null;

	/**
	 * The system processes associated with
	 * this launch, or empty if none.
	 */
	private List<IProcess> fProcesses = new ArrayList<IProcess>();

	/**
	 * The source locator to use in the debug session
	 * or <code>null</code> if not supported.
	 */
	private ISourceLocator fLocator= null;

	/**
	 * The mode this launch was launched in.
	 */
	private String fMode;

	/**
	 * Table of client defined attributes
	 */
	private HashMap<String, String> fAttributes;

	/**
	 * Flag indicating that change notification should
	 * be suppressed. <code>true</code> until this
	 * launch has been initialized.
	 */
	private boolean fSuppressChange = true;

	/**
	 * Constructs a launch with the specified attributes.
	 *
	 * @param launchConfiguration the configuration that was launched
	 * @param mode the mode of this launch - run or debug (constants
	 *  defined by <code>ILaunchManager</code>)
	 * @param locator the source locator to use for this debug session, or
	 * 	<code>null</code> if not supported
	 */
	public Launch(ILaunchConfiguration launchConfiguration, String mode, ISourceLocator locator) {
		fConfiguration = launchConfiguration;
		setSourceLocator(locator);
		fMode = mode;
		fSuppressChange = false;
		getLaunchManager().addLaunchListener(this);
		getLaunchManager().addLaunchConfigurationListener(this);
	}

	/**
	 * Registers debug event listener.
	 */
	private void addEventListener() {
		DebugPlugin.getDefault().addDebugEventListener(this);
	}

	/**
	 * Removes debug event listener.
	 */
	private void removeEventListener() {
		DebugPlugin.getDefault().removeDebugEventListener(this);
	}

	/**
	 * @see org.eclipse.debug.core.model.ITerminate#canTerminate()
	 */
	@Override
	public boolean canTerminate() {
		for (IProcess process : getProcesses0()) {
			if (process.canTerminate()) {
				return true;
			}
		}
		for (IDebugTarget target : getDebugTargets0()) {
			if (target.canTerminate() || target.canDisconnect()) {
				return true;
			}
		}
		return false;
	}

	/**
	 * @see ILaunch#getChildren()
	 */
	@Override
	public Object[] getChildren() {
		ArrayList<Object> children = new ArrayList<Object>(getDebugTargets0());
		children.addAll(getProcesses0());
		return children.toArray();
	}

	/**
	 * @see ILaunch#getDebugTarget()
	 */
	@Override
	public IDebugTarget getDebugTarget() {
		if (!getDebugTargets0().isEmpty()) {
			return getDebugTargets0().get(0);
		}
		return null;
	}

	/**
	 * @see ILaunch#getProcesses()
	 */
	@Override
	public IProcess[] getProcesses() {
		return getProcesses0().toArray(new IProcess[getProcesses0().size()]);
	}

	/**
	 * Returns the processes associated with this
	 * launch, in its internal form - a list.
	 *
	 * @return list of processes
	 */
	protected List<IProcess> getProcesses0() {
		return fProcesses;
	}

	/**
	 * @see ILaunch#getSourceLocator()
	 */
	@Override
	public ISourceLocator getSourceLocator() {
		return fLocator;
	}

	/**
	 * @see ILaunch#setSourceLocator(ISourceLocator)
	 */
	@Override
	public void setSourceLocator(ISourceLocator sourceLocator) {
		fLocator = sourceLocator;
	}

	/**
	 * @see org.eclipse.debug.core.model.ITerminate#isTerminated()
	 */
	@Override
	public boolean isTerminated() {
		if (getProcesses0().isEmpty() && getDebugTargets0().isEmpty()) {
			return false;
		}
		for (IProcess process : getProcesses0()) {
			if (!process.isTerminated()) {
				return false;
			}
		}
		for (IDebugTarget target : getDebugTargets0()) {
			if (!(target.isTerminated() || target.isDisconnected())) {
				return false;
			}
		}
		return true;
	}

	/**
	 * @see org.eclipse.debug.core.model.ITerminate#terminate()
	 */
	@Override
	public void terminate() throws DebugException {
		MultiStatus status=
			new MultiStatus(DebugPlugin.getUniqueIdentifier(), DebugException.REQUEST_FAILED, DebugCoreMessages.Launch_terminate_failed, null);
		//stop targets first to free up and sockets, etc held by the target
		// terminate or disconnect debug target if it is still alive
		IDebugTarget[] targets = getDebugTargets();
		for (int i = 0; i < targets.length; i++) {
			IDebugTarget target= targets[i];
			if (target != null) {
				if (target.canTerminate()) {
					try {
						target.terminate();
					} catch (DebugException e) {
						status.merge(e.getStatus());
					}
				} else {
					if (target.canDisconnect()) {
						try {
							target.disconnect();
						} catch (DebugException de) {
							status.merge(de.getStatus());
						}
					}
				}
			}
		}
		//second kill the underlying process
		// terminate the system processes
		IProcess[] processes = getProcesses();
		for (int i = 0; i < processes.length; i++) {
			IProcess process = processes[i];
			if (process.canTerminate()) {
				try {
					process.terminate();
				} catch (DebugException e) {
					status.merge(e.getStatus());
				}
			}
		}
		if (status.isOK()) {
			return;
		}
		IStatus[] children= status.getChildren();
		if (children.length == 1) {
			throw new DebugException(children[0]);
		}
		throw new DebugException(status);
	}

	/**
	 * @see ILaunch#getLaunchMode()
	 */
	@Override
	public String getLaunchMode() {
		return fMode;
	}

	/**
	 * @see ILaunch#getLaunchConfiguration()
	 */
	@Override
	public ILaunchConfiguration getLaunchConfiguration() {
		return fConfiguration;
	}

	/**
	 * @see ILaunch#setAttribute(String, String)
	 */
	@Override
	public void setAttribute(String key, String value) {
		if (fAttributes == null) {
			fAttributes = new HashMap<String, String>(5);
		}
		fAttributes.put(key, value);
	}

	/**
	 * @see ILaunch#getAttribute(String)
	 */
	@Override
	public String getAttribute(String key) {
		if (fAttributes == null) {
			return null;
		}
		return fAttributes.get(key);
	}

	/**
	 * @see ILaunch#getDebugTargets()
	 */
	@Override
	public IDebugTarget[] getDebugTargets() {
		return fTargets.toArray(new IDebugTarget[fTargets.size()]);
	}

	/**
	 * Returns the debug targets associated with this
	 * launch, in its internal form - a list
	 *
	 * @return list of debug targets
	 */
	protected List<IDebugTarget> getDebugTargets0() {
		return fTargets;
	}

	/**
	 * @see ILaunch#addDebugTarget(IDebugTarget)
	 */
	@Override
	public void addDebugTarget(IDebugTarget target) {
		if (target != null) {
			if (!getDebugTargets0().contains(target)) {
				addEventListener();
				getDebugTargets0().add(target);
				fireChanged();
			}
		}
	}

	/**
	 * @see ILaunch#removeDebugTarget(IDebugTarget)
	 */
	@Override
	public void removeDebugTarget(IDebugTarget target) {
		if (target != null) {
			if (getDebugTargets0().remove(target)) {
				fireChanged();
			}
		}
	}

	/**
	 * @see ILaunch#addProcess(IProcess)
	 */
	@Override
	public void addProcess(IProcess process) {
		if (process != null) {
			if (!getProcesses0().contains(process)) {
				addEventListener();
				getProcesses0().add(process);
				fireChanged();
			}
		}
	}

	/**
	 * @see ILaunch#removeProcess(IProcess)
	 */
	@Override
	public void removeProcess(IProcess process) {
		if (process != null) {
			if (getProcesses0().remove(process)) {
				fireChanged();
			}
		}
	}

	/**
	 * Adds the given processes to this launch.
	 *
	 * @param processes processes to add
	 */
	protected void addProcesses(IProcess[] processes) {
		if (processes != null) {
			for (int i = 0; i < processes.length; i++) {
				addProcess(processes[i]);
				fireChanged();
			}
		}
	}

	/**
	 * Notifies listeners that this launch has changed.
	 * Has no effect of this launch has not yet been
	 * properly created/initialized.
	 */
	protected void fireChanged() {
		if (!fSuppressChange) {
			((LaunchManager)getLaunchManager()).fireUpdate(this, LaunchManager.CHANGED);
			((LaunchManager)getLaunchManager()).fireUpdate(new ILaunch[] {this}, LaunchManager.CHANGED);
		}
	}

	/**
	 * Notifies listeners that this launch has terminated.
	 * Has no effect of this launch has not yet been
	 * properly created/initialized.
	 */
	protected void fireTerminate() {
		if (!fSuppressChange) {
			((LaunchManager)getLaunchManager()).fireUpdate(this, LaunchManager.TERMINATE);
			((LaunchManager)getLaunchManager()).fireUpdate(new ILaunch[] {this}, LaunchManager.TERMINATE);
		}
		removeEventListener();
	}

	/**
	 * @see ILaunch#hasChildren()
	 */
	@Override
	public boolean hasChildren() {
		return getProcesses0().size() > 0 || (getDebugTargets0().size() > 0);
	}

	/**
     * Returns whether any processes or targets can be disconnected.
     * Ones that are already terminated or disconnected are ignored.
     *
	 * @see org.eclipse.debug.core.model.IDisconnect#canDisconnect()
	 */
	@Override
	public boolean canDisconnect() {
		for (IProcess process : getProcesses0()) {
			if (process instanceof IDisconnect) {
				if (((IDisconnect) process).canDisconnect()) {
					return true;
				}
			}
		}
		for (IDebugTarget target : getDebugTargets0()) {
			if (target.canDisconnect()) {
				return true;
			}
		}
        return false;
	}

	/**
	 * @see org.eclipse.debug.core.model.IDisconnect#disconnect()
	 */
	@Override
	public void disconnect() throws DebugException {
		for (IProcess process : getProcesses0()) {
			if (process instanceof IDisconnect) {
				IDisconnect dis = (IDisconnect) process;
				if (dis.canDisconnect()) {
					dis.disconnect();
				}
			}
		}
		for (IDebugTarget target : getDebugTargets0()) {
			if (target.canDisconnect()) {
				target.disconnect();
			}
		}
	}

	/**
     * Returns whether all of the contained targets and processes are
     * disconnected. Processes that don't support disconnecting are not
     * counted.
     *
	 * @see org.eclipse.debug.core.model.IDisconnect#isDisconnected()
	 */
	@Override
	public boolean isDisconnected() {
		for (IProcess process : getProcesses0()) {
			if (process instanceof IDisconnect) {
				if (!((IDisconnect) process).isDisconnected()) {
					return false;
				}
			}
		}
		for (IDebugTarget target : getDebugTargets0()) {
			if (!target.isDisconnected()) {
				return false;
			}
		}
        // only return true if there are processes or targets that are disconnected
        return hasChildren();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.ILaunchListener#launchRemoved(org.eclipse.debug.core.ILaunch)
	 */
	@Override
	public void launchRemoved(ILaunch launch) {
		if (this.equals(launch)) {
			removeEventListener();
			getLaunchManager().removeLaunchListener(this);
			getLaunchManager().removeLaunchConfigurationListener(this);
		}
	}

	/**
	 * Returns the launch manager.
	 *
	 * @return the launch manager.
	 */
	protected ILaunchManager getLaunchManager() {
		return DebugPlugin.getDefault().getLaunchManager();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.ILaunchListener#launchAdded(org.eclipse.debug.core.ILaunch)
	 */
	@Override
	public void launchAdded(ILaunch launch) {
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.ILaunchListener#launchChanged(org.eclipse.debug.core.ILaunch)
	 */
	@Override
	public void launchChanged(ILaunch launch) {
	}

	/* (non-Javadoc)
	 *
	 * If the launch configuration this launch is associated with is
	 * moved, update the underlying handle to the new location.
	 *
	 * @see org.eclipse.debug.core.ILaunchConfigurationListener#launchConfigurationAdded(org.eclipse.debug.core.ILaunchConfiguration)
	 */
	@Override
	public void launchConfigurationAdded(ILaunchConfiguration configuration) {
		ILaunchConfiguration from = getLaunchManager().getMovedFrom(configuration);
		if (from != null && from.equals(getLaunchConfiguration())) {
			fConfiguration = configuration;
			fireChanged();
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.ILaunchConfigurationListener#launchConfigurationChanged(org.eclipse.debug.core.ILaunchConfiguration)
	 */
	@Override
	public void launchConfigurationChanged(ILaunchConfiguration configuration) {}

	/* (non-Javadoc)
	 *
	 * Update the launch configuration associated with this launch if the
	 * underlying configuration is deleted.
	 *
	 * @see org.eclipse.debug.core.ILaunchConfigurationListener#launchConfigurationRemoved(org.eclipse.debug.core.ILaunchConfiguration)
	 */
	@Override
	public void launchConfigurationRemoved(ILaunchConfiguration configuration) {
		if (configuration.equals(getLaunchConfiguration())) {
			if (getLaunchManager().getMovedTo(configuration) == null) {
				fConfiguration = null;
				fireChanged();
			}
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.IDebugEventSetListener#handleDebugEvents(org.eclipse.debug.core.DebugEvent[])
	 */
	@Override
	public void handleDebugEvents(DebugEvent[] events) {
		for (int i = 0; i < events.length; i++) {
			DebugEvent event = events[i];
			if (event.getKind() == DebugEvent.TERMINATE) {
				Object object = event.getSource();
				ILaunch launch = null;
				if (object instanceof IProcess) {
					launch = ((IProcess)object).getLaunch();
				} else if (object instanceof IDebugTarget) {
					launch = ((IDebugTarget)object).getLaunch();
				}
				if (this.equals(launch)) {
					if (isTerminated()) {
						fireTerminate();
					}
				}
			}
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.core.runtime.PlatformObject#getAdapter(java.lang.Class)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public <T> T getAdapter(Class<T> adapter) {
		if (adapter.equals(ILaunch.class)) {
			return (T) this;
		}
		//CONTEXTLAUNCHING
		if(adapter.equals(ILaunchConfiguration.class)) {
			return (T) getLaunchConfiguration();
		}
		return super.getAdapter(adapter);
	}



}

Back to the top