]> git.uio.no Git - ifi-stolz-refaktor.git/blob - case-study/jdt-before/ui/org/eclipse/jdt/internal/ui/wizards/buildpaths/newsourcepage/DialogPackageExplorer.java
Case Study: adding data and statistics
[ifi-stolz-refaktor.git] / case-study / jdt-before / ui / org / eclipse / jdt / internal / ui / wizards / buildpaths / newsourcepage / DialogPackageExplorer.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2011 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
12 package org.eclipse.jdt.internal.ui.wizards.buildpaths.newsourcepage;
13
14 import java.util.ArrayList;
15 import java.util.List;
16
17 import org.eclipse.swt.SWT;
18 import org.eclipse.swt.events.DisposeEvent;
19 import org.eclipse.swt.events.DisposeListener;
20 import org.eclipse.swt.graphics.Color;
21 import org.eclipse.swt.graphics.Image;
22 import org.eclipse.swt.widgets.Composite;
23 import org.eclipse.swt.widgets.Control;
24 import org.eclipse.swt.widgets.Display;
25 import org.eclipse.swt.widgets.Menu;
26
27 import org.eclipse.core.runtime.CoreException;
28 import org.eclipse.core.runtime.IProgressMonitor;
29 import org.eclipse.core.runtime.NullProgressMonitor;
30
31 import org.eclipse.core.resources.IFile;
32 import org.eclipse.core.resources.IFolder;
33 import org.eclipse.core.resources.IResource;
34 import org.eclipse.core.resources.IWorkspace;
35 import org.eclipse.core.resources.IWorkspaceRunnable;
36 import org.eclipse.core.resources.ResourcesPlugin;
37
38 import org.eclipse.jface.action.IMenuListener;
39 import org.eclipse.jface.action.IMenuManager;
40 import org.eclipse.jface.action.MenuManager;
41 import org.eclipse.jface.viewers.DoubleClickEvent;
42 import org.eclipse.jface.viewers.IDoubleClickListener;
43 import org.eclipse.jface.viewers.IPostSelectionProvider;
44 import org.eclipse.jface.viewers.ISelection;
45 import org.eclipse.jface.viewers.ISelectionChangedListener;
46 import org.eclipse.jface.viewers.IStructuredSelection;
47 import org.eclipse.jface.viewers.StructuredSelection;
48 import org.eclipse.jface.viewers.TreeViewer;
49 import org.eclipse.jface.viewers.Viewer;
50
51 import org.eclipse.ui.part.ISetSelectionTarget;
52
53 import org.eclipse.jdt.core.IClasspathEntry;
54 import org.eclipse.jdt.core.IJavaProject;
55 import org.eclipse.jdt.core.IPackageFragment;
56 import org.eclipse.jdt.core.IPackageFragmentRoot;
57 import org.eclipse.jdt.core.JavaModelException;
58
59 import org.eclipse.jdt.internal.corext.buildpath.ClasspathModifier;
60 import org.eclipse.jdt.internal.corext.util.Messages;
61
62 import org.eclipse.jdt.ui.JavaElementComparator;
63 import org.eclipse.jdt.ui.JavaElementLabels;
64
65 import org.eclipse.jdt.internal.ui.JavaPlugin;
66 import org.eclipse.jdt.internal.ui.filters.LibraryFilter;
67 import org.eclipse.jdt.internal.ui.filters.OutputFolderFilter;
68 import org.eclipse.jdt.internal.ui.packageview.PackageExplorerContentProvider;
69 import org.eclipse.jdt.internal.ui.packageview.PackageFragmentRootContainer;
70 import org.eclipse.jdt.internal.ui.viewsupport.AppearanceAwareLabelProvider;
71 import org.eclipse.jdt.internal.ui.viewsupport.DecoratingJavaLabelProvider;
72 import org.eclipse.jdt.internal.ui.viewsupport.JavaElementImageProvider;
73 import org.eclipse.jdt.internal.ui.wizards.NewWizardMessages;
74 import org.eclipse.jdt.internal.ui.wizards.buildpaths.CPListElement;
75 import org.eclipse.jdt.internal.ui.wizards.buildpaths.CPListElementAttribute;
76 import org.eclipse.jdt.internal.ui.wizards.buildpaths.CPListLabelProvider;
77 import org.eclipse.jdt.internal.ui.workingsets.WorkingSetModel;
78
79 /**
80  * A package explorer widget that can be used in dialogs. It uses its own
81  * content provider, label provider, element sorter and filter to display
82  * elements that are not shown usually in the package explorer of the
83  * workspace.
84  */
85 public class DialogPackageExplorer implements IMenuListener, IPostSelectionProvider, ISetSelectionTarget {
86     /**
87      * A extended content provider for the package explorer which can additionally display
88      * an output folder item.
89      */
90     private final class PackageContentProvider extends PackageExplorerContentProvider {
91         public PackageContentProvider() {
92             super(false);
93         }
94
95         /**
96          * Get the elements of the current project
97          *
98          * @param element the element to get the children from, will
99          * not be used, instead the project children are returned directly
100          * @return returns the children of the project
101          */
102         @Override
103                 public Object[] getElements(Object element) {
104             if (fCurrJProject == null || !fCurrJProject.exists())
105                 return new Object[0];
106             return new Object[] {fCurrJProject};
107         }
108
109         /**
110          * Get the children of the current <code>element</code>. If the
111          * element is of type <code>IPackageFragmentRoot</code> and
112          * displaying the output folders is selected, then an icon for
113          * the output folder is created and displayed additionally.
114          *
115          * @param element the current element to get the children from
116          * @return an array of children
117          */
118         @Override
119                 public Object[] getChildren(Object element) {
120             Object[] children= super.getChildren(element);
121             if (((element instanceof IPackageFragmentRoot && !ClasspathModifier.isInExternalOrArchive((IPackageFragmentRoot) element)) ||
122                     (element instanceof IJavaProject && fCurrJProject.isOnClasspath(fCurrJProject))) && fShowOutputFolders) {
123                 try {
124                     IClasspathEntry entry;
125                     if (element instanceof IPackageFragmentRoot)
126                         entry= ((IPackageFragmentRoot) element).getRawClasspathEntry();
127                     else
128                         entry= ClasspathModifier.getClasspathEntryFor(fCurrJProject.getPath(), fCurrJProject, IClasspathEntry.CPE_SOURCE);
129                     CPListElement parent= CPListElement.createFromExisting(entry, fCurrJProject);
130                     CPListElementAttribute outputFolder= new CPListElementAttribute(parent, CPListElement.OUTPUT,
131                             parent.getAttribute(CPListElement.OUTPUT), true);
132                     Object[] extendedChildren= new Object[children.length + 1];
133                     System.arraycopy(children, 0, extendedChildren, 1, children.length);
134                     extendedChildren[0]= outputFolder;
135                     return extendedChildren;
136                 } catch (JavaModelException e) {
137                     JavaPlugin.log(e);
138                 }
139                 return null;
140             }
141             else
142                 return children;
143         }
144     }
145
146     /**
147      * A extended label provider for the package explorer which can additionally display
148      * an output folder item.
149      */
150     private final class PackageLabelProvider extends AppearanceAwareLabelProvider {
151         private CPListLabelProvider outputFolderLabel;
152
153         public PackageLabelProvider(long textFlags, int imageFlags) {
154             super(textFlags, imageFlags);
155             outputFolderLabel= new CPListLabelProvider();
156         }
157
158         @Override
159                 public String getText(Object element) {
160             if (element instanceof CPListElementAttribute)
161                 return outputFolderLabel.getText(element);
162             String text= super.getText(element);
163             try {
164                 if (element instanceof IPackageFragmentRoot) {
165                     IPackageFragmentRoot root= (IPackageFragmentRoot)element;
166                     if (root.exists() && ClasspathModifier.filtersSet(root)) {
167                         IClasspathEntry entry= root.getRawClasspathEntry();
168                         int excluded= entry.getExclusionPatterns().length;
169                         if (excluded == 1)
170                             return Messages.format(NewWizardMessages.DialogPackageExplorer_LabelProvider_SingleExcluded, text);
171                         else if (excluded > 1)
172                             return Messages.format(NewWizardMessages.DialogPackageExplorer_LabelProvider_MultiExcluded, new Object[] {text, new Integer(excluded)});
173                     }
174                 }
175                 if (element instanceof IJavaProject) {
176                     IJavaProject project= (IJavaProject)element;
177                     if (project.exists() && project.isOnClasspath(project)) {
178                         IPackageFragmentRoot root= project.findPackageFragmentRoot(project.getPath());
179                         if (ClasspathModifier.filtersSet(root)) {
180                             IClasspathEntry entry= root.getRawClasspathEntry();
181                             int excluded= entry.getExclusionPatterns().length;
182                             if (excluded == 1)
183                                 return Messages.format(NewWizardMessages.DialogPackageExplorer_LabelProvider_SingleExcluded, text);
184                             else if (excluded > 1)
185                                 return Messages.format(NewWizardMessages.DialogPackageExplorer_LabelProvider_MultiExcluded, new Object[] {text, new Integer(excluded)});
186                         }
187                     }
188                 }
189                 if (element instanceof IFile || element instanceof IFolder) {
190                     IResource resource= (IResource)element;
191                         if (resource.exists() && ClasspathModifier.isExcluded(resource, fCurrJProject))
192                             return Messages.format(NewWizardMessages.DialogPackageExplorer_LabelProvider_Excluded, text);
193                 }
194             } catch (JavaModelException e) {
195                 JavaPlugin.log(e);
196             }
197             return text;
198         }
199
200         /* (non-Javadoc)
201          * @see org.eclipse.jdt.internal.ui.viewsupport.JavaUILabelProvider#getForeground(java.lang.Object)
202          */
203         @Override
204                 public Color getForeground(Object element) {
205             try {
206                 if (element instanceof IPackageFragmentRoot) {
207                     IPackageFragmentRoot root= (IPackageFragmentRoot)element;
208                     if (root.exists() && ClasspathModifier.filtersSet(root))
209                         return getBlueColor();
210                 }
211                 if (element instanceof IJavaProject) {
212                     IJavaProject project= (IJavaProject)element;
213                     if (project.exists() && project.isOnClasspath(project)) {
214                         IPackageFragmentRoot root= project.findPackageFragmentRoot(project.getPath());
215                         if (root != null && ClasspathModifier.filtersSet(root))
216                             return getBlueColor();
217                     }
218                 }
219                 if (element instanceof IFile || element instanceof IFolder) {
220                     IResource resource= (IResource)element;
221                     if (resource.exists() && ClasspathModifier.isExcluded(resource, fCurrJProject))
222                         return getBlueColor();
223                 }
224             } catch (JavaModelException e) {
225                 JavaPlugin.log(e);
226             }
227             return null;
228         }
229
230         private Color getBlueColor() {
231             return Display.getCurrent().getSystemColor(SWT.COLOR_BLUE);
232         }
233
234         @Override
235                 public Image getImage(Object element) {
236             if (element instanceof CPListElementAttribute)
237                 return outputFolderLabel.getImage(element);
238             return super.getImage(element);
239         }
240
241         @Override
242                 public void dispose() {
243             outputFolderLabel.dispose();
244             super.dispose();
245         }
246     }
247
248     /**
249      * A extended element sorter for the package explorer which displays the output
250      * folder (if any) as first child of a source folder. The other java elements
251      * are sorted in the normal way.
252      */
253     private final class ExtendedJavaElementSorter extends JavaElementComparator {
254         public ExtendedJavaElementSorter() {
255             super();
256         }
257
258         @Override
259                 public int compare(Viewer viewer, Object e1, Object e2) {
260             if (e1 instanceof CPListElementAttribute)
261                 return -1;
262             if (e2 instanceof CPListElementAttribute)
263                 return 1;
264             return super.compare(viewer, e1, e2);
265         }
266     }
267
268     /**
269      * An extended filter for the package explorer which filters
270      * libraries,
271      * files named ".classpath" or ".project",
272      * the default package, and
273      * hidden folders.
274      */
275     private final class PackageFilter extends LibraryFilter {
276         private OutputFolderFilter fOutputFolderFilter= new OutputFolderFilter();
277         @Override
278                 public boolean select(Viewer viewer, Object parentElement, Object element) {
279             try {
280                 if (element instanceof IFile) {
281                     IFile file= (IFile) element;
282                     if (file.getName().equals(".classpath") || file.getName().equals(".project")) //$NON-NLS-1$//$NON-NLS-2$
283                         return false;
284                 } else if (element instanceof IPackageFragmentRoot) {
285                     IClasspathEntry cpe= ((IPackageFragmentRoot)element).getRawClasspathEntry();
286                     if (cpe == null || cpe.getEntryKind() == IClasspathEntry.CPE_CONTAINER || cpe.getEntryKind() == IClasspathEntry.CPE_LIBRARY || cpe.getEntryKind() == IClasspathEntry.CPE_VARIABLE)
287                         return false;
288                 } else if (element instanceof PackageFragmentRootContainer) {
289                         return false;
290                 } else if (element instanceof IPackageFragment) {
291                                         IPackageFragment fragment= (IPackageFragment)element;
292                         if (fragment.isDefaultPackage() && !fragment.hasChildren())
293                                 return false;
294                 } else if (element instanceof IFolder) {
295                         IFolder folder= (IFolder)element;
296                         if (folder.getName().startsWith(".")) //$NON-NLS-1$
297                                 return false;
298                 }
299             } catch (JavaModelException e) {
300                 JavaPlugin.log(e);
301             }
302             /*if (element instanceof IPackageFragmentRoot) {
303                 IPackageFragmentRoot root= (IPackageFragmentRoot)element;
304                 if (root.getElementName().endsWith(".jar") || root.getElementName().endsWith(".zip")) //$NON-NLS-1$ //$NON-NLS-2$
305                     return false;
306             }*/
307             return /*super.select(viewer, parentElement, element) &&*/ fOutputFolderFilter.select(viewer, parentElement, element);
308         }
309     }
310
311     /** The tree showing the project like in the package explorer */
312     private TreeViewer fPackageViewer;
313     /** The tree's context menu */
314     private Menu fContextMenu;
315     /** The action group which is used to fill the context menu. The action group
316      * is also called if the selection on the tree changes */
317     private DialogPackageExplorerActionGroup fActionGroup;
318     /**
319      * Flag to indicate whether output folders
320      * can be created or not. This is used to
321      * set the content correctly in the case
322      * that a IPackageFragmentRoot is selected.
323      *
324      * @see #showOutputFolders(boolean)
325      */
326     private boolean fShowOutputFolders= false;
327
328     /** Stores the current selection in the tree
329      * @see #getSelection()
330      */
331     private IStructuredSelection fCurrentSelection;
332
333     /** The current java project
334      * @see #setInput(IJavaProject)
335      */
336     private IJavaProject fCurrJProject;
337         private PackageContentProvider fContentProvider;
338
339     public DialogPackageExplorer() {
340         fActionGroup= null;
341         fCurrJProject= null;
342         fCurrentSelection= new StructuredSelection();
343     }
344
345     public Control createControl(Composite parent) {
346         fPackageViewer= new TreeViewer(parent, SWT.MULTI);
347         fPackageViewer.setComparer(WorkingSetModel.COMPARER);
348         fPackageViewer.addFilter(new PackageFilter());
349         fPackageViewer.setComparator(new ExtendedJavaElementSorter());
350         fPackageViewer.addDoubleClickListener(new IDoubleClickListener() {
351             public void doubleClick(DoubleClickEvent event) {
352                 Object element= ((IStructuredSelection)event.getSelection()).getFirstElement();
353                 if (fPackageViewer.isExpandable(element)) {
354                     fPackageViewer.setExpandedState(element, !fPackageViewer.getExpandedState(element));
355                 } else {
356                         if (element instanceof CPListElementAttribute) {
357                                                 CPListElementAttribute attribute= (CPListElementAttribute)element;
358                                 if (attribute.getKey().equals(CPListElement.OUTPUT)) {
359                                         fActionGroup.getEditOutputFolderAction().run();
360                                 }
361                         }
362                 }
363             }
364         });
365
366         MenuManager menuMgr= new MenuManager("#PopupMenu"); //$NON-NLS-1$
367         menuMgr.setRemoveAllWhenShown(true);
368         menuMgr.addMenuListener(this);
369         fContextMenu= menuMgr.createContextMenu(fPackageViewer.getTree());
370         fPackageViewer.getTree().setMenu(fContextMenu);
371         parent.addDisposeListener(new DisposeListener() {
372             public void widgetDisposed(DisposeEvent e) {
373                 fContextMenu.dispose();
374             }
375         });
376
377         return fPackageViewer.getControl();
378     }
379
380     /**
381      * Sets the action group for the package explorer.
382      * The action group is necessary to populate the
383      * context menu with available actions. If no
384      * context menu is needed, then this method does not
385      * have to be called.
386      *
387      * Should only be called once.
388      *
389      * @param actionGroup the action group to be used for
390      * the context menu.
391      */
392     public void setActionGroup(final DialogPackageExplorerActionGroup actionGroup) {
393         fActionGroup= actionGroup;
394     }
395
396     /**
397      * Populate the context menu with the necessary actions.
398      *
399      * @see org.eclipse.jface.action.IMenuListener#menuAboutToShow(org.eclipse.jface.action.IMenuManager)
400      */
401     public void menuAboutToShow(IMenuManager manager) {
402         if (fActionGroup == null) // no context menu
403             return;
404         JavaPlugin.createStandardGroups(manager);
405         fActionGroup.fillContextMenu(manager);
406     }
407
408     /**
409      * Set the content and label provider of the
410      * <code>fPackageViewer</code>
411      */
412     public void setContentProvider() {
413         if (fContentProvider != null) {
414                 fContentProvider.dispose();
415         }
416                 fContentProvider= new PackageContentProvider();
417                 fContentProvider.setIsFlatLayout(true);
418                 PackageLabelProvider labelProvider= new PackageLabelProvider(AppearanceAwareLabelProvider.DEFAULT_TEXTFLAGS | JavaElementLabels.P_COMPRESSED,
419                                 AppearanceAwareLabelProvider.DEFAULT_IMAGEFLAGS | JavaElementImageProvider.SMALL_ICONS);
420                 fPackageViewer.setContentProvider(fContentProvider);
421                 fPackageViewer.setLabelProvider(new DecoratingJavaLabelProvider(labelProvider, false));
422     }
423
424     /**
425      * Set the input for the package explorer.
426      *
427      * @param project the project to be displayed
428      */
429     public void setInput(IJavaProject project) {
430         IJavaProject oldProject= fCurrJProject;
431         fCurrJProject= project;
432         if (fContentProvider != null)
433                 fContentProvider.inputChanged(fPackageViewer, oldProject, fCurrJProject);
434                 fPackageViewer.setInput(new Object[0]);
435
436         List<IJavaProject> selectedElements= new ArrayList<IJavaProject>();
437         selectedElements.add(fCurrJProject);
438         setSelection(selectedElements);
439     }
440
441     public void dispose() {
442         if (fContentProvider != null) {
443                 fContentProvider.dispose();
444                 fContentProvider= null;
445         }
446         if (fActionGroup != null) {
447                 fActionGroup.dispose();
448                 fActionGroup= null;
449         }
450         fPackageViewer= null;
451     }
452
453     /**
454      * Set the selection and focus to the list of elements
455      * @param elements the object to be selected and displayed
456      */
457     public void setSelection(final List<?> elements) {
458         if (elements == null || elements.size() == 0)
459             return;
460                 try {
461                 ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
462                         public void run(IProgressMonitor monitor) throws CoreException {
463                                 fPackageViewer.refresh();
464                         IStructuredSelection selection= new StructuredSelection(elements);
465                         fPackageViewer.setSelection(selection, true);
466                         fPackageViewer.getTree().setFocus();
467
468                         if (elements.size() == 1 && elements.get(0) instanceof IJavaProject)
469                             fPackageViewer.expandToLevel(elements.get(0), 1);
470                     }
471                 }, ResourcesPlugin.getWorkspace().getRoot(), IWorkspace.AVOID_UPDATE, new NullProgressMonitor());
472         } catch (CoreException e) {
473                 JavaPlugin.log(e);
474         }
475     }
476
477     /**
478      * The current list of selected elements. The
479      * list may be empty if no element is selected.
480      *
481      * @return the current selection
482      */
483     public ISelection getSelection() {
484         return fCurrentSelection;
485     }
486
487     /**
488      * Get the viewer's control
489      *
490      * @return the viewers control
491      */
492     public Control getViewerControl() {
493         return fPackageViewer.getControl();
494     }
495
496     /**
497      * Method that is called whenever setting of
498      * output folders is allowed or forbidden (for example
499      * on changing a checkbox with this setting):
500      *
501      * @param showOutputFolders <code>true</code> if output
502      * folders should be shown, <code>false</code> otherwise.
503      */
504     public void showOutputFolders(boolean showOutputFolders) {
505         fShowOutputFolders= showOutputFolders;
506         fActionGroup.getEditOutputFolderAction().showOutputFolders(showOutputFolders);
507         fPackageViewer.refresh();
508     }
509
510         /**
511      * {@inheritDoc}
512      */
513     public void addSelectionChangedListener(ISelectionChangedListener listener) {
514         fPackageViewer.addSelectionChangedListener(listener);
515     }
516
517         /**
518      * {@inheritDoc}
519      */
520     public void removeSelectionChangedListener(ISelectionChangedListener listener) {
521         fPackageViewer.removeSelectionChangedListener(listener);
522     }
523
524         /**
525      * {@inheritDoc}
526      */
527     public void setSelection(ISelection selection) {
528         setSelection(((StructuredSelection)selection).toList());
529     }
530
531         /**
532      * {@inheritDoc}
533      */
534     public void addPostSelectionChangedListener(ISelectionChangedListener listener) {
535         fPackageViewer.addPostSelectionChangedListener(listener);
536     }
537
538         /**
539      * {@inheritDoc}
540      */
541     public void removePostSelectionChangedListener(ISelectionChangedListener listener) {
542         fPackageViewer.removePostSelectionChangedListener(listener);
543     }
544
545         /**
546      * {@inheritDoc}
547      */
548     public void selectReveal(ISelection selection) {
549         setSelection(selection);
550     }
551 }