KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > debug > ui > launchConfigurations > JavaClasspathTab


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 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  * BEA - Daniel R Somerfield - Bug 88939
11  *******************************************************************************/

12 package org.eclipse.jdt.debug.ui.launchConfigurations;
13
14
15 import java.util.ArrayList JavaDoc;
16 import java.util.List JavaDoc;
17
18 import org.eclipse.core.resources.IProject;
19 import org.eclipse.core.resources.IResource;
20 import org.eclipse.core.resources.IWorkspace;
21 import org.eclipse.core.resources.ResourcesPlugin;
22 import org.eclipse.core.runtime.CoreException;
23 import org.eclipse.core.runtime.IStatus;
24 import org.eclipse.debug.core.ILaunchConfiguration;
25 import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
26 import org.eclipse.jdt.internal.debug.ui.IJavaDebugHelpContextIds;
27 import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
28 import org.eclipse.jdt.internal.debug.ui.JavaDebugImages;
29 import org.eclipse.jdt.internal.debug.ui.actions.AddAdvancedAction;
30 import org.eclipse.jdt.internal.debug.ui.actions.AddExternalFolderAction;
31 import org.eclipse.jdt.internal.debug.ui.actions.AddExternalJarAction;
32 import org.eclipse.jdt.internal.debug.ui.actions.AddFolderAction;
33 import org.eclipse.jdt.internal.debug.ui.actions.AddJarAction;
34 import org.eclipse.jdt.internal.debug.ui.actions.AddLibraryAction;
35 import org.eclipse.jdt.internal.debug.ui.actions.AddProjectAction;
36 import org.eclipse.jdt.internal.debug.ui.actions.AddVariableAction;
37 import org.eclipse.jdt.internal.debug.ui.actions.AttachSourceAction;
38 import org.eclipse.jdt.internal.debug.ui.actions.EditClasspathEntryAction;
39 import org.eclipse.jdt.internal.debug.ui.actions.MoveDownAction;
40 import org.eclipse.jdt.internal.debug.ui.actions.MoveUpAction;
41 import org.eclipse.jdt.internal.debug.ui.actions.RemoveAction;
42 import org.eclipse.jdt.internal.debug.ui.actions.RestoreDefaultEntriesAction;
43 import org.eclipse.jdt.internal.debug.ui.actions.RuntimeClasspathAction;
44 import org.eclipse.jdt.internal.debug.ui.classpath.BootpathFilter;
45 import org.eclipse.jdt.internal.debug.ui.classpath.ClasspathContentProvider;
46 import org.eclipse.jdt.internal.debug.ui.classpath.ClasspathEntry;
47 import org.eclipse.jdt.internal.debug.ui.classpath.ClasspathLabelProvider;
48 import org.eclipse.jdt.internal.debug.ui.classpath.ClasspathModel;
49 import org.eclipse.jdt.internal.debug.ui.classpath.IClasspathEntry;
50 import org.eclipse.jdt.internal.debug.ui.classpath.RuntimeClasspathViewer;
51 import org.eclipse.jdt.internal.debug.ui.launcher.AbstractJavaClasspathTab;
52 import org.eclipse.jdt.internal.debug.ui.launcher.LauncherMessages;
53 import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
54 import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
55 import org.eclipse.jdt.launching.JavaRuntime;
56 import org.eclipse.jface.action.IAction;
57 import org.eclipse.swt.SWT;
58 import org.eclipse.swt.graphics.Font;
59 import org.eclipse.swt.graphics.Image;
60 import org.eclipse.swt.layout.GridData;
61 import org.eclipse.swt.layout.GridLayout;
62 import org.eclipse.swt.widgets.Button;
63 import org.eclipse.swt.widgets.Composite;
64 import org.eclipse.swt.widgets.Label;
65 import org.eclipse.ui.PlatformUI;
66
67 import com.ibm.icu.text.MessageFormat;
68
69 /**
70  * A launch configuration tab that displays and edits the user and
71  * bootstrap classes comprising the classpath launch configuration
72  * attribute.
73  * <p>
74  * This class may be instantiated. This class is not intended to be sub-classed.
75  * </p>
76  * @since 2.0
77  */

78 public class JavaClasspathTab extends AbstractJavaClasspathTab {
79
80     protected RuntimeClasspathViewer fClasspathViewer;
81     private ClasspathModel fModel;
82
83     protected static final String JavaDoc DIALOG_SETTINGS_PREFIX = "JavaClasspathTab"; //$NON-NLS-1$
84

85     /**
86      * The last launch config this tab was initialized from
87      */

88     protected ILaunchConfiguration fLaunchConfiguration;
89     
90     /* (non-Javadoc)
91      * @see org.eclipse.debug.ui.ILaunchConfigurationTab#createControl(org.eclipse.swt.widgets.Composite)
92      */

93     public void createControl(Composite parent) {
94         Font font = parent.getFont();
95         
96         Composite comp = new Composite(parent, SWT.NONE);
97         setControl(comp);
98         PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IJavaDebugHelpContextIds.LAUNCH_CONFIGURATION_DIALOG_CLASSPATH_TAB);
99         GridLayout topLayout = new GridLayout();
100         topLayout.numColumns = 2;
101         comp.setLayout(topLayout);
102         GridData gd;
103         
104         Label label = new Label(comp, SWT.NONE);
105         label.setText(LauncherMessages.JavaClasspathTab_0);
106         gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
107         gd.horizontalSpan = 2;
108         label.setLayoutData(gd);
109         
110         fClasspathViewer = new RuntimeClasspathViewer(comp);
111         fClasspathViewer.addEntriesChangedListener(this);
112         fClasspathViewer.getControl().setFont(font);
113         fClasspathViewer.setLabelProvider(new ClasspathLabelProvider());
114         fClasspathViewer.setContentProvider(new ClasspathContentProvider(this));
115         if (!isShowBootpath()) {
116             fClasspathViewer.addFilter(new BootpathFilter());
117         }
118     
119         Composite pathButtonComp = new Composite(comp, SWT.NONE);
120         GridLayout pathButtonLayout = new GridLayout();
121         pathButtonLayout.marginHeight = 0;
122         pathButtonLayout.marginWidth = 0;
123         pathButtonComp.setLayout(pathButtonLayout);
124         gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.HORIZONTAL_ALIGN_FILL);
125         pathButtonComp.setLayoutData(gd);
126         pathButtonComp.setFont(font);
127         
128         createPathButtons(pathButtonComp);
129     }
130     
131     /**
132      * Creates the buttons to manipulate the classpath.
133      *
134      * @param pathButtonComp composite buttons are contained in
135      * @since 3.0
136      */

137     protected void createPathButtons(Composite pathButtonComp) {
138         List JavaDoc advancedActions = new ArrayList JavaDoc(5);
139         
140         createButton(pathButtonComp, new MoveUpAction(fClasspathViewer));
141         createButton(pathButtonComp, new MoveDownAction(fClasspathViewer));
142         createButton(pathButtonComp, new RemoveAction(fClasspathViewer));
143         createButton(pathButtonComp, new AddProjectAction(fClasspathViewer));
144         createButton(pathButtonComp, new AddJarAction(fClasspathViewer));
145         createButton(pathButtonComp, new AddExternalJarAction(fClasspathViewer, DIALOG_SETTINGS_PREFIX));
146
147         RuntimeClasspathAction action = new AddFolderAction(null);
148         advancedActions.add(action);
149         
150         action = new AddExternalFolderAction(null, DIALOG_SETTINGS_PREFIX);
151         advancedActions.add(action);
152
153         action = new AddVariableAction(null);
154         advancedActions.add(action);
155         
156         action = new AddLibraryAction(null);
157         advancedActions.add(action);
158         
159         action = new AttachSourceAction(null, SWT.RADIO);
160         advancedActions.add(action);
161         
162         IAction[] adv = (IAction[])advancedActions.toArray(new IAction[advancedActions.size()]);
163         createButton(pathButtonComp, new AddAdvancedAction(fClasspathViewer, adv));
164
165         action = new EditClasspathEntryAction(fClasspathViewer, getLaunchConfiguration());
166         createButton(pathButtonComp, action);
167         
168         action= new RestoreDefaultEntriesAction(fClasspathViewer, this);
169         createButton(pathButtonComp, action);
170         action.setEnabled(true);
171     }
172
173     /**
174      * Creates a button for the given action.
175      *
176      * @param pathButtonComp parent composite for the button
177      * @param action the action triggered by the button
178      * @return the button that was created
179      */

180     protected Button createButton(Composite pathButtonComp, RuntimeClasspathAction action) {
181         Button button = createPushButton(pathButtonComp, action.getText(), null);
182         action.setButton(button);
183         return button;
184     }
185
186     /* (non-Javadoc)
187      * @see org.eclipse.debug.ui.ILaunchConfigurationTab#setDefaults(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
188      */

189     public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
190     }
191
192     /* (non-Javadoc)
193      * @see org.eclipse.debug.ui.ILaunchConfigurationTab#initializeFrom(org.eclipse.debug.core.ILaunchConfiguration)
194      */

195     public void initializeFrom(ILaunchConfiguration configuration) {
196         refresh(configuration);
197         fClasspathViewer.expandToLevel(2);
198     }
199     
200     /* (non-Javadoc)
201      * @see org.eclipse.debug.ui.ILaunchConfigurationTab#activated(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
202      */

203     public void activated(ILaunchConfigurationWorkingCopy workingCopy) {
204         try {
205             boolean useDefault= workingCopy.getAttribute(IJavaLaunchConfigurationConstants.ATTR_DEFAULT_CLASSPATH, true);
206             if (useDefault) {
207                 if (!isDefaultClasspath(getCurrentClasspath(), workingCopy)) {
208                     initializeFrom(workingCopy);
209                     return;
210                 }
211             }
212             fClasspathViewer.refresh();
213         } catch (CoreException e) {
214         }
215     }
216     
217     /**
218      * Refreshes the classpath entries based on the current state of the given
219      * launch configuration.
220      */

221     private void refresh(ILaunchConfiguration configuration) {
222         boolean useDefault = true;
223         setErrorMessage(null);
224         try {
225             useDefault = configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_DEFAULT_CLASSPATH, true);
226         } catch (CoreException e) {
227             JDIDebugUIPlugin.log(e);
228         }
229         
230         if (configuration == getLaunchConfiguration()) {
231             // no need to update if an explicit path is being used and this setting
232
// has not changed (and viewing the same config as last time)
233
if (!useDefault) {
234                 setDirty(false);
235                 return;
236             }
237         }
238         
239         setLaunchConfiguration(configuration);
240         try {
241             createClasspathModel(configuration);
242         } catch (CoreException e) {
243             setErrorMessage(e.getMessage());
244         }
245         
246         fClasspathViewer.setLaunchConfiguration(configuration);
247         fClasspathViewer.setInput(fModel);
248         setDirty(false);
249     }
250     
251     private void createClasspathModel(ILaunchConfiguration configuration) throws CoreException {
252         fModel= new ClasspathModel();
253         IRuntimeClasspathEntry[] entries= JavaRuntime.computeUnresolvedRuntimeClasspath(configuration);
254         IRuntimeClasspathEntry entry;
255         for (int i = 0; i < entries.length; i++) {
256             entry= entries[i];
257             switch (entry.getClasspathProperty()) {
258                 case IRuntimeClasspathEntry.USER_CLASSES:
259                     fModel.addEntry(ClasspathModel.USER, entry);
260                     break;
261                 default:
262                     fModel.addEntry(ClasspathModel.BOOTSTRAP, entry);
263                     break;
264             }
265         }
266     }
267     
268     /* (non-Javadoc)
269      * @see org.eclipse.debug.ui.ILaunchConfigurationTab#performApply(org.eclipse.debug.core.ILaunchConfigurationWorkingCopy)
270      */

271     public void performApply(ILaunchConfigurationWorkingCopy configuration) {
272         if (isDirty()) {
273             IRuntimeClasspathEntry[] classpath = getCurrentClasspath();
274             boolean def = isDefaultClasspath(classpath, configuration.getOriginal());
275             if (def) {
276                 configuration.setAttribute(IJavaLaunchConfigurationConstants.ATTR_DEFAULT_CLASSPATH, (String JavaDoc)null);
277                 configuration.setAttribute(IJavaLaunchConfigurationConstants.ATTR_CLASSPATH, (String JavaDoc)null);
278             } else {
279                 configuration.setAttribute(IJavaLaunchConfigurationConstants.ATTR_DEFAULT_CLASSPATH, false);
280                 try {
281                     List JavaDoc mementos = new ArrayList JavaDoc(classpath.length);
282                     for (int i = 0; i < classpath.length; i++) {
283                         IRuntimeClasspathEntry entry = classpath[i];
284                         mementos.add(entry.getMemento());
285                     }
286                     configuration.setAttribute(IJavaLaunchConfigurationConstants.ATTR_CLASSPATH, mementos);
287                 } catch (CoreException e) {
288                     JDIDebugUIPlugin.statusDialog(LauncherMessages.JavaClasspathTab_Unable_to_save_classpath_1, e.getStatus());
289                 }
290             }
291         }
292     }
293     
294     /**
295      * Returns the classpath entries currently specified by this tab.
296      *
297      * @return the classpath entries currently specified by this tab
298      */

299     private IRuntimeClasspathEntry[] getCurrentClasspath() {
300         IClasspathEntry[] boot = fModel.getEntries(ClasspathModel.BOOTSTRAP);
301         IClasspathEntry[] user = fModel.getEntries(ClasspathModel.USER);
302         List JavaDoc entries = new ArrayList JavaDoc(boot.length + user.length);
303         IClasspathEntry bootEntry;
304         IRuntimeClasspathEntry entry;
305         for (int i = 0; i < boot.length; i++) {
306             bootEntry= boot[i];
307             entry = null;
308             if (bootEntry instanceof ClasspathEntry) {
309                 entry = ((ClasspathEntry)bootEntry).getDelegate();
310             } else if (bootEntry instanceof IRuntimeClasspathEntry) {
311                 entry= (IRuntimeClasspathEntry) boot[i];
312             }
313             if (entry != null) {
314                 if (entry.getClasspathProperty() == IRuntimeClasspathEntry.USER_CLASSES) {
315                     entry.setClasspathProperty(IRuntimeClasspathEntry.BOOTSTRAP_CLASSES);
316                 }
317                 entries.add(entry);
318             }
319         }
320         IClasspathEntry userEntry;
321         for (int i = 0; i < user.length; i++) {
322             userEntry= user[i];
323             entry = null;
324             if (userEntry instanceof ClasspathEntry) {
325                 entry = ((ClasspathEntry)userEntry).getDelegate();
326             } else if (userEntry instanceof IRuntimeClasspathEntry) {
327                 entry= (IRuntimeClasspathEntry) user[i];
328             }
329             if (entry != null) {
330                 entry.setClasspathProperty(IRuntimeClasspathEntry.USER_CLASSES);
331                 entries.add(entry);
332             }
333         }
334         return (IRuntimeClasspathEntry[]) entries.toArray(new IRuntimeClasspathEntry[entries.size()]);
335     }
336
337     /**
338      * Returns whether the specified classpath is equivalent to the
339      * default classpath for this configuration.
340      *
341      * @param classpath classpath to compare to default
342      * @param configuration original configuration
343      * @return whether the specified classpath is equivalent to the
344      * default classpath for this configuration
345      */

346     private boolean isDefaultClasspath(IRuntimeClasspathEntry[] classpath, ILaunchConfiguration configuration) {
347         try {
348             ILaunchConfigurationWorkingCopy wc = configuration.getWorkingCopy();
349             wc.setAttribute(IJavaLaunchConfigurationConstants.ATTR_DEFAULT_CLASSPATH, true);
350             IRuntimeClasspathEntry[] entries= JavaRuntime.computeUnresolvedRuntimeClasspath(wc);
351             if (classpath.length == entries.length) {
352                 for (int i = 0; i < entries.length; i++) {
353                     IRuntimeClasspathEntry entry = entries[i];
354                     if (!entry.equals(classpath[i])) {
355                         return false;
356                     }
357                 }
358                 return true;
359             }
360             return false;
361         } catch (CoreException e) {
362             return false;
363         }
364     }
365
366     /* (non-Javadoc)
367      * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getName()
368      */

369     public String JavaDoc getName() {
370         return LauncherMessages.JavaClasspathTab_Cla_ss_path_3;
371     }
372     
373     /**
374      * @see org.eclipse.debug.ui.AbstractLaunchConfigurationTab#getId()
375      *
376      * @since 3.3
377      */

378     public String JavaDoc getId() {
379         return "org.eclipse.jdt.debug.ui.javaClasspathTab"; //$NON-NLS-1$
380
}
381     
382     /**
383      * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getImage()
384      */

385     public static Image getClasspathImage() {
386         return JavaDebugImages.get(JavaDebugImages.IMG_OBJS_CLASSPATH);
387     }
388     
389     /**
390      * Sets the launch configuration for this classpath tab
391      */

392     private void setLaunchConfiguration(ILaunchConfiguration config) {
393         fLaunchConfiguration = config;
394     }
395     
396     /**
397      * Returns the current launch configuration
398      */

399     public ILaunchConfiguration getLaunchConfiguration() {
400         return fLaunchConfiguration;
401     }
402     
403     /* (non-Javadoc)
404      * @see org.eclipse.debug.ui.ILaunchConfigurationTab#dispose()
405      */

406     public void dispose() {
407         if (fClasspathViewer != null) {
408             fClasspathViewer.removeEntriesChangedListener(this);
409         }
410         super.dispose();
411     }
412
413     /* (non-Javadoc)
414      * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getImage()
415      */

416     public Image getImage() {
417         return getClasspathImage();
418     }
419     
420     /* (non-Javadoc)
421      * @see org.eclipse.debug.ui.ILaunchConfigurationTab#isValid(org.eclipse.debug.core.ILaunchConfiguration)
422      */

423     public boolean isValid(ILaunchConfiguration launchConfig) {
424         setErrorMessage(null);
425         setMessage(null);
426         String JavaDoc projectName= null;
427         try {
428             projectName= launchConfig.getAttribute(IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, ""); //$NON-NLS-1$
429
} catch (CoreException e) {
430             return false;
431         }
432         if (projectName.length() > 0) {
433             IWorkspace workspace = ResourcesPlugin.getWorkspace();
434             IStatus status = workspace.validateName(projectName, IResource.PROJECT);
435             if (status.isOK()) {
436                 IProject project= ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
437                 if (!project.exists()) {
438                     setErrorMessage(MessageFormat.format(LauncherMessages.JavaMainTab_20, new String JavaDoc[] {projectName}));
439                     return false;
440                 }
441                 if (!project.isOpen()) {
442                     setErrorMessage(MessageFormat.format(LauncherMessages.JavaMainTab_21, new String JavaDoc[] {projectName}));
443                     return false;
444                 }
445             } else {
446                 setErrorMessage(MessageFormat.format(LauncherMessages.JavaMainTab_19, new String JavaDoc[]{status.getMessage()}));
447                 return false;
448             }
449         }
450         
451         IRuntimeClasspathEntry [] entries = fModel.getAllEntries();
452         int type = -1;
453         for (int i=0; i<entries.length; i++) {
454             type = entries[i].getType();
455             if (type == IRuntimeClasspathEntry.ARCHIVE) {
456                 if(!entries[i].getPath().isAbsolute()) {
457                     setErrorMessage(MessageFormat.format(LauncherMessages.JavaClasspathTab_Invalid_runtime_classpath_1, new String JavaDoc[]{entries[i].getPath().toString()}));
458                     return false;
459                 }
460             }
461             if(type == IRuntimeClasspathEntry.PROJECT) {
462                 IResource res = entries[i].getResource();
463                 if(res != null && !res.isAccessible()) {
464                     setErrorMessage(MessageFormat.format(LauncherMessages.JavaClasspathTab_1, new String JavaDoc[]{res.getName()}));
465                     return false;
466                 }
467             }
468         }
469         
470         return true;
471     }
472     
473     /**
474      * Returns whether the bootpath should be displayed.
475      *
476      * @return whether the bootpath should be displayed
477      * @since 3.0
478      */

479     public boolean isShowBootpath() {
480         return true;
481     }
482     
483     /**
484      * @return Returns the classpath model.
485      */

486     protected ClasspathModel getModel() {
487         return fModel;
488     }
489 }
490
Popular Tags