KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2000, 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.jdt.internal.ui.wizards.buildpaths.newsourcepage;
12
13 import java.io.File JavaDoc;
14 import java.lang.reflect.InvocationTargetException JavaDoc;
15 import java.util.Observable JavaDoc;
16 import java.util.Observer JavaDoc;
17
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.OperationCanceledException;
23 import org.eclipse.core.runtime.Path;
24
25 import org.eclipse.core.resources.IContainer;
26 import org.eclipse.core.resources.IFolder;
27 import org.eclipse.core.resources.IPathVariableManager;
28 import org.eclipse.core.resources.IResource;
29 import org.eclipse.core.resources.IWorkspace;
30 import org.eclipse.core.resources.IWorkspaceRoot;
31 import org.eclipse.core.resources.ResourcesPlugin;
32
33 import org.eclipse.swt.SWT;
34 import org.eclipse.swt.layout.GridData;
35 import org.eclipse.swt.layout.GridLayout;
36 import org.eclipse.swt.widgets.Composite;
37 import org.eclipse.swt.widgets.Control;
38 import org.eclipse.swt.widgets.DirectoryDialog;
39 import org.eclipse.swt.widgets.Label;
40 import org.eclipse.swt.widgets.Shell;
41
42 import org.eclipse.jface.dialogs.ErrorDialog;
43 import org.eclipse.jface.dialogs.IDialogConstants;
44 import org.eclipse.jface.dialogs.MessageDialog;
45 import org.eclipse.jface.dialogs.ProgressMonitorDialog;
46 import org.eclipse.jface.dialogs.StatusDialog;
47
48 import org.eclipse.ui.actions.WorkspaceModifyOperation;
49
50 import org.eclipse.ui.ide.dialogs.PathVariableSelectionDialog;
51
52 import org.eclipse.jdt.internal.corext.util.Messages;
53
54 import org.eclipse.jdt.ui.JavaUI;
55
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.wizards.NewWizardMessages;
60 import org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField;
61 import org.eclipse.jdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
62 import org.eclipse.jdt.internal.ui.wizards.dialogfields.IStringButtonAdapter;
63 import org.eclipse.jdt.internal.ui.wizards.dialogfields.LayoutUtil;
64 import org.eclipse.jdt.internal.ui.wizards.dialogfields.SelectionButtonDialogField;
65 import org.eclipse.jdt.internal.ui.wizards.dialogfields.StringButtonDialogField;
66 import org.eclipse.jdt.internal.ui.wizards.dialogfields.StringDialogField;
67
68 public class LinkFolderDialog extends StatusDialog {
69     private final class FolderNameField extends Observable JavaDoc implements IDialogFieldListener {
70         private StringDialogField fNameDialogField;
71         
72         public FolderNameField(Composite parent, int numOfColumns) {
73             createControls(parent, numOfColumns);
74         }
75         
76         private void createControls(Composite parent, int numColumns) {
77             fNameDialogField= new StringDialogField();
78             fNameDialogField.setLabelText(NewWizardMessages.LinkFolderDialog_folderNameGroup_label);
79             fNameDialogField.doFillIntoGrid(parent, 2);
80             LayoutUtil.setHorizontalGrabbing(fNameDialogField.getTextControl(null));
81             LayoutUtil.setHorizontalSpan(fNameDialogField.getLabelControl(null), numColumns);
82             DialogField.createEmptySpace(parent, numColumns - 1);
83             
84             fNameDialogField.setDialogFieldListener(this);
85         }
86         
87         public StringDialogField getNameDialogField() {
88             return fNameDialogField;
89         }
90         
91         public void setText(String JavaDoc text) {
92             fNameDialogField.setText(text);
93             fNameDialogField.setFocus();
94         }
95         
96         public String JavaDoc getText() {
97             return fNameDialogField.getText();
98         }
99         
100         protected void fireEvent() {
101             setChanged();
102             notifyObservers();
103         }
104
105         public void dialogFieldChanged(DialogField field) {
106             fireEvent();
107         }
108     }
109     
110     private final class LinkFields extends Observable JavaDoc implements IStringButtonAdapter, IDialogFieldListener{
111         private StringButtonDialogField fLinkLocation;
112         
113         private static final String JavaDoc DIALOGSTORE_LAST_EXTERNAL_LOC= JavaUI.ID_PLUGIN + ".last.external.project"; //$NON-NLS-1$
114

115         public LinkFields(Composite parent, int numColumns) {
116             createControls(parent, numColumns);
117         }
118         
119         private void createControls(Composite parent, int numColumns) {
120             fLinkLocation= new StringButtonDialogField(this);
121             
122             fLinkLocation.setLabelText(NewWizardMessages.LinkFolderDialog_dependenciesGroup_locationLabel_desc);
123             fLinkLocation.setButtonLabel(NewWizardMessages.LinkFolderDialog_dependenciesGroup_browseButton_desc);
124             fLinkLocation.setDialogFieldListener(this);
125             
126             SelectionButtonDialogField variables= new SelectionButtonDialogField(SWT.PUSH);
127             variables.setLabelText(NewWizardMessages.LinkFolderDialog_dependenciesGroup_variables_desc);
128             variables.setDialogFieldListener(new IDialogFieldListener() {
129                 public void dialogFieldChanged(DialogField field) {
130                     handleVariablesButtonPressed();
131                 }
132             });
133             
134             fLinkLocation.doFillIntoGrid(parent, numColumns);
135
136             LayoutUtil.setHorizontalSpan(fLinkLocation.getLabelControl(null), numColumns);
137             LayoutUtil.setHorizontalGrabbing(fLinkLocation.getTextControl(null));
138             
139             variables.doFillIntoGrid(parent, 1);
140         }
141         
142         public String JavaDoc getLinkTarget() {
143             return fLinkLocation.getText();
144         }
145         
146         public void setLinkTarget(String JavaDoc text) {
147             fLinkLocation.setText(text);
148         }
149
150         /*(non-Javadoc)
151          * @see org.eclipse.jdt.internal.ui.wizards.dialogfields.IStringButtonAdapter#changeControlPressed(org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField)
152          */

153         public void changeControlPressed(DialogField field) {
154             final DirectoryDialog dialog= new DirectoryDialog(getShell());
155             dialog.setMessage(NewWizardMessages.JavaProjectWizardFirstPage_directory_message);
156             String JavaDoc directoryName = getLinkTarget().trim();
157             if (directoryName.length() == 0) {
158                 String JavaDoc prevLocation= JavaPlugin.getDefault().getDialogSettings().get(DIALOGSTORE_LAST_EXTERNAL_LOC);
159                 if (prevLocation != null) {
160                     directoryName= prevLocation;
161                 }
162             }
163         
164             if (directoryName.length() > 0) {
165                 final File JavaDoc path = new File JavaDoc(directoryName);
166                 if (path.exists())
167                     dialog.setFilterPath(directoryName);
168             }
169             final String JavaDoc selectedDirectory = dialog.open();
170             if (selectedDirectory != null) {
171                 fLinkLocation.setText(selectedDirectory);
172                 if (fName == null) {
173                     fFolderNameField.setText(selectedDirectory.substring(selectedDirectory.lastIndexOf(File.separatorChar) + 1));
174                 }
175                 JavaPlugin.getDefault().getDialogSettings().put(DIALOGSTORE_LAST_EXTERNAL_LOC, selectedDirectory);
176             }
177         }
178         
179         /**
180          * Opens a path variable selection dialog
181          */

182         private void handleVariablesButtonPressed() {
183             int variableTypes = IResource.FOLDER;
184
185             // allow selecting file and folder variables when creating a
186
// linked file
187
/*if (type == IResource.FILE)
188                 variableTypes |= IResource.FILE;*/

189
190             PathVariableSelectionDialog dialog = new PathVariableSelectionDialog(getShell(), variableTypes);
191             if (dialog.open() == IDialogConstants.OK_ID) {
192                 String JavaDoc[] variableNames = (String JavaDoc[]) dialog.getResult();
193                 if (variableNames != null && variableNames.length == 1) {
194                     fLinkLocation.setText(variableNames[0]);
195                     if (fName == null) {
196                         fFolderNameField.setText(variableNames[0]);
197                     }
198                 }
199             }
200         }
201         
202         public void dialogFieldChanged(DialogField field) {
203             fireEvent();
204         }
205         
206         private void fireEvent() {
207             setChanged();
208             notifyObservers();
209         }
210     }
211     
212     /**
213      * Validate this page and show appropriate warnings and error NewWizardMessages.
214      */

215     private final class Validator implements Observer JavaDoc {
216
217         public void update(Observable JavaDoc o, Object JavaDoc arg) {
218             String JavaDoc name= fFolderNameField.getText();
219             IStatus nameStatus= validateFolderName(name);
220             if (nameStatus.matches(IStatus.ERROR)) {
221                 updateStatus(nameStatus);
222             } else {
223                 IStatus dependencyStatus= validateLinkLocation(name);
224                 updateStatus(StatusUtil.getMoreSevere(nameStatus, dependencyStatus));
225             }
226         }
227         
228         /**
229          * Validates this page's controls.
230          *
231          * @return IStatus indicating the validation result. IStatus.OK if the
232          * specified link target is valid given the linkHandle.
233          */

234         private IStatus validateLinkLocation(String JavaDoc name) {
235             IWorkspace workspace= JavaPlugin.getWorkspace();
236             IPath path= Path.fromOSString(fDependenciesGroup.getLinkTarget());
237
238             IStatus locationStatus= workspace.validateLinkLocation(fContainer.getFolder(new Path(name)), path);
239             if (locationStatus.matches(IStatus.ERROR))
240                 return locationStatus;
241
242             // use the resolved link target name
243
String JavaDoc resolvedLinkTarget= resolveVariable();
244             path= new Path(resolvedLinkTarget);
245             File JavaDoc linkTargetFile= new Path(resolvedLinkTarget).toFile();
246             if (linkTargetFile.exists()) {
247                 IStatus fileTypeStatus= validateFileType(linkTargetFile);
248                 if (!fileTypeStatus.isOK())
249                     return fileTypeStatus;
250             } else
251                 if (locationStatus.isOK()) {
252                     // locationStatus takes precedence over missing location warning.
253
return new StatusInfo(IStatus.ERROR, NewWizardMessages.NewFolderDialog_linkTargetNonExistent);
254                 }
255             if (locationStatus.isOK()) {
256                 return new StatusInfo();
257             }
258             return new StatusInfo(locationStatus.getSeverity(), locationStatus.getMessage());
259         }
260         
261         /**
262          * Validates the type of the given file against the link type specified
263          * in the constructor.
264          *
265          * @param linkTargetFile file to validate
266          * @return IStatus indicating the validation result. IStatus.OK if the
267          * given file is valid.
268          */

269         private IStatus validateFileType(File JavaDoc linkTargetFile) {
270             if (!linkTargetFile.isDirectory())
271                 return new StatusInfo(IStatus.ERROR, NewWizardMessages.NewFolderDialog_linkTargetNotFolder);
272             return new StatusInfo();
273         }
274         
275         /**
276          * Tries to resolve the value entered in the link target field as
277          * a variable, if the value is a relative path.
278          * Displays the resolved value if the entered value is a variable.
279          */

280         private String JavaDoc resolveVariable() {
281             IPathVariableManager pathVariableManager = ResourcesPlugin.getWorkspace().getPathVariableManager();
282             IPath path= Path.fromOSString(fDependenciesGroup.getLinkTarget());
283             IPath resolvedPath= pathVariableManager.resolvePath(path);
284             return resolvedPath.toOSString();
285         }
286                 
287         /**
288          * Checks if the folder name is valid.
289          *
290          * @return <code>true</code> if validation was
291          * correct, <code>false</code> otherwise
292          */

293         private IStatus validateFolderName(String JavaDoc name) {
294             if (name.length() == 0) {
295                 return new StatusInfo(IStatus.ERROR, NewWizardMessages.NewFolderDialog_folderNameEmpty);
296             }
297             
298             IStatus nameStatus = fContainer.getWorkspace().validateName(name, IResource.FOLDER);
299             if (!nameStatus.matches(IStatus.ERROR)) {
300                 return nameStatus;
301             }
302             
303             IPath path = new Path(name);
304             if (fContainer.findMember(path) != null) {
305                 return new StatusInfo(IStatus.ERROR, Messages.format(NewWizardMessages.NewFolderDialog_folderNameEmpty_alreadyExists, name));
306             }
307             return nameStatus;
308         }
309     }
310     
311     private FolderNameField fFolderNameField;
312     private LinkFields fDependenciesGroup;
313     private IContainer fContainer;
314     private IFolder fCreatedFolder;
315     private boolean fCreateLink;
316     private String JavaDoc fName;
317     private String JavaDoc fTarget;
318
319     /**
320      * Creates a NewFolderDialog
321      *
322      * @param parentShell parent of the new dialog
323      * @param container parent of the new folder
324      *
325      * @see HintTextGroup
326      */

327     public LinkFolderDialog(Shell parentShell, IContainer container) {
328         this(parentShell, container, true);
329     }
330
331     public LinkFolderDialog(Shell parentShell, IContainer container, boolean createLink) {
332         super(parentShell);
333         fContainer = container;
334         fCreateLink= createLink;
335         setTitle(NewWizardMessages.LinkFolderDialog_title);
336         setShellStyle(getShellStyle() | SWT.RESIZE);
337         setStatusLineAboveButtons(true);
338     }
339
340     /* (non-Javadoc)
341      * Method declared in Window.
342      */

343     protected void configureShell(Shell shell) {
344         super.configureShell(shell);
345     }
346
347     /**
348      * @see org.eclipse.jface.window.Window#create()
349      */

350     public void create() {
351         super.create();
352         // initially disable the ok button since we don't preset the
353
// folder name field
354
getButton(IDialogConstants.OK_ID).setEnabled(false);
355     }
356     
357     public void setName(String JavaDoc name) {
358         if (fFolderNameField != null) {
359             fFolderNameField.setText(name);
360         }
361         fName= name;
362     }
363     
364     public void setLinkTarget(String JavaDoc target) {
365         if (fDependenciesGroup != null) {
366             fDependenciesGroup.setLinkTarget(target);
367         }
368         fTarget= target;
369     }
370
371     /* (non-Javadoc)
372      * Method declared on Dialog.
373      */

374     protected Control createDialogArea(Composite parent) {
375         initializeDialogUnits(parent);
376         
377         int numOfColumns= 3;
378         Composite composite = new Composite(parent, SWT.NONE);
379         composite.setFont(parent.getFont());
380         
381         GridLayout layout = new GridLayout(numOfColumns, false);
382         layout.marginHeight= convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
383         layout.marginWidth= convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
384         composite.setLayout(layout);
385         GridData gridData= new GridData(SWT.FILL, SWT.FILL, true, true);
386         gridData.minimumWidth= convertWidthInCharsToPixels(80);
387         composite.setLayoutData(gridData);
388         
389         Label label= new Label(composite, SWT.NONE);
390         label.setFont(composite.getFont());
391         label.setText(Messages.format(NewWizardMessages.LinkFolderDialog_createIn, fContainer.getFullPath().makeRelative().toString()));
392         label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, numOfColumns, 1));
393         
394         fDependenciesGroup= new LinkFields(composite, numOfColumns);
395         if (fTarget != null) {
396             fDependenciesGroup.setLinkTarget(fTarget);
397         }
398         fFolderNameField= new FolderNameField(composite, numOfColumns);
399         if (fName != null) {
400             fFolderNameField.setText(fName);
401         }
402         
403         Validator validator= new Validator();
404         fDependenciesGroup.addObserver(validator);
405         fFolderNameField.addObserver(validator);
406
407         return composite;
408     }
409
410     /**
411      * Creates a folder resource handle for the folder with the given name.
412      * The folder handle is created relative to the container specified during
413      * object creation.
414      *
415      * @param folderName the name of the folder resource to create a handle for
416      * @return the new folder resource handle
417      */

418     private IFolder createFolderHandle(String JavaDoc folderName) {
419         IWorkspaceRoot workspaceRoot = fContainer.getWorkspace().getRoot();
420         IPath folderPath = fContainer.getFullPath().append(folderName);
421         IFolder folderHandle = workspaceRoot.getFolder(folderPath);
422
423         return folderHandle;
424     }
425
426     /**
427      * Creates a new folder with the given name and optionally linking to
428      * the specified link target.
429      *
430      * @param folderName name of the new folder
431      * @param linkTargetName name of the link target folder. may be null.
432      * @return IFolder the new folder
433      */

434     private IFolder createNewFolder(final String JavaDoc folderName, final String JavaDoc linkTargetName) {
435         final IFolder folderHandle = createFolderHandle(folderName);
436         
437         WorkspaceModifyOperation operation = new WorkspaceModifyOperation() {
438             public void execute(IProgressMonitor monitor) throws CoreException {
439                 try {
440                     monitor.beginTask(NewWizardMessages.NewFolderDialog_progress, 2000);
441                     if (monitor.isCanceled())
442                         throw new OperationCanceledException();
443                     
444                         // create link to folder
445
folderHandle.createLink(Path.fromOSString(fDependenciesGroup.getLinkTarget()), IResource.ALLOW_MISSING_LOCAL, monitor);
446                     
447                     if (monitor.isCanceled())
448                         throw new OperationCanceledException();
449                 } catch (StringIndexOutOfBoundsException JavaDoc e) {
450                     e.printStackTrace();
451                 }
452                 finally {
453                     monitor.done();
454                 }
455             }
456         };
457         
458         try {
459             new ProgressMonitorDialog(getShell())
460                     .run(true, true, operation);
461         } catch (InterruptedException JavaDoc exception) {
462             return null;
463         } catch (InvocationTargetException JavaDoc exception) {
464             if (exception.getTargetException() instanceof CoreException) {
465                 ErrorDialog.openError(getShell(), NewWizardMessages.NewFolderDialog_errorTitle,
466                         null, // no special message
467
((CoreException) exception.getTargetException())
468                                 .getStatus());
469             } else {
470                 // CoreExceptions are handled above, but unexpected runtime exceptions and errors may still occur.
471
JavaPlugin.log(new Exception JavaDoc(Messages.format(
472                         "Exception in {0}.createNewFolder(): {1}", //$NON-NLS-1$
473
new Object JavaDoc[] { getClass().getName(),
474                                 exception.getTargetException() })));
475                 MessageDialog.openError(getShell(), NewWizardMessages.NewFolderDialog_errorTitle,
476                         Messages.format(
477                                 NewWizardMessages.NewFolderDialog_internalError,
478                                 new Object JavaDoc[] { exception.getTargetException()
479                                         .getMessage() }));
480             }
481             return null;
482         }
483         
484         return folderHandle;
485     }
486
487     /**
488      * Update the dialog's status line to reflect the given status. It is safe to call
489      * this method before the dialog has been opened.
490      */

491     protected void updateStatus(IStatus status) {
492         super.updateStatus(status);
493     }
494    
495     /* (non-Javadoc)
496      * @see org.eclipse.ui.dialogs.SelectionStatusDialog#okPressed()
497      */

498     protected void okPressed() {
499         if (fCreateLink) {
500             String JavaDoc linkTarget = fDependenciesGroup.getLinkTarget();
501             linkTarget= linkTarget.length() == 0 ? null : linkTarget;
502             fCreatedFolder = createNewFolder(fFolderNameField.getText(), linkTarget);
503         } else {
504             fCreatedFolder = createFolderHandle(fFolderNameField.getText());
505         }
506         super.okPressed();
507     }
508     
509     /**
510      * Returns the created folder or <code>null</code>
511      * if there is none.
512      *
513      * @return created folder or <code>null</code>
514      */

515     public IFolder getCreatedFolder() {
516         return fCreatedFolder;
517     }
518
519     public IPath getLinkTarget() {
520         return Path.fromOSString(fDependenciesGroup.getLinkTarget());
521     }
522     
523 }
524
Popular Tags