KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > debug > core > model > LaunchConfigurationDelegate


1 /*******************************************************************************
2  * Copyright (c) 2004, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.debug.core.model;
12
13 import com.ibm.icu.text.MessageFormat;
14 import java.util.ArrayList JavaDoc;
15 import java.util.HashSet JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.List JavaDoc;
18 import java.util.Set JavaDoc;
19
20 import org.eclipse.core.resources.IMarker;
21 import org.eclipse.core.resources.IProject;
22 import org.eclipse.core.resources.IResource;
23 import org.eclipse.core.resources.IWorkspace;
24 import org.eclipse.core.resources.IncrementalProjectBuilder;
25 import org.eclipse.core.resources.ResourcesPlugin;
26 import org.eclipse.core.runtime.CoreException;
27 import org.eclipse.core.runtime.IProgressMonitor;
28 import org.eclipse.core.runtime.IStatus;
29 import org.eclipse.core.runtime.Status;
30 import org.eclipse.debug.core.DebugPlugin;
31 import org.eclipse.debug.core.IBreakpointManager;
32 import org.eclipse.debug.core.ILaunch;
33 import org.eclipse.debug.core.ILaunchConfiguration;
34 import org.eclipse.debug.core.ILaunchManager;
35 import org.eclipse.debug.core.IStatusHandler;
36 import org.eclipse.debug.internal.core.DebugCoreMessages;
37
38 /**
39  * Default implementation of a launch configuration delegate. Provides
40  * convenience methods for computing the build order of projects,
41  * building projects, and searching for errors in the workspace. The
42  * default pre-launch check prompts the user to launch in debug mode
43  * if breakpoints are present in the workspace.
44  * <p>
45  * Clients implementing launch configuration delegates should subclass
46  * this class.
47  * </p>
48  * @since 3.0
49  */

50 public abstract class LaunchConfigurationDelegate implements ILaunchConfigurationDelegate2 {
51     
52     /**
53      * Constant to define debug.core for the status codes
54      *
55      * @since 3.2
56      */

57     private static final String JavaDoc DEBUG_CORE = "org.eclipse.debug.core"; //$NON-NLS-1$
58

59     /**
60      * Constant to define debug.ui for the status codes
61      *
62      * @since 3.2
63      */

64     private static final String JavaDoc DEBUG_UI = "org.eclipse.debug.ui"; //$NON-NLS-1$
65

66     /**
67      * Constant to represent the empty string
68      *
69      * @since 3.2
70      */

71     private static final String JavaDoc EMPTY_STRING = ""; //$NON-NLS-1$
72

73     /**
74      * Status code for which a UI prompter is registered.
75      */

76     protected static final IStatus promptStatus = new Status(IStatus.INFO, DEBUG_UI, 200, EMPTY_STRING, null);
77     
78     /**
79      * Status code for which a prompter is registered to ask the user if they
80      * want to launch in debug mode when breakpoints are present.
81      */

82     protected static final IStatus switchToDebugPromptStatus = new Status(IStatus.INFO, DEBUG_CORE, 201, EMPTY_STRING, null);
83     
84     /**
85      * Status code for which a prompter is registered to ask the user if the
86      * want to continue launch despite existing compile errors
87      */

88     protected static final IStatus complileErrorPromptStatus = new Status(IStatus.INFO, DEBUG_CORE, 202, EMPTY_STRING, null);
89     
90     /**
91      * Status code for which a prompter will ask the user to save any/all of the dirty editors which have only to do
92      * with this launch (scoping them to the current launch/build)
93      *
94      * @since 3.2
95      */

96     protected static final IStatus saveScopedDirtyEditors = new Status(IStatus.INFO, DEBUG_CORE, 222, EMPTY_STRING, null);
97     
98     /**
99      * Status code for which a prompter is registered to ask the user if the
100      * want to continue launch despite existing compile errors in specific
101      * projects. This enhances the 'compileErrorPromptStatus' by specifying
102      * which projects the errors exist in.
103      *
104      * @since 3.1
105      */

106     protected static final IStatus complileErrorProjectPromptStatus = new Status(IStatus.INFO, DEBUG_CORE, 203, EMPTY_STRING, null);
107     
108     /* (non-Javadoc)
109      * @see org.eclipse.debug.core.model.ILaunchConfigurationDelegate2#getLaunch(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String)
110      */

111     public ILaunch getLaunch(ILaunchConfiguration configuration, String JavaDoc mode) throws CoreException {
112         return null;
113     }
114     
115     /* (non-Javadoc)
116      * @see org.eclipse.debug.core.model.ILaunchConfigurationDelegate2#buildForLaunch(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.core.runtime.IProgressMonitor)
117      */

118     public boolean buildForLaunch(ILaunchConfiguration configuration, String JavaDoc mode, IProgressMonitor monitor) throws CoreException {
119         IProject[] projects = getBuildOrder(configuration, mode);
120         if (projects == null) {
121             return true;
122         }
123         buildProjects(projects, monitor);
124         return false;
125     }
126     
127     /**
128      * Returns the projects to build before launching the given launch configuration
129      * or <code>null</code> if the entire workspace should be built incrementally.
130      * Subclasses should override as required.
131      *
132      * @param configuration the configuration being launched
133      * @param mode launch mode
134      * @return projects to build, in build order, or <code>null</code>
135      * @throws CoreException if an exception occurs
136      */

137     protected IProject[] getBuildOrder(ILaunchConfiguration configuration, String JavaDoc mode) throws CoreException {
138         return null;
139     }
140     
141     /**
142      * Returns the set of projects to use when searching for errors or <code>null</code>
143      * if no search is to be done.
144      *
145      * @param configuration the configuration being launched
146      * @param mode launch mode
147      * @return a list of projects or <code>null</code>
148      * @throws CoreException if an exception occurs
149      */

150     protected IProject[] getProjectsForProblemSearch(ILaunchConfiguration configuration, String JavaDoc mode) throws CoreException {
151         return null;
152     }
153     
154     /* (non-Javadoc)
155      * @see org.eclipse.debug.core.model.ILaunchConfigurationDelegate2#finalLaunchCheck(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.core.runtime.IProgressMonitor)
156      */

157     public boolean finalLaunchCheck(ILaunchConfiguration configuration, String JavaDoc mode, IProgressMonitor monitor) throws CoreException {
158         IProject[] projects = getProjectsForProblemSearch(configuration, mode);
159         if (projects == null) {
160             return true; //continue launch
161
}
162         boolean continueLaunch = true;
163             
164         monitor.subTask(DebugCoreMessages.LaunchConfigurationDelegate_6);
165         List JavaDoc errors = new ArrayList JavaDoc();
166         for (int i = 0; i < projects.length; i++) {
167             monitor.subTask(MessageFormat.format(DebugCoreMessages.LaunchConfigurationDelegate_7, new String JavaDoc[]{projects[i].getName()}));
168             if (existsProblems(projects[i])) {
169                 errors.add(projects[i]);
170             }
171         }
172         if (!errors.isEmpty()) {
173             errors.add(0, configuration);
174             IStatusHandler prompter = DebugPlugin.getDefault().getStatusHandler(promptStatus);
175             if (prompter != null) {
176                 continueLaunch = ((Boolean JavaDoc) prompter.handleStatus(complileErrorProjectPromptStatus, errors)).booleanValue();
177             }
178         }
179             
180         return continueLaunch;
181     }
182     
183     /* (non-Javadoc)
184      *
185      * If launching in run mode, and the configuration supports debug mode, check
186      * if there are any breakpoints in the workspace, and ask the user if they'd
187      * rather launch in debug mode.
188      * <p>
189      * Since 3.2, this check also performs saving of resources before launching.
190      * </p>
191      *
192      * @see org.eclipse.debug.core.model.ILaunchConfigurationDelegate2#preLaunchCheck(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.core.runtime.IProgressMonitor)
193      */

194     public boolean preLaunchCheck(ILaunchConfiguration configuration, String JavaDoc mode, IProgressMonitor monitor) throws CoreException {
195         if (!saveBeforeLaunch(configuration, mode, monitor)) {
196             return false;
197         }
198         if (mode.equals(ILaunchManager.RUN_MODE) && configuration.supportsMode(ILaunchManager.DEBUG_MODE)) {
199             IBreakpoint[] breakpoints= getBreakpoints(configuration);
200             if (breakpoints == null) {
201                 return true;
202             }
203             for (int i = 0; i < breakpoints.length; i++) {
204                 if (breakpoints[i].isEnabled()) {
205                     IStatusHandler prompter = DebugPlugin.getDefault().getStatusHandler(promptStatus);
206                     if (prompter != null) {
207                         boolean launchInDebugModeInstead = ((Boolean JavaDoc)prompter.handleStatus(switchToDebugPromptStatus, configuration)).booleanValue();
208                         if (launchInDebugModeInstead) {
209                             return false; //kill this launch
210
}
211                     }
212                     // if no user prompt, or user says to continue (no need to check other breakpoints)
213
return true;
214                 }
215             }
216         }
217         // no enabled breakpoints... continue launch
218
return true;
219     }
220     
221     /**
222      * Performs the scoped saving of resources before launching and returns whether
223      * the launch should continue. By default, only resources contained within the projects
224      * which are part of the build scope are considered.
225      * <p>
226      * Subclasses may override this method if required.
227      * </p>
228      *
229      * @param configuration the configuration being launched
230      * @param mode the launch mode
231      * @param monitor progress monitor
232      * @return whether the launch should continue
233      * @throws CoreException if an exception occurs during the save
234      * @since 3.2
235      */

236     protected boolean saveBeforeLaunch(ILaunchConfiguration configuration, String JavaDoc mode, IProgressMonitor monitor) throws CoreException {
237         IStatusHandler prompter = DebugPlugin.getDefault().getStatusHandler(promptStatus);
238         if(prompter != null) {
239             //do save here and remove saving from DebugUIPlugin to avoid it 'trumping' this save
240
IProject[] buildOrder = getBuildOrder(configuration, mode);
241             if(!((Boolean JavaDoc)prompter.handleStatus(saveScopedDirtyEditors, new Object JavaDoc[]{configuration, buildOrder})).booleanValue()) {
242                 return false;
243             }
244         }
245         return true;
246     }
247
248     /**
249      * Returns the breakpoint collection that is relevant for this launch delegate.
250      * By default this is all the breakpoints registered with the Debug breakpoint manager.
251      *
252      * @since 3.1
253      * @return the breakpoints that are relevant for this launch delegate
254      */

255     protected IBreakpoint[] getBreakpoints(ILaunchConfiguration configuration) {
256         IBreakpointManager breakpointManager = DebugPlugin.getDefault().getBreakpointManager();
257         if (!breakpointManager.isEnabled()) {
258             // no need to check breakpoints individually.
259
return null;
260         }
261         return breakpointManager.getBreakpoints();
262     }
263     
264     /**
265      * Returns an array of projects in their suggested build order
266      * containing all of the projects specified by <code>baseProjects</code>
267      * and all of their referenced projects.
268      *
269      * @param baseProjects a collection of projects
270      * @return an array of projects in their suggested build order
271      * containing all of the projects specified by <code>baseProjects</code>
272      * @throws CoreException if an error occurs while computing referenced
273      * projects
274      */

275     protected IProject[] computeReferencedBuildOrder(IProject[] baseProjects) throws CoreException {
276         HashSet JavaDoc unorderedProjects = new HashSet JavaDoc();
277         for(int i = 0; i< baseProjects.length; i++) {
278             unorderedProjects.add(baseProjects[i]);
279             addReferencedProjects(baseProjects[i], unorderedProjects);
280         }
281         IProject[] projectSet = (IProject[]) unorderedProjects.toArray(new IProject[unorderedProjects.size()]);
282         return computeBuildOrder(projectSet);
283     }
284     
285     
286     /**
287      * Adds all projects referenced by <code>project</code> to the given
288      * set.
289      *
290      * @param project project
291      * @param references set to which referenced projects are added
292      * @throws CoreException if an error occurs while computing referenced
293      * projects
294      */

295     protected void addReferencedProjects(IProject project, Set JavaDoc references) throws CoreException{
296         if (project.isOpen()) {
297             IProject[] projects = project.getReferencedProjects();
298             for (int i = 0; i < projects.length; i++) {
299                 IProject refProject= projects[i];
300                 if (refProject.exists() && !references.contains(refProject)) {
301                     references.add(refProject);
302                     addReferencedProjects(refProject, references);
303                 }
304             }
305         }
306     }
307     
308     /**
309      * Returns a list of projects in their suggested build order from the
310      * given unordered list of projects.
311      *
312      * @param projects the list of projects to sort into build order
313      * @return a new array containing all projects from <code>projects</code> sorted
314      * according to their build order.
315      */

316     protected IProject[] computeBuildOrder(IProject[] projects) {
317         String JavaDoc[] orderedNames = ResourcesPlugin.getWorkspace().getDescription().getBuildOrder();
318         if (orderedNames != null) {
319             List JavaDoc orderedProjects = new ArrayList JavaDoc(projects.length);
320             //Projects may not be in the build order but should be built if selected
321
List JavaDoc unorderedProjects = new ArrayList JavaDoc(projects.length);
322             for(int i = 0; i < projects.length; ++i) {
323                 unorderedProjects.add(projects[i]);
324             }
325             
326             for (int i = 0; i < orderedNames.length; i++) {
327                 String JavaDoc projectName = orderedNames[i];
328                 for (Iterator JavaDoc iterator = unorderedProjects.iterator(); iterator.hasNext(); ) {
329                     IProject project = (IProject)iterator.next();
330                     if (project.getName().equals(projectName)) {
331                         orderedProjects.add(project);
332                         iterator.remove();
333                         break;
334                     }
335                 }
336             }
337             //Add anything not specified before we return
338
orderedProjects.addAll(unorderedProjects);
339             return (IProject[]) orderedProjects.toArray(new IProject[orderedProjects.size()]);
340         }
341         
342         // Computing build order returned null, try the project prerequisite order
343
IWorkspace.ProjectOrder po = ResourcesPlugin.getWorkspace().computeProjectOrder(projects);
344         return po.projects;
345     }
346     
347     /**
348      * Returns whether the given project contains any problem markers of the
349      * specified severity.
350      *
351      * @param proj the project to search
352      * @return whether the given project contains any problems that should
353      * stop it from launching
354      * @throws CoreException if an error occurs while searching for
355      * problem markers
356      */

357     protected boolean existsProblems(IProject proj) throws CoreException {
358         IMarker[] markers = proj.findMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE);
359         if (markers.length > 0) {
360             for (int i = 0; i < markers.length; i++) {
361                 if (isLaunchProblem(markers[i])) {
362                     return true;
363                 }
364             }
365         }
366         return false;
367     }
368     
369     /**
370      * Returns whether the given problem should potentially abort the launch.
371      * By default if the problem has an error severity, the problem is considered
372      * a potential launch problem. Subclasses may override to specialize error
373      * detection.
374      *
375      * @param problemMarker candidate problem
376      * @return whether the given problem should potentially abort the launch
377      * @throws CoreException if any exceptions occur while accessing marker attributes
378      */

379     protected boolean isLaunchProblem(IMarker problemMarker) throws CoreException {
380         Integer JavaDoc severity = (Integer JavaDoc)problemMarker.getAttribute(IMarker.SEVERITY);
381         if (severity != null) {
382             return severity.intValue() >= IMarker.SEVERITY_ERROR;
383         }
384         
385         return false;
386     }
387     
388     /**
389      * Performs an incremental build on each of the given projects.
390      *
391      * @param projects projects to build
392      * @param monitor progress monitor
393      * @throws CoreException if an exception occurs while building
394      */

395     protected void buildProjects(IProject[] projects, IProgressMonitor monitor) throws CoreException {
396         for (int i = 0; i < projects.length; i++ ) {
397             projects[i].build(IncrementalProjectBuilder.INCREMENTAL_BUILD, monitor);
398         }
399     }
400 }
401
Popular Tags