KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > wizards > buildpaths > SourceAttachmentBlock


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  *******************************************************************************/

11 package org.eclipse.jdt.internal.ui.wizards.buildpaths;
12
13 import java.io.File JavaDoc;
14 import java.lang.reflect.InvocationTargetException JavaDoc;
15 import java.util.List JavaDoc;
16
17 import org.eclipse.core.runtime.Assert;
18 import org.eclipse.core.runtime.CoreException;
19 import org.eclipse.core.runtime.IPath;
20 import org.eclipse.core.runtime.IProgressMonitor;
21 import org.eclipse.core.runtime.IStatus;
22 import org.eclipse.core.runtime.Path;
23
24 import org.eclipse.core.resources.IResource;
25 import org.eclipse.core.resources.IWorkspaceRoot;
26 import org.eclipse.core.resources.ResourcesPlugin;
27
28 import org.eclipse.swt.SWT;
29 import org.eclipse.swt.layout.GridData;
30 import org.eclipse.swt.layout.GridLayout;
31 import org.eclipse.swt.widgets.Composite;
32 import org.eclipse.swt.widgets.Control;
33 import org.eclipse.swt.widgets.DirectoryDialog;
34 import org.eclipse.swt.widgets.FileDialog;
35 import org.eclipse.swt.widgets.Label;
36 import org.eclipse.swt.widgets.Shell;
37
38 import org.eclipse.jface.dialogs.Dialog;
39 import org.eclipse.jface.operation.IRunnableWithProgress;
40 import org.eclipse.jface.viewers.ILabelProvider;
41 import org.eclipse.jface.viewers.ITreeContentProvider;
42 import org.eclipse.jface.viewers.ViewerFilter;
43 import org.eclipse.jface.window.Window;
44
45 import org.eclipse.ui.PlatformUI;
46 import org.eclipse.ui.model.WorkbenchContentProvider;
47 import org.eclipse.ui.model.WorkbenchLabelProvider;
48
49 import org.eclipse.jdt.core.IClasspathEntry;
50 import org.eclipse.jdt.core.IJavaProject;
51 import org.eclipse.jdt.core.JavaCore;
52
53 import org.eclipse.jdt.internal.corext.util.Messages;
54
55 import org.eclipse.jdt.internal.ui.IJavaHelpContextIds;
56 import org.eclipse.jdt.internal.ui.JavaPlugin;
57 import org.eclipse.jdt.internal.ui.dialogs.StatusInfo;
58 import org.eclipse.jdt.internal.ui.dialogs.StatusUtil;
59 import org.eclipse.jdt.internal.ui.util.PixelConverter;
60 import org.eclipse.jdt.internal.ui.wizards.IStatusChangeListener;
61 import org.eclipse.jdt.internal.ui.wizards.NewWizardMessages;
62 import org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField;
63 import org.eclipse.jdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
64 import org.eclipse.jdt.internal.ui.wizards.dialogfields.IStringButtonAdapter;
65 import org.eclipse.jdt.internal.ui.wizards.dialogfields.LayoutUtil;
66 import org.eclipse.jdt.internal.ui.wizards.dialogfields.SelectionButtonDialogField;
67 import org.eclipse.jdt.internal.ui.wizards.dialogfields.StringButtonDialogField;
68
69 /**
70  * UI to set the source attachment archive and root.
71  * Same implementation for both setting attachments for libraries from
72  * variable entries and for normal (internal or external) jar.
73  */

74 public class SourceAttachmentBlock {
75         
76     private IStatusChangeListener fContext;
77     
78     private StringButtonDialogField fFileNameField;
79     private SelectionButtonDialogField fWorkspaceButton;
80     private SelectionButtonDialogField fExternalFolderButton;
81     
82     private IStatus fNameStatus;
83     
84     /**
85      * The path to which the archive variable points.
86      * Null if invalid path or not resolvable. Must not exist.
87      */

88     private IPath fFileVariablePath;
89         
90     private IWorkspaceRoot fWorkspaceRoot;
91     
92     private Control fSWTWidget;
93     private Label fFullPathResolvedLabel;
94     
95     private IJavaProject fProject;
96     private IClasspathEntry fEntry;
97     private IPath fContainerPath;
98
99
100     /**
101      * @param context listeners for status updates
102      * @param entry The entry to edit
103      */

104     public SourceAttachmentBlock(IStatusChangeListener context, IClasspathEntry entry) {
105         Assert.isNotNull(entry);
106         
107         fContext= context;
108         fEntry= entry;
109
110         
111         int kind= entry.getEntryKind();
112         Assert.isTrue(kind == IClasspathEntry.CPE_LIBRARY || kind == IClasspathEntry.CPE_VARIABLE);
113                 
114         fWorkspaceRoot= ResourcesPlugin.getWorkspace().getRoot();
115         
116         fNameStatus= new StatusInfo();
117         
118         SourceAttachmentAdapter adapter= new SourceAttachmentAdapter();
119         
120         // create the dialog fields (no widgets yet)
121
if (isVariableEntry()) {
122             fFileNameField= new VariablePathDialogField(adapter);
123             fFileNameField.setDialogFieldListener(adapter);
124             fFileNameField.setLabelText(NewWizardMessages.SourceAttachmentBlock_filename_varlabel);
125             fFileNameField.setButtonLabel(NewWizardMessages.SourceAttachmentBlock_filename_external_varbutton);
126             ((VariablePathDialogField)fFileNameField).setVariableButtonLabel(NewWizardMessages.SourceAttachmentBlock_filename_variable_button);
127                     
128         } else {
129             fFileNameField= new StringButtonDialogField(adapter);
130             fFileNameField.setDialogFieldListener(adapter);
131             fFileNameField.setLabelText(NewWizardMessages.SourceAttachmentBlock_filename_label);
132             fFileNameField.setButtonLabel(NewWizardMessages.SourceAttachmentBlock_filename_externalfile_button);
133         
134             fWorkspaceButton= new SelectionButtonDialogField(SWT.PUSH);
135             fWorkspaceButton.setDialogFieldListener(adapter);
136             fWorkspaceButton.setLabelText(NewWizardMessages.SourceAttachmentBlock_filename_internal_button);
137
138             fExternalFolderButton= new SelectionButtonDialogField(SWT.PUSH);
139             fExternalFolderButton.setDialogFieldListener(adapter);
140             fExternalFolderButton.setLabelText(NewWizardMessages.SourceAttachmentBlock_filename_externalfolder_button);
141         }
142     
143         // set the old settings
144
setDefaults();
145     }
146     
147     /**
148      * @deprecated Use API {@link org.eclipse.jdt.ui.wizards.BuildPathDialogAccess#configureSourceAttachment(Shell, IClasspathEntry)}
149      */

150     public SourceAttachmentBlock(IStatusChangeListener context, IClasspathEntry entry, IPath containerPath, IJavaProject project) {
151         this(context, entry);
152         fContainerPath= containerPath;
153         fProject= project;
154     }
155     
156     public void setDefaults() {
157         if (fEntry.getSourceAttachmentPath() != null) {
158             fFileNameField.setText(fEntry.getSourceAttachmentPath().toString());
159         } else {
160             fFileNameField.setText(""); //$NON-NLS-1$
161
}
162     }
163     
164     private boolean isVariableEntry() {
165         return fEntry.getEntryKind() == IClasspathEntry.CPE_VARIABLE;
166     }
167     
168     
169     /**
170      * Gets the source attachment path chosen by the user
171      */

172     public IPath getSourceAttachmentPath() {
173         if (fFileNameField.getText().length() == 0) {
174             return null;
175         }
176         return getFilePath();
177     }
178
179     /**
180      * Gets the source attachment root chosen by the user
181      * Returns null to let JCore automatically detect the root.
182      */

183     public IPath getSourceAttachmentRootPath() {
184         return null;
185     }
186     
187     public IClasspathEntry getNewEntry() {
188         CPListElement elem= CPListElement.createFromExisting(fEntry, fProject);
189         elem.setAttribute(CPListElement.SOURCEATTACHMENT, getSourceAttachmentPath());
190         return elem.getClasspathEntry();
191     }
192         
193     /**
194      * Creates the control
195      */

196     public Control createControl(Composite parent) {
197         PixelConverter converter= new PixelConverter(parent);
198         
199         fSWTWidget= parent;
200         
201         Composite composite= new Composite(parent, SWT.NONE);
202         
203         GridLayout layout= new GridLayout();
204         layout.marginHeight= 0;
205         layout.marginWidth= 0;
206         layout.numColumns= 4;
207         composite.setLayout(layout);
208         
209         
210         if (isVariableEntry()) {
211             int widthHint= converter.convertWidthInCharsToPixels(40);
212             int labelWidthHint= widthHint * 2;
213             
214             Label message= new Label(composite, SWT.WRAP);
215             GridData gd= new GridData(GridData.FILL, GridData.BEGINNING, false, false, 4, 1);
216             message.setLayoutData(gd);
217             message.setText(Messages.format(NewWizardMessages.SourceAttachmentBlock_message, fEntry.getPath().lastSegment()));
218             
219             //DialogField.createEmptySpace(composite, 1);
220

221             Label desc= new Label(composite, SWT.WRAP);
222             gd= new GridData(GridData.FILL, GridData.BEGINNING, false, false, 4, 1);
223             gd.widthHint= labelWidthHint;
224             desc.setLayoutData(gd);
225             desc.setText(NewWizardMessages.SourceAttachmentBlock_filename_description);
226             
227             fFileNameField.doFillIntoGrid(composite, 4);
228             LayoutUtil.setWidthHint(fFileNameField.getTextControl(null), widthHint);
229
230             // label that shows the resolved path for variable jars
231
//DialogField.createEmptySpace(composite, 1);
232
fFullPathResolvedLabel= new Label(composite, SWT.WRAP);
233             fFullPathResolvedLabel.setText(getResolvedLabelString());
234             gd= new GridData(GridData.FILL, GridData.BEGINNING, false, false, 4, 1);
235             gd.widthHint= labelWidthHint;
236             fFullPathResolvedLabel.setLayoutData(gd);
237             
238             LayoutUtil.setHorizontalGrabbing(fFileNameField.getTextControl(null));
239         } else {
240             int widthHint= converter.convertWidthInCharsToPixels(60);
241             
242             GridData gd= new GridData(GridData.FILL, GridData.BEGINNING, false, false, 3, 1);
243             gd.widthHint= converter.convertWidthInCharsToPixels(50);
244
245             Label message= new Label(composite, SWT.LEFT + SWT.WRAP);
246             message.setLayoutData(gd);
247             message.setText(Messages.format(NewWizardMessages.SourceAttachmentBlock_message, fEntry.getPath().lastSegment()));
248             
249             fWorkspaceButton.doFillIntoGrid(composite, 1);
250             ((GridData) fWorkspaceButton.getSelectionButton(null).getLayoutData()).verticalAlignment= SWT.END;
251             
252             
253             // archive name field
254
fFileNameField.doFillIntoGrid(composite, 4);
255             LayoutUtil.setWidthHint(fFileNameField.getTextControl(null), widthHint);
256             LayoutUtil.setHorizontalGrabbing(fFileNameField.getTextControl(null));
257
258             // Additional 'browse workspace' button for normal jars
259
DialogField.createEmptySpace(composite, 3);
260             
261             fExternalFolderButton.doFillIntoGrid(composite, 1);
262         }
263                 
264         fFileNameField.postSetFocusOnDialogField(parent.getDisplay());
265         
266         Dialog.applyDialogFont(composite);
267                 
268         PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, IJavaHelpContextIds.SOURCE_ATTACHMENT_BLOCK);
269         return composite;
270     }
271     
272         
273     private class SourceAttachmentAdapter implements IStringButtonAdapter, IDialogFieldListener {
274         
275         // -------- IStringButtonAdapter --------
276
public void changeControlPressed(DialogField field) {
277             attachmentChangeControlPressed(field);
278         }
279         
280         // ---------- IDialogFieldListener --------
281
public void dialogFieldChanged(DialogField field) {
282             attachmentDialogFieldChanged(field);
283         }
284     }
285     
286     private void attachmentChangeControlPressed(DialogField field) {
287         if (field == fFileNameField) {
288             IPath jarFilePath= isVariableEntry() ? chooseExtension() : chooseExtJarFile();
289             if (jarFilePath != null) {
290                 fFileNameField.setText(jarFilePath.toString());
291             }
292         }
293     }
294     
295     // ---------- IDialogFieldListener --------
296

297     private void attachmentDialogFieldChanged(DialogField field) {
298         if (field == fFileNameField) {
299             fNameStatus= updateFileNameStatus();
300         } else if (field == fWorkspaceButton) {
301             IPath jarFilePath= chooseInternal();
302             if (jarFilePath != null) {
303                 fFileNameField.setText(jarFilePath.toString());
304             }
305             return;
306         } else if (field == fExternalFolderButton) {
307             IPath folderPath= chooseExtFolder();
308             if (folderPath != null) {
309                 fFileNameField.setText(folderPath.toString());
310             }
311             return;
312         }
313         doStatusLineUpdate();
314     }
315         
316     private void doStatusLineUpdate() {
317         fFileNameField.enableButton(canBrowseFileName());
318         
319         // set the resolved path for variable jars
320
if (fFullPathResolvedLabel != null) {
321             fFullPathResolvedLabel.setText(getResolvedLabelString());
322         }
323         
324         IStatus status= StatusUtil.getMostSevere(new IStatus[] { fNameStatus });
325         fContext.statusChanged(status);
326     }
327     
328     private boolean canBrowseFileName() {
329         if (!isVariableEntry()) {
330             return true;
331         }
332         // to browse with a variable JAR, the variable name must point to a directory
333
if (fFileVariablePath != null) {
334             return fFileVariablePath.toFile().isDirectory();
335         }
336         return false;
337     }
338     
339     private String JavaDoc getResolvedLabelString() {
340         IPath resolvedPath= getResolvedPath(getFilePath());
341         if (resolvedPath != null) {
342             return resolvedPath.toOSString();
343         }
344         return ""; //$NON-NLS-1$
345
}
346     
347     private IPath getResolvedPath(IPath path) {
348         if (path != null) {
349             String JavaDoc varName= path.segment(0);
350             if (varName != null) {
351                 IPath varPath= JavaCore.getClasspathVariable(varName);
352                 if (varPath != null) {
353                     return varPath.append(path.removeFirstSegments(1));
354                 }
355             }
356         }
357         return null;
358     }
359     
360     private IStatus updateFileNameStatus() {
361         StatusInfo status= new StatusInfo();
362         fFileVariablePath= null;
363         
364         String JavaDoc fileName= fFileNameField.getText();
365         if (fileName.length() == 0) {
366             // no source attachment
367
return status;
368         } else {
369             if (!Path.EMPTY.isValidPath(fileName)) {
370                 status.setError(NewWizardMessages.SourceAttachmentBlock_filename_error_notvalid);
371                 return status;
372             }
373             IPath filePath= Path.fromOSString(fileName);
374             IPath resolvedPath;
375             if (isVariableEntry()) {
376                 if (filePath.getDevice() != null) {
377                     status.setError(NewWizardMessages.SourceAttachmentBlock_filename_error_deviceinpath);
378                     return status;
379                 }
380                 String JavaDoc varName= filePath.segment(0);
381                 if (varName == null) {
382                     status.setError(NewWizardMessages.SourceAttachmentBlock_filename_error_notvalid);
383                     return status;
384                 }
385                 fFileVariablePath= JavaCore.getClasspathVariable(varName);
386                 if (fFileVariablePath == null) {
387                     status.setError(NewWizardMessages.SourceAttachmentBlock_filename_error_varnotexists);
388                     return status;
389                 }
390                 resolvedPath= fFileVariablePath.append(filePath.removeFirstSegments(1));
391                 
392                 if (resolvedPath.isEmpty()) {
393                     status.setWarning(NewWizardMessages.SourceAttachmentBlock_filename_warning_varempty);
394                     return status;
395                 }
396                 File JavaDoc file= resolvedPath.toFile();
397                 if (!file.exists()) {
398                     String JavaDoc message= Messages.format(NewWizardMessages.SourceAttachmentBlock_filename_error_filenotexists, resolvedPath.toOSString());
399                     status.setWarning(message);
400                     return status;
401                 }
402                 if (!resolvedPath.isAbsolute()) {
403                     String JavaDoc message= Messages.format(NewWizardMessages.SourceAttachmentBlock_filename_error_notabsolute, filePath.toString());
404                     status.setError(message);
405                     return status;
406                 }
407                 
408                 String JavaDoc deprecationMessage= BuildPathSupport.getDeprecationMessage(varName);
409                 if (deprecationMessage != null) {
410                     status.setWarning(deprecationMessage);
411                     return status;
412                 }
413                 
414             } else {
415                 // JDT/Core only supports source attachments in archives on the
416
// local file system. So using getLocation is save here.
417
File JavaDoc file= filePath.toFile();
418                 IResource res= fWorkspaceRoot.findMember(filePath);
419                 if (res != null && res.getLocation() != null) {
420                     file= res.getLocation().toFile();
421                 }
422                 if (!file.exists()) {
423                     String JavaDoc message= Messages.format(NewWizardMessages.SourceAttachmentBlock_filename_error_filenotexists, filePath.toString());
424                     status.setError(message);
425                     return status;
426                 }
427                 if (res == null) {
428                     if (!filePath.isAbsolute()) {
429                         String JavaDoc message= Messages.format(NewWizardMessages.SourceAttachmentBlock_filename_error_notabsolute, filePath.toString());
430                         status.setError(message);
431                         return status;
432                     }
433                 }
434             }
435             
436         }
437         return status;
438     }
439     
440     private IPath getFilePath() {
441         return Path.fromOSString(fFileNameField.getText()).makeAbsolute();
442     }
443     
444     private IPath chooseExtension() {
445         IPath currPath= getFilePath();
446         if (currPath.segmentCount() == 0) {
447             currPath= fEntry.getPath();
448         }
449     
450         IPath resolvedPath= getResolvedPath(currPath);
451         File JavaDoc initialSelection= resolvedPath != null ? resolvedPath.toFile() : null;
452             
453         String JavaDoc currVariable= currPath.segment(0);
454         JARFileSelectionDialog dialog= new JARFileSelectionDialog(getShell(), false, true);
455         dialog.setTitle(NewWizardMessages.SourceAttachmentBlock_extvardialog_title);
456         dialog.setMessage(NewWizardMessages.SourceAttachmentBlock_extvardialog_description);
457         dialog.setInput(fFileVariablePath.toFile());
458         dialog.setInitialSelection(initialSelection);
459         if (dialog.open() == Window.OK) {
460             File JavaDoc result= (File JavaDoc) dialog.getResult()[0];
461             IPath returnPath= Path.fromOSString(result.getPath()).makeAbsolute();
462             return modifyPath(returnPath, currVariable);
463         }
464         return null;
465     }
466     
467     /*
468      * Opens a dialog to choose a jar from the file system.
469      */

470     private IPath chooseExtJarFile() {
471         IPath currPath= getFilePath();
472         if (currPath.segmentCount() == 0) {
473             currPath= fEntry.getPath();
474         }
475             
476         if (ArchiveFileFilter.isArchivePath(currPath)) {
477             currPath= currPath.removeLastSegments(1);
478         }
479     
480         FileDialog dialog= new FileDialog(getShell());
481         dialog.setText(NewWizardMessages.SourceAttachmentBlock_extjardialog_text);
482         dialog.setFilterExtensions(new String JavaDoc[] {"*.jar;*.zip"}); //$NON-NLS-1$
483
dialog.setFilterPath(currPath.toOSString());
484         String JavaDoc res= dialog.open();
485         if (res != null) {
486             return Path.fromOSString(res).makeAbsolute();
487         }
488         return null;
489     }
490     
491     private IPath chooseExtFolder() {
492         IPath currPath= getFilePath();
493         if (currPath.segmentCount() == 0) {
494             currPath= fEntry.getPath();
495         }
496         if (ArchiveFileFilter.isArchivePath(currPath)) {
497             currPath= currPath.removeLastSegments(1);
498         }
499     
500         DirectoryDialog dialog= new DirectoryDialog(getShell());
501         dialog.setMessage(NewWizardMessages.SourceAttachmentBlock_extfolderdialog_message);
502         dialog.setText(NewWizardMessages.SourceAttachmentBlock_extfolderdialog_text);
503         dialog.setFilterPath(currPath.toOSString());
504         String JavaDoc res= dialog.open();
505         if (res != null) {
506             return Path.fromOSString(res).makeAbsolute();
507         }
508         return null;
509     }
510     
511     /*
512      * Opens a dialog to choose an internal jar.
513      */

514     private IPath chooseInternal() {
515         String JavaDoc initSelection= fFileNameField.getText();
516         
517         ViewerFilter filter= new ArchiveFileFilter((List JavaDoc) null, false);
518
519         ILabelProvider lp= new WorkbenchLabelProvider();
520         ITreeContentProvider cp= new WorkbenchContentProvider();
521
522         IResource initSel= null;
523         if (initSelection.length() > 0) {
524             initSel= fWorkspaceRoot.findMember(new Path(initSelection));
525         }
526         if (initSel == null) {
527             initSel= fWorkspaceRoot.findMember(fEntry.getPath());
528         }
529
530         FolderSelectionDialog dialog= new FolderSelectionDialog(getShell(), lp, cp);
531         dialog.setAllowMultiple(false);
532         dialog.addFilter(filter);
533         dialog.setTitle(NewWizardMessages.SourceAttachmentBlock_intjardialog_title);
534         dialog.setMessage(NewWizardMessages.SourceAttachmentBlock_intjardialog_message);
535         dialog.setInput(fWorkspaceRoot);
536         dialog.setInitialSelection(initSel);
537         if (dialog.open() == Window.OK) {
538             IResource res= (IResource) dialog.getFirstResult();
539             return res.getFullPath();
540         }
541         return null;
542     }
543     
544     private Shell getShell() {
545         if (fSWTWidget != null) {
546             return fSWTWidget.getShell();
547         }
548         return JavaPlugin.getActiveWorkbenchShell();
549     }
550     
551     /**
552      * Takes a path and replaces the beginning with a variable name
553      * (if the beginning matches with the variables value)
554      */

555     private IPath modifyPath(IPath path, String JavaDoc varName) {
556         if (varName == null || path == null) {
557             return null;
558         }
559         if (path.isEmpty()) {
560             return new Path(varName);
561         }
562         
563         IPath varPath= JavaCore.getClasspathVariable(varName);
564         if (varPath != null) {
565             if (varPath.isPrefixOf(path)) {
566                 path= path.removeFirstSegments(varPath.segmentCount());
567             } else {
568                 path= new Path(path.lastSegment());
569             }
570         } else {
571             path= new Path(path.lastSegment());
572         }
573         return new Path(varName).append(path);
574     }
575
576
577     /**
578      * Creates a runnable that sets the source attachment by modifying the project's classpath.
579      */

580     public static IRunnableWithProgress getRunnable(final Shell shell, final IClasspathEntry newEntry, final IJavaProject jproject, final IPath containerPath) {
581         return new IRunnableWithProgress() {
582             public void run(IProgressMonitor monitor) throws InvocationTargetException JavaDoc {
583                 try {
584                     String JavaDoc[] changedAttributes= { CPListElement.SOURCEATTACHMENT };
585                     BuildPathSupport.modifyClasspathEntry(shell, newEntry, changedAttributes, jproject, containerPath, monitor);
586                 } catch (CoreException e) {
587                     throw new InvocationTargetException JavaDoc(e);
588                 }
589             }
590         };
591     }
592
593     /**
594      * @deprecated Use {@link #getRunnable(Shell, IClasspathEntry, IJavaProject, IPath)}
595      */

596     public IRunnableWithProgress getRunnable(final Shell shell) {
597         return getRunnable(shell, getNewEntry(), fProject, fContainerPath);
598     }
599     
600     
601 }
602
Popular Tags