cdt/cdt_5_0_x/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/core/executables/StandardExecutableProvider.java
changeset 14 c50c3d06898c
parent 0 0e6d23e2b466
equal deleted inserted replaced
8:2cfb52d98e82 14:c50c3d06898c
    10  *******************************************************************************/
    10  *******************************************************************************/
    11 
    11 
    12 package org.eclipse.cdt.debug.core.executables;
    12 package org.eclipse.cdt.debug.core.executables;
    13 
    13 
    14 import java.util.ArrayList;
    14 import java.util.ArrayList;
       
    15 import java.util.List;
    15 
    16 
       
    17 import org.eclipse.cdt.core.CCProjectNature;
       
    18 import org.eclipse.cdt.core.CProjectNature;
    16 import org.eclipse.cdt.core.model.CModelException;
    19 import org.eclipse.cdt.core.model.CModelException;
    17 import org.eclipse.cdt.core.model.CoreModel;
       
    18 import org.eclipse.cdt.core.model.IBinary;
    20 import org.eclipse.cdt.core.model.IBinary;
    19 import org.eclipse.cdt.core.model.ICProject;
    21 import org.eclipse.cdt.core.model.ICProject;
    20 import org.eclipse.cdt.core.settings.model.CProjectDescriptionEvent;
       
    21 import org.eclipse.cdt.core.settings.model.ICProjectDescription;
       
    22 import org.eclipse.cdt.core.settings.model.ICProjectDescriptionListener;
       
    23 import org.eclipse.cdt.debug.core.CDebugCorePlugin;
    22 import org.eclipse.cdt.debug.core.CDebugCorePlugin;
    24 import org.eclipse.cdt.internal.core.model.CModelManager;
    23 import org.eclipse.cdt.internal.core.model.CModelManager;
    25 import org.eclipse.core.resources.IProject;
    24 import org.eclipse.core.resources.IProject;
    26 import org.eclipse.core.resources.IResource;
    25 import org.eclipse.core.resources.IResource;
    27 import org.eclipse.core.resources.IResourceChangeEvent;
       
    28 import org.eclipse.core.resources.IResourceChangeListener;
       
    29 import org.eclipse.core.resources.IResourceDelta;
       
    30 import org.eclipse.core.resources.IResourceDeltaVisitor;
       
    31 import org.eclipse.core.resources.IWorkspaceRoot;
       
    32 import org.eclipse.core.resources.ResourcesPlugin;
       
    33 import org.eclipse.core.runtime.CoreException;
    26 import org.eclipse.core.runtime.CoreException;
    34 import org.eclipse.core.runtime.IPath;
    27 import org.eclipse.core.runtime.IPath;
    35 import org.eclipse.core.runtime.IProgressMonitor;
    28 import org.eclipse.core.runtime.IProgressMonitor;
    36 import org.eclipse.core.runtime.IStatus;
    29 import org.eclipse.core.runtime.IStatus;
    37 import org.eclipse.core.runtime.Status;
    30 import org.eclipse.core.runtime.Status;
       
    31 import org.eclipse.core.runtime.SubMonitor;
    38 import org.eclipse.debug.core.DebugPlugin;
    32 import org.eclipse.debug.core.DebugPlugin;
    39 
    33 
    40 public class StandardExecutableProvider implements IResourceChangeListener, ICProjectDescriptionListener, IExecutableProvider {
    34 public class StandardExecutableProvider implements IProjectExecutablesProvider {
    41 
    35 
    42 	private ArrayList<Executable> executables = new ArrayList<Executable>();
    36 	List<String> supportedNatureIds = new ArrayList<String>();
    43 
    37 	
    44 	public StandardExecutableProvider() {
    38 	public StandardExecutableProvider() {
    45 		ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.POST_CHANGE);
    39 		supportedNatureIds.add(CProjectNature.C_NATURE_ID);
    46 		CoreModel.getDefault().getProjectDescriptionManager().addCProjectDescriptionListener(this,
    40 		supportedNatureIds.add(CCProjectNature.CC_NATURE_ID);
    47 				CProjectDescriptionEvent.DATA_APPLIED | CProjectDescriptionEvent.LOADED);
    41 	}
       
    42 	
       
    43 	public List<String> getProjectNatures() {
       
    44 		return supportedNatureIds;
    48 	}
    45 	}
    49 
    46 
    50 	public void resourceChanged(IResourceChangeEvent event) {
    47 	public List<Executable> getExecutables(IProject project, IProgressMonitor monitor) {
       
    48 		List<Executable> executables = new ArrayList<Executable>();
       
    49 		
       
    50 		ICProject cproject = CModelManager.getDefault().create(project);
       
    51 		try {
       
    52 			IBinary[] binaries = cproject.getBinaryContainer().getBinaries();
    51 
    53 
    52 		// refresh when projects are opened or closed. note that deleted
    54 			SubMonitor progress = SubMonitor.convert(monitor, binaries.length);
    53 		// projects are handled later
    55 
    54 		// in this method. new projects are handled in handleEvent.
    56 			for (IBinary binary : binaries) {
    55 		// resource changed events always start at the workspace root, so
    57 				if (progress.isCanceled()) {
    56 		// projects
    58 					break;
    57 		// are the next level down
       
    58 		IResourceDelta[] projects = event.getDelta().getAffectedChildren();
       
    59 		for (IResourceDelta projectDelta : projects) {
       
    60 			if ((projectDelta.getFlags() & IResourceDelta.OPEN) != 0) {
       
    61 				if (projectDelta.getKind() == IResourceDelta.CHANGED) {
       
    62 					// project was opened or closed
       
    63 					ExecutablesManager.getExecutablesManager().scheduleRefresh(this, 0);
       
    64 					return;
       
    65 				}
    59 				}
       
    60 
       
    61 				if (binary.isExecutable() || binary.isSharedLib()) {
       
    62 					IPath exePath = binary.getResource().getLocation();
       
    63 					if (exePath == null)
       
    64 						exePath = binary.getPath();
       
    65 					executables.add(new Executable(exePath, project, binary.getResource()));
       
    66 				}
       
    67 				
       
    68 				progress.worked(1);
    66 			}
    69 			}
       
    70 		} catch (CModelException e) {
    67 		}
    71 		}
    68 
    72 		
    69 		try {
    73 		return executables;
    70 			final StandardExecutableProvider provider = this;
       
    71 			event.getDelta().accept(new IResourceDeltaVisitor() {
       
    72 
       
    73 				public boolean visit(IResourceDelta delta) throws CoreException {
       
    74 					if (delta.getKind() == IResourceDelta.ADDED || delta.getKind() == IResourceDelta.REMOVED) {
       
    75 						IResource deltaResource = delta.getResource();
       
    76 						if (deltaResource != null) {
       
    77 							boolean refresh = false;
       
    78 							if (delta.getKind() == IResourceDelta.REMOVED && deltaResource instanceof IProject) {
       
    79 								// project deleted
       
    80 								refresh = true;
       
    81 							} else {
       
    82 								// see if a binary has been added/removed
       
    83 								IPath resourcePath = delta.getResource().getLocation();
       
    84 								if (resourcePath != null && Executable.isExecutableFile(resourcePath)) {
       
    85 									refresh = true;
       
    86 								}
       
    87 							}
       
    88 							if (refresh) {
       
    89 								ExecutablesManager.getExecutablesManager().scheduleRefresh(provider, 0);
       
    90 								return false;
       
    91 							}
       
    92 						}
       
    93 					}
       
    94 					return true;
       
    95 				}
       
    96 			});
       
    97 		} catch (CoreException e) {
       
    98 		}
       
    99 	}
       
   100 
       
   101 	public void handleEvent(CProjectDescriptionEvent event) {
       
   102 		// this handles the cases where the active build configuration changes,
       
   103 		// and when new
       
   104 		// projects are created.
       
   105 		boolean refresh = false;
       
   106 
       
   107 		int eventType = event.getEventType();
       
   108 
       
   109 		if (eventType == CProjectDescriptionEvent.DATA_APPLIED) {
       
   110 			// see if the active build config has changed
       
   111 			ICProjectDescription newDesc = event.getNewCProjectDescription();
       
   112 			ICProjectDescription oldDesc = event.getOldCProjectDescription();
       
   113 			if (oldDesc != null && newDesc != null) {
       
   114 				String newConfigName = newDesc.getActiveConfiguration().getName();
       
   115 				String oldConfigName = oldDesc.getActiveConfiguration().getName();
       
   116 				refresh = (!newConfigName.equals(oldConfigName));
       
   117 			} else if (newDesc != null && oldDesc == null) {
       
   118 				// project just created
       
   119 				refresh = true;
       
   120 			}
       
   121 		}
       
   122 
       
   123 		if (refresh) {
       
   124 			ExecutablesManager.getExecutablesManager().scheduleRefresh(this, 0);
       
   125 		}
       
   126 	}
       
   127 
       
   128 	public Executable[] getExecutables(IProgressMonitor monitor) {
       
   129 		synchronized (executables) {
       
   130 			executables.clear();
       
   131 
       
   132 			IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
       
   133 			IProject[] projects = root.getProjects();
       
   134 
       
   135 			monitor.beginTask("Checking C/C++ Projects", projects.length);
       
   136 
       
   137 			for (IProject project : projects) {
       
   138 
       
   139 				if (monitor.isCanceled())
       
   140 					break;
       
   141 
       
   142 				try {
       
   143 					if (CoreModel.hasCNature(project)) {
       
   144 						CModelManager manager = CModelManager.getDefault();
       
   145 						ICProject cproject = manager.create(project);
       
   146 						try {
       
   147 							IBinary[] binaries = cproject.getBinaryContainer().getBinaries();
       
   148 							for (IBinary binary : binaries) {
       
   149 								if (binary.isExecutable() || binary.isSharedLib()) {
       
   150 									IPath exePath = binary.getResource().getLocation();
       
   151 									if (exePath == null)
       
   152 										exePath = binary.getPath();
       
   153 									Executable exe = new Executable(exePath, project, binary.getResource());
       
   154 									executables.add(exe);
       
   155 								}
       
   156 							}
       
   157 						} catch (CModelException e) {
       
   158 						}
       
   159 					}
       
   160 				} catch (Exception e) {
       
   161 					DebugPlugin.log( e );
       
   162 				}
       
   163 				monitor.worked(1);
       
   164 			}
       
   165 			monitor.done();
       
   166 		}
       
   167 		return executables.toArray(new Executable[executables.size()]);
       
   168 	}
       
   169 
       
   170 	public int getPriority() {
       
   171 		return NORMAL_PRIORITY;
       
   172 	}
    74 	}
   173 
    75 
   174 	public IStatus removeExecutable(Executable executable, IProgressMonitor monitor) {
    76 	public IStatus removeExecutable(Executable executable, IProgressMonitor monitor) {
   175 		IResource exeResource = executable.getResource();
    77 		IResource exeResource = executable.getResource();
   176 		if (exeResource != null)
    78 		if (exeResource != null) {
   177 		{
    79 			try {
   178 			if (exeResource.isLinked())
    80 				exeResource.delete(true, monitor);
   179 			{
    81 			} catch (CoreException e) {
   180 				try {
    82 				DebugPlugin.log( e );
   181 					exeResource.delete(true, monitor);
       
   182 				} catch (CoreException e) {
       
   183 					DebugPlugin.log( e );
       
   184 				}				
       
   185 			}
    83 			}
   186 			return Status.OK_STATUS;
    84 			return Status.OK_STATUS;
   187 		}
    85 		}
   188 		return new Status(IStatus.WARNING, CDebugCorePlugin.PLUGIN_ID, "Can't remove " + executable.getName() + ": it is built by project \"" + executable.getProject().getName() + "\"");
    86 		return new Status(IStatus.WARNING, CDebugCorePlugin.PLUGIN_ID, "Can't remove " + executable.getName() + ": it is built by project \"" + executable.getProject().getName() + "\"");
   189 	}
    87 	}
   190 
       
   191 }
    88 }