KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > ui > wizards > NewContainerWizardPage


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.ui.wizards;
12
13 import org.eclipse.core.runtime.CoreException;
14 import org.eclipse.core.runtime.IAdaptable;
15 import org.eclipse.core.runtime.IPath;
16 import org.eclipse.core.runtime.IStatus;
17 import org.eclipse.core.runtime.Path;
18
19 import org.eclipse.core.resources.IProject;
20 import org.eclipse.core.resources.IResource;
21 import org.eclipse.core.resources.IWorkspaceRoot;
22 import org.eclipse.core.resources.ResourcesPlugin;
23
24 import org.eclipse.swt.widgets.Composite;
25
26 import org.eclipse.jface.viewers.ILabelProvider;
27 import org.eclipse.jface.viewers.ISelection;
28 import org.eclipse.jface.viewers.ISelectionProvider;
29 import org.eclipse.jface.viewers.IStructuredSelection;
30 import org.eclipse.jface.viewers.Viewer;
31 import org.eclipse.jface.viewers.ViewerFilter;
32 import org.eclipse.jface.window.Window;
33
34 import org.eclipse.jface.text.ITextSelection;
35
36 import org.eclipse.ui.IEditorPart;
37 import org.eclipse.ui.IWorkbenchPart;
38 import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
39
40 import org.eclipse.ui.views.contentoutline.ContentOutline;
41
42 import org.eclipse.jdt.core.IJavaElement;
43 import org.eclipse.jdt.core.IJavaModel;
44 import org.eclipse.jdt.core.IJavaProject;
45 import org.eclipse.jdt.core.IPackageFragmentRoot;
46 import org.eclipse.jdt.core.JavaCore;
47 import org.eclipse.jdt.core.JavaModelException;
48
49 import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
50 import org.eclipse.jdt.internal.corext.util.Messages;
51
52 import org.eclipse.jdt.ui.JavaElementComparator;
53 import org.eclipse.jdt.ui.JavaElementLabelProvider;
54 import org.eclipse.jdt.ui.StandardJavaElementContentProvider;
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.viewsupport.IViewPartInputProvider;
59 import org.eclipse.jdt.internal.ui.wizards.NewWizardMessages;
60 import org.eclipse.jdt.internal.ui.wizards.TypedElementSelectionValidator;
61 import org.eclipse.jdt.internal.ui.wizards.TypedViewerFilter;
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.StringButtonDialogField;
67
68 /**
69  * Wizard page that acts as a base class for wizard pages that create new Java elements.
70  * The class provides a input field for source folders (called container in this class) and
71  * API to validate the enter source folder name.
72  *
73  * <p>
74  * Clients may subclass.
75  * </p>
76  *
77  * @since 2.0
78  */

79 public abstract class NewContainerWizardPage extends NewElementWizardPage {
80     
81     /** Id of the container field */
82     protected static final String JavaDoc CONTAINER= "NewContainerWizardPage.container"; //$NON-NLS-1$
83

84     /** The status of the last validation. */
85     protected IStatus fContainerStatus;
86
87     private StringButtonDialogField fContainerDialogField;
88         
89     /*
90      * package fragment root corresponding to the input type (can be null)
91      */

92     private IPackageFragmentRoot fCurrRoot;
93     
94     private IWorkspaceRoot fWorkspaceRoot;
95     
96     /**
97      * Create a new <code>NewContainerWizardPage</code>
98      *
99      * @param name the wizard page's name
100      */

101     public NewContainerWizardPage(String JavaDoc name) {
102         super(name);
103         fWorkspaceRoot= ResourcesPlugin.getWorkspace().getRoot();
104         ContainerFieldAdapter adapter= new ContainerFieldAdapter();
105         
106         fContainerDialogField= new StringButtonDialogField(adapter);
107         fContainerDialogField.setDialogFieldListener(adapter);
108         fContainerDialogField.setLabelText(getContainerLabel());
109         fContainerDialogField.setButtonLabel(NewWizardMessages.NewContainerWizardPage_container_button);
110         
111         fContainerStatus= new StatusInfo();
112         fCurrRoot= null;
113     }
114
115     /**
116      * Returns the label that is used for the container input field.
117      *
118      * @return the label that is used for the container input field.
119      * @since 3.2
120      */

121     protected String JavaDoc getContainerLabel() {
122         return NewWizardMessages.NewContainerWizardPage_container_label;
123     }
124             
125     /**
126      * Initializes the source folder field with a valid package fragment root.
127      * The package fragment root is computed from the given Java element.
128      *
129      * @param elem the Java element used to compute the initial package
130      * fragment root used as the source folder
131      */

132     protected void initContainerPage(IJavaElement elem) {
133         IPackageFragmentRoot initRoot= null;
134         if (elem != null) {
135             initRoot= JavaModelUtil.getPackageFragmentRoot(elem);
136             try {
137                 if (initRoot == null || initRoot.getKind() != IPackageFragmentRoot.K_SOURCE) {
138                     IJavaProject jproject= elem.getJavaProject();
139                     if (jproject != null) {
140                             initRoot= null;
141                             if (jproject.exists()) {
142                                 IPackageFragmentRoot[] roots= jproject.getPackageFragmentRoots();
143                                 for (int i= 0; i < roots.length; i++) {
144                                     if (roots[i].getKind() == IPackageFragmentRoot.K_SOURCE) {
145                                         initRoot= roots[i];
146                                         break;
147                                     }
148                                 }
149                             }
150                         if (initRoot == null) {
151                             initRoot= jproject.getPackageFragmentRoot(jproject.getResource());
152                         }
153                     }
154                 }
155             } catch (JavaModelException e) {
156                 JavaPlugin.log(e);
157             }
158         }
159         setPackageFragmentRoot(initRoot, true);
160     }
161     
162     /**
163      * Utility method to inspect a selection to find a Java element.
164      *
165      * @param selection the selection to be inspected
166      * @return a Java element to be used as the initial selection, or <code>null</code>,
167      * if no Java element exists in the given selection
168      */

169     protected IJavaElement getInitialJavaElement(IStructuredSelection selection) {
170         IJavaElement jelem= null;
171         if (selection != null && !selection.isEmpty()) {
172             Object JavaDoc selectedElement= selection.getFirstElement();
173             if (selectedElement instanceof IAdaptable) {
174                 IAdaptable adaptable= (IAdaptable) selectedElement;
175                 
176                 jelem= (IJavaElement) adaptable.getAdapter(IJavaElement.class);
177                 if (jelem == null) {
178                     IResource resource= (IResource) adaptable.getAdapter(IResource.class);
179                     if (resource != null && resource.getType() != IResource.ROOT) {
180                         while (jelem == null && resource.getType() != IResource.PROJECT) {
181                             resource= resource.getParent();
182                             jelem= (IJavaElement) resource.getAdapter(IJavaElement.class);
183                         }
184                         if (jelem == null) {
185                             jelem= JavaCore.create(resource); // java project
186
}
187                     }
188                 }
189             }
190         }
191         if (jelem == null) {
192             IWorkbenchPart part= JavaPlugin.getActivePage().getActivePart();
193             if (part instanceof ContentOutline) {
194                 part= JavaPlugin.getActivePage().getActiveEditor();
195             }
196             
197             if (part instanceof IViewPartInputProvider) {
198                 Object JavaDoc elem= ((IViewPartInputProvider)part).getViewPartInput();
199                 if (elem instanceof IJavaElement) {
200                     jelem= (IJavaElement) elem;
201                 }
202             }
203         }
204
205         if (jelem == null || jelem.getElementType() == IJavaElement.JAVA_MODEL) {
206             try {
207                 IJavaProject[] projects= JavaCore.create(getWorkspaceRoot()).getJavaProjects();
208                 if (projects.length == 1) {
209                     jelem= projects[0];
210                 }
211             } catch (JavaModelException e) {
212                 JavaPlugin.log(e);
213             }
214         }
215         return jelem;
216     }
217     
218     /**
219      * Returns the text selection of the current editor. <code>null</code> is returned
220      * when the current editor does not have focus or does not return a text selection.
221      * @return Returns the text selection of the current editor or <code>null</code>.
222      *
223      * @since 3.0
224      */

225     protected ITextSelection getCurrentTextSelection() {
226         IWorkbenchPart part= JavaPlugin.getActivePage().getActivePart();
227         if (part instanceof IEditorPart) {
228             ISelectionProvider selectionProvider= part.getSite().getSelectionProvider();
229             if (selectionProvider != null) {
230                 ISelection selection= selectionProvider.getSelection();
231                 if (selection instanceof ITextSelection) {
232                     return (ITextSelection) selection;
233                 }
234             }
235         }
236         return null;
237     }
238     
239     
240     /**
241      * Returns the recommended maximum width for text fields (in pixels). This
242      * method requires that createContent has been called before this method is
243      * call. Subclasses may override to change the maximum width for text
244      * fields.
245      *
246      * @return the recommended maximum width for text fields.
247      */

248     protected int getMaxFieldWidth() {
249         return convertWidthInCharsToPixels(40);
250     }
251     
252     
253     /**
254      * Creates the necessary controls (label, text field and browse button) to edit
255      * the source folder location. The method expects that the parent composite
256      * uses a <code>GridLayout</code> as its layout manager and that the
257      * grid layout has at least 3 columns.
258      *
259      * @param parent the parent composite
260      * @param nColumns the number of columns to span. This number must be
261      * greater or equal three
262      */

263     protected void createContainerControls(Composite parent, int nColumns) {
264         fContainerDialogField.doFillIntoGrid(parent, nColumns);
265         LayoutUtil.setWidthHint(fContainerDialogField.getTextControl(null), getMaxFieldWidth());
266     }
267
268     /**
269      * Sets the focus to the source folder's text field.
270      */

271     protected void setFocusOnContainer() {
272         fContainerDialogField.setFocus();
273     }
274
275     // -------- ContainerFieldAdapter --------
276

277     private class ContainerFieldAdapter implements IStringButtonAdapter, IDialogFieldListener {
278
279         // -------- IStringButtonAdapter
280
public void changeControlPressed(DialogField field) {
281             containerChangeControlPressed(field);
282         }
283         
284         // -------- IDialogFieldListener
285
public void dialogFieldChanged(DialogField field) {
286             containerDialogFieldChanged(field);
287         }
288     }
289     
290     private void containerChangeControlPressed(DialogField field) {
291         // take the current jproject as init element of the dialog
292
IPackageFragmentRoot root= chooseContainer();
293         if (root != null) {
294             setPackageFragmentRoot(root, true);
295         }
296     }
297     
298     private void containerDialogFieldChanged(DialogField field) {
299         if (field == fContainerDialogField) {
300             fContainerStatus= containerChanged();
301         }
302         // tell all others
303
handleFieldChanged(CONTAINER);
304     }
305     
306     // ----------- validation ----------
307

308     /**
309      * This method is a hook which gets called after the source folder's
310      * text input field has changed. This default implementation updates
311      * the model and returns an error status. The underlying model
312      * is only valid if the returned status is OK.
313      *
314      * @return the model's error status
315      */

316     protected IStatus containerChanged() {
317         StatusInfo status= new StatusInfo();
318         
319         fCurrRoot= null;
320         String JavaDoc str= getPackageFragmentRootText();
321         if (str.length() == 0) {
322             status.setError(NewWizardMessages.NewContainerWizardPage_error_EnterContainerName);
323             return status;
324         }
325         IPath path= new Path(str);
326         IResource res= fWorkspaceRoot.findMember(path);
327         if (res != null) {
328             int resType= res.getType();
329             if (resType == IResource.PROJECT || resType == IResource.FOLDER) {
330                 IProject proj= res.getProject();
331                 if (!proj.isOpen()) {
332                     status.setError(Messages.format(NewWizardMessages.NewContainerWizardPage_error_ProjectClosed, proj.getFullPath().toString()));
333                     return status;
334                 }
335                 IJavaProject jproject= JavaCore.create(proj);
336                 fCurrRoot= jproject.getPackageFragmentRoot(res);
337                 if (res.exists()) {
338                     try {
339                         if (!proj.hasNature(JavaCore.NATURE_ID)) {
340                             if (resType == IResource.PROJECT) {
341                                 status.setError(NewWizardMessages.NewContainerWizardPage_warning_NotAJavaProject);
342                             } else {
343                                 status.setWarning(NewWizardMessages.NewContainerWizardPage_warning_NotInAJavaProject);
344                             }
345                             return status;
346                         }
347                         if (fCurrRoot.isArchive()) {
348                             status.setError(Messages.format(NewWizardMessages.NewContainerWizardPage_error_ContainerIsBinary, str));
349                             return status;
350                         }
351                         if (fCurrRoot.getKind() == IPackageFragmentRoot.K_BINARY) {
352                             status.setWarning(Messages.format(NewWizardMessages.NewContainerWizardPage_warning_inside_classfolder, str));
353                         } else if (!jproject.isOnClasspath(fCurrRoot)) {
354                             status.setWarning(Messages.format(NewWizardMessages.NewContainerWizardPage_warning_NotOnClassPath, str));
355                         }
356                     } catch (CoreException e) {
357                         status.setWarning(NewWizardMessages.NewContainerWizardPage_warning_NotAJavaProject);
358                     }
359                 }
360                 return status;
361             } else {
362                 status.setError(Messages.format(NewWizardMessages.NewContainerWizardPage_error_NotAFolder, str));
363                 return status;
364             }
365         } else {
366             status.setError(Messages.format(NewWizardMessages.NewContainerWizardPage_error_ContainerDoesNotExist, str));
367             return status;
368         }
369     }
370         
371     // -------- update message ----------------
372

373     /**
374      * Hook method that gets called when a field on this page has changed. For this page the
375      * method gets called when the source folder field changes.
376      * <p>
377      * Every sub type is responsible to call this method when a field on its page has changed.
378      * Subtypes override (extend) the method to add verification when a own field has a
379      * dependency to an other field. For example the class name input must be verified
380      * again when the package field changes (check for duplicated class names).
381      *
382      * @param fieldName The name of the field that has changed (field id). For the
383      * source folder the field id is <code>CONTAINER</code>
384      */

385     protected void handleFieldChanged(String JavaDoc fieldName) {
386     }
387     
388     
389     // ---- get ----------------
390

391     /**
392      * Returns the workspace root.
393      *
394      * @return the workspace root
395      */

396     protected IWorkspaceRoot getWorkspaceRoot() {
397         return fWorkspaceRoot;
398     }
399     
400     /**
401      * Returns the Java project of the currently selected package fragment root or <code>null</code>
402      * if no package fragment root is configured.
403      *
404      * @return The current Java project or <code>null</code>.
405      * @since 3.3
406      */

407     public IJavaProject getJavaProject() {
408         IPackageFragmentRoot root= getPackageFragmentRoot();
409         if (root != null) {
410             return root.getJavaProject();
411         }
412         return null;
413     }
414     
415     /**
416      * Returns the <code>IPackageFragmentRoot</code> that corresponds to the current
417      * value of the source folder field.
418      *
419      * @return the IPackageFragmentRoot or <code>null</code> if the current source
420      * folder value is not a valid package fragment root
421      *
422      */

423     public IPackageFragmentRoot getPackageFragmentRoot() {
424         return fCurrRoot;
425     }
426
427     /**
428      * Returns the current text of source folder text field.
429      *
430      * @return the text of the source folder text field
431      */

432     public String JavaDoc getPackageFragmentRootText() {
433         return fContainerDialogField.getText();
434     }
435     
436     
437     /**
438      * Sets the current source folder (model and text field) to the given package
439      * fragment root.
440
441      * @param root The new root.
442      * @param canBeModified if <code>false</code> the source folder field can
443      * not be changed by the user. If <code>true</code> the field is editable
444      */

445     public void setPackageFragmentRoot(IPackageFragmentRoot root, boolean canBeModified) {
446         fCurrRoot= root;
447         String JavaDoc str= (root == null) ? "" : root.getPath().makeRelative().toString(); //$NON-NLS-1$
448
fContainerDialogField.setText(str);
449         fContainerDialogField.setEnabled(canBeModified);
450     }
451         
452     // ------------- choose source container dialog
453

454     /**
455      * Opens a selection dialog that allows to select a source container.
456      *
457      * @return returns the selected package fragment root or <code>null</code> if the dialog has been canceled.
458      * The caller typically sets the result to the container input field.
459      * <p>
460      * Clients can override this method if they want to offer a different dialog.
461      * </p>
462      *
463      * @since 3.2
464      */

465     protected IPackageFragmentRoot chooseContainer() {
466         IJavaElement initElement= getPackageFragmentRoot();
467         Class JavaDoc[] acceptedClasses= new Class JavaDoc[] { IPackageFragmentRoot.class, IJavaProject.class };
468         TypedElementSelectionValidator validator= new TypedElementSelectionValidator(acceptedClasses, false) {
469             public boolean isSelectedValid(Object JavaDoc element) {
470                 try {
471                     if (element instanceof IJavaProject) {
472                         IJavaProject jproject= (IJavaProject)element;
473                         IPath path= jproject.getProject().getFullPath();
474                         return (jproject.findPackageFragmentRoot(path) != null);
475                     } else if (element instanceof IPackageFragmentRoot) {
476                         return (((IPackageFragmentRoot)element).getKind() == IPackageFragmentRoot.K_SOURCE);
477                     }
478                     return true;
479                 } catch (JavaModelException e) {
480                     JavaPlugin.log(e.getStatus()); // just log, no UI in validation
481
}
482                 return false;
483             }
484         };
485         
486         acceptedClasses= new Class JavaDoc[] { IJavaModel.class, IPackageFragmentRoot.class, IJavaProject.class };
487         ViewerFilter filter= new TypedViewerFilter(acceptedClasses) {
488             public boolean select(Viewer viewer, Object JavaDoc parent, Object JavaDoc element) {
489                 if (element instanceof IPackageFragmentRoot) {
490                     try {
491                         return (((IPackageFragmentRoot)element).getKind() == IPackageFragmentRoot.K_SOURCE);
492                     } catch (JavaModelException e) {
493                         JavaPlugin.log(e.getStatus()); // just log, no UI in validation
494
return false;
495                     }
496                 }
497                 return super.select(viewer, parent, element);
498             }
499         };
500
501         StandardJavaElementContentProvider provider= new StandardJavaElementContentProvider();
502         ILabelProvider labelProvider= new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_DEFAULT);
503         ElementTreeSelectionDialog dialog= new ElementTreeSelectionDialog(getShell(), labelProvider, provider);
504         dialog.setValidator(validator);
505         dialog.setComparator(new JavaElementComparator());
506         dialog.setTitle(NewWizardMessages.NewContainerWizardPage_ChooseSourceContainerDialog_title);
507         dialog.setMessage(NewWizardMessages.NewContainerWizardPage_ChooseSourceContainerDialog_description);
508         dialog.addFilter(filter);
509         dialog.setInput(JavaCore.create(fWorkspaceRoot));
510         dialog.setInitialSelection(initElement);
511         dialog.setHelpAvailable(false);
512         
513         if (dialog.open() == Window.OK) {
514             Object JavaDoc element= dialog.getFirstResult();
515             if (element instanceof IJavaProject) {
516                 IJavaProject jproject= (IJavaProject)element;
517                 return jproject.getPackageFragmentRoot(jproject.getProject());
518             } else if (element instanceof IPackageFragmentRoot) {
519                 return (IPackageFragmentRoot)element;
520             }
521             return null;
522         }
523         return null;
524     }
525     
526 }
527
Popular Tags