]> git.uio.no Git - ifi-stolz-refaktor.git/blob - case-study/jdt-before/ui/org/eclipse/jdt/ui/wizards/BuildPathDialogAccess.java
Case Study: adding data and statistics
[ifi-stolz-refaktor.git] / case-study / jdt-before / ui / org / eclipse / jdt / ui / wizards / BuildPathDialogAccess.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2012 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 java.io.File;
14 import java.net.URL;
15 import java.util.ArrayList;
16
17 import org.eclipse.swt.SWT;
18 import org.eclipse.swt.widgets.DirectoryDialog;
19 import org.eclipse.swt.widgets.FileDialog;
20 import org.eclipse.swt.widgets.Shell;
21
22 import org.eclipse.core.runtime.IPath;
23 import org.eclipse.core.runtime.Path;
24
25 import org.eclipse.core.resources.IContainer;
26 import org.eclipse.core.resources.IFile;
27 import org.eclipse.core.resources.IFolder;
28 import org.eclipse.core.resources.IProject;
29 import org.eclipse.core.resources.IResource;
30 import org.eclipse.core.resources.IWorkspaceRoot;
31 import org.eclipse.core.resources.ResourcesPlugin;
32
33 import org.eclipse.jface.window.Window;
34
35 import org.eclipse.ui.model.WorkbenchContentProvider;
36 import org.eclipse.ui.model.WorkbenchLabelProvider;
37 import org.eclipse.ui.views.navigator.ResourceComparator;
38
39 import org.eclipse.jdt.core.IClasspathEntry;
40 import org.eclipse.jdt.core.IJavaProject;
41
42 import org.eclipse.jdt.ui.JavaUI;
43
44 import org.eclipse.jdt.internal.ui.IUIConstants;
45 import org.eclipse.jdt.internal.ui.JavaPlugin;
46 import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels;
47 import org.eclipse.jdt.internal.ui.viewsupport.FilteredElementTreeSelectionDialog;
48 import org.eclipse.jdt.internal.ui.wizards.NewWizardMessages;
49 import org.eclipse.jdt.internal.ui.wizards.TypedElementSelectionValidator;
50 import org.eclipse.jdt.internal.ui.wizards.TypedViewerFilter;
51 import org.eclipse.jdt.internal.ui.wizards.buildpaths.ArchiveFileFilter;
52 import org.eclipse.jdt.internal.ui.wizards.buildpaths.CPListElement;
53 import org.eclipse.jdt.internal.ui.wizards.buildpaths.ClasspathContainerWizard;
54 import org.eclipse.jdt.internal.ui.wizards.buildpaths.EditVariableEntryDialog;
55 import org.eclipse.jdt.internal.ui.wizards.buildpaths.JavadocLocationDialog;
56 import org.eclipse.jdt.internal.ui.wizards.buildpaths.MultipleFolderSelectionDialog;
57 import org.eclipse.jdt.internal.ui.wizards.buildpaths.NewVariableEntryDialog;
58 import org.eclipse.jdt.internal.ui.wizards.buildpaths.SourceAttachmentDialog;
59
60 /**
61  * Class that gives access to dialogs used by the Java build path page to configure classpath entries
62  * and properties of classpath entries.
63  * Static methods are provided to show dialogs for:
64  * <ul>
65  *  <li> configuration of source attachments</li>
66  *  <li> configuration of Javadoc locations</li>
67  *  <li> configuration and selection of classpath variable entries</li>
68  *  <li> configuration and selection of classpath container entries</li>
69  *  <li> configuration and selection of JAR and external JAR entries</li>
70  *  <li> selection of class and source folders</li>
71  * </ul>
72  * <p>
73  * This class is not intended to be instantiated or subclassed by clients.
74  * </p>
75  * @since 3.0
76  *
77  * @noinstantiate This class is not intended to be instantiated by clients.
78  */
79 public final class BuildPathDialogAccess {
80
81         private BuildPathDialogAccess() {
82                 // do not instantiate
83         }
84
85         /**
86          * Shows the UI for configuring source attachments, with editing of source attachment encoding
87          * disabled. <code>null</code> is returned if the user cancels the dialog. The dialog does not
88          * apply any changes.
89          * 
90          * @param shell The parent shell for the dialog
91          * @param initialEntry The entry to edit. The kind of the classpath entry must be either
92          *            <code>IClasspathEntry.CPE_LIBRARY</code> or
93          *            <code>IClasspathEntry.CPE_VARIABLE</code>.
94          * @return Returns the resulting classpath entry containing a potentially modified source
95          *         attachment path, source attachment root and source attachment encoding. The resulting
96          *         entry can be used to replace the original entry on the classpath. Note that the
97          *         dialog does not make any changes on the passed entry nor on the classpath that
98          *         contains it.
99          */
100         public static IClasspathEntry configureSourceAttachment(Shell shell, IClasspathEntry initialEntry) {
101                 return configureSourceAttachment(shell, initialEntry, false);
102         }
103
104         /**
105          * Shows the UI for configuring source attachments. The source attachment encoding can be edited
106          * depending on the parameter <code>canEditEncoding</code>. <code>null</code> is returned if the
107          * user cancels the dialog. The dialog does not apply any changes.
108          * 
109          * @param shell The parent shell for the dialog
110          * @param initialEntry The entry to edit. The kind of the classpath entry must be either
111          *            <code>IClasspathEntry.CPE_LIBRARY</code> or
112          *            <code>IClasspathEntry.CPE_VARIABLE</code>.
113          * @param canEditEncoding whether the source attachment encoding can be edited
114          * @return Returns the resulting classpath entry containing a potentially modified source
115          *         attachment path, source attachment root and source attachment encoding. The resulting
116          *         entry can be used to replace the original entry on the classpath. Note that the
117          *         dialog does not make any changes on the passed entry nor on the classpath that
118          *         contains it.
119          * @since 3.8
120          */
121         public static IClasspathEntry configureSourceAttachment(Shell shell, IClasspathEntry initialEntry, boolean canEditEncoding) {
122                 if (initialEntry == null) {
123                         throw new IllegalArgumentException();
124                 }
125                 int entryKind= initialEntry.getEntryKind();
126                 if (entryKind != IClasspathEntry.CPE_LIBRARY && entryKind != IClasspathEntry.CPE_VARIABLE) {
127                         throw new IllegalArgumentException();
128                 }
129
130                 SourceAttachmentDialog dialog=  new SourceAttachmentDialog(shell, initialEntry, canEditEncoding);
131                 if (dialog.open() == Window.OK) {
132                         return dialog.getResult();
133                 }
134                 return null;
135         }
136         
137         /**
138          * Shows the UI for configuring a javadoc location. <code>null</code> is returned
139          * if the user cancels the dialog. If OK is pressed, an array of length 1 containing the configured URL is
140          * returned. Note that the configured URL can be <code>null</code> when the user
141          * wishes to have no URL location specified. The dialog does not apply any changes.
142          * Use {@link org.eclipse.jdt.ui.JavaUI} to access and configure
143          * Javadoc locations.
144          *
145          * @param shell The parent shell for the dialog.
146          * @param libraryName Name of of the library to which configured javadoc location belongs.
147          * @param initialURL The initial URL or <code>null</code>.
148          * @return Returns an array of size 1 that contains the resulting javadoc location or
149          * <code>null</code> if the dialog has been canceled. Note that the configured URL can be <code>null</code> when the user
150          * wishes to have no URL location specified.
151          */
152         public static URL[] configureJavadocLocation(Shell shell, String libraryName, URL initialURL) {
153                 if (libraryName == null) {
154                         throw new IllegalArgumentException();
155                 }
156
157                 JavadocLocationDialog dialog=  new JavadocLocationDialog(shell, libraryName, initialURL);
158                 if (dialog.open() == Window.OK) {
159                         return new URL[] { dialog.getResult() };
160                 }
161                 return null;
162         }
163
164         /**
165          * Shows the UI for configuring a javadoc location attribute of the classpath entry. <code>null</code> is returned
166          * if the user cancels the dialog. The dialog does not apply any changes.
167          *
168          * @param shell The parent shell for the dialog.
169          * @param initialEntry The entry to edit. The kind of the classpath entry must be either
170          * <code>IClasspathEntry.CPE_LIBRARY</code> or <code>IClasspathEntry.CPE_VARIABLE</code>.
171          * @return Returns the resulting classpath entry containing a potentially modified javadoc location attribute
172          * The resulting entry can be used to replace the original entry on the classpath.
173          * Note that the dialog does not make any changes on the passed entry nor on the classpath that
174          * contains it.
175          *
176          * @since 3.1
177          */
178         public static IClasspathEntry configureJavadocLocation(Shell shell, IClasspathEntry initialEntry) {
179                 if (initialEntry == null) {
180                         throw new IllegalArgumentException();
181                 }
182                 int entryKind= initialEntry.getEntryKind();
183                 if (entryKind != IClasspathEntry.CPE_LIBRARY && entryKind != IClasspathEntry.CPE_VARIABLE) {
184                         throw new IllegalArgumentException();
185                 }
186
187                 URL location= JavaUI.getLibraryJavadocLocation(initialEntry);
188                 JavadocLocationDialog dialog=  new JavadocLocationDialog(shell, BasicElementLabels.getPathLabel(initialEntry.getPath(), false), location);
189                 if (dialog.open() == Window.OK) {
190                         CPListElement element= CPListElement.createFromExisting(initialEntry, null);
191                         URL res= dialog.getResult();
192                         element.setAttribute(CPListElement.JAVADOC, res != null ? res.toExternalForm() : null);
193                         return element.getClasspathEntry();
194                 }
195                 return null;
196         }
197
198         /**
199          * Shows the UI for configuring a variable classpath entry. See {@link IClasspathEntry#CPE_VARIABLE} for
200          * details about variable classpath entries.
201          * The dialog returns the configured classpath entry path or <code>null</code> if the dialog has
202          * been canceled. The dialog does not apply any changes.
203          *
204          * @param shell The parent shell for the dialog.
205          * @param initialEntryPath The initial variable classpath variable path or <code>null</code> to use
206          * an empty path.
207          * @param existingPaths An array of paths that are already on the classpath and therefore should not be
208          * selected again.
209          * @return Returns the configures classpath entry path or <code>null</code> if the dialog has
210          * been canceled.
211          */
212         public static IPath configureVariableEntry(Shell shell, IPath initialEntryPath, IPath[] existingPaths) {
213                 if (existingPaths == null) {
214                         throw new IllegalArgumentException();
215                 }
216
217                 EditVariableEntryDialog dialog= new EditVariableEntryDialog(shell, initialEntryPath, existingPaths);
218                 if (dialog.open() == Window.OK) {
219                         return dialog.getPath();
220                 }
221                 return null;
222         }
223
224         /**
225          * Shows the UI for selecting new variable classpath entries. See {@link IClasspathEntry#CPE_VARIABLE} for
226          * details about variable classpath entries.
227          * The dialog returns an array of the selected variable entries or <code>null</code> if the dialog has
228          * been canceled. The dialog does not apply any changes.
229          *
230          * @param shell The parent shell for the dialog.
231          * @param existingPaths An array of paths that are already on the classpath and therefore should not be
232          * selected again.
233          * @return Returns an non empty array of the selected variable entries or <code>null</code> if the dialog has
234          * been canceled.
235          */
236         public static IPath[] chooseVariableEntries(Shell shell, IPath[] existingPaths) {
237                 if (existingPaths == null) {
238                         throw new IllegalArgumentException();
239                 }
240                 NewVariableEntryDialog dialog= new NewVariableEntryDialog(shell);
241                 if (dialog.open() == Window.OK) {
242                         return dialog.getResult();
243                 }
244                 return null;
245         }
246
247         /**
248          * Shows the UI to configure a classpath container classpath entry. See {@link IClasspathEntry#CPE_CONTAINER} for
249          * details about container classpath entries.
250          * The dialog returns the configured classpath entry or <code>null</code> if the dialog has
251          * been canceled. The dialog does not apply any changes.
252          *
253          * @param shell The parent shell for the dialog.
254          * @param initialEntry The initial classpath container entry.
255          * @param project The project the entry belongs to. The project does not have to exist and can also be <code>null</code>.
256          * @param currentClasspath The class path entries currently selected to be set as the projects classpath. This can also
257          * include the entry to be edited. The dialog uses these entries as information only (e.g. to avoid duplicate entries); The user still can make changes after the
258          * the classpath container dialog has been closed. See {@link IClasspathContainerPageExtension} for
259          * more information.
260          * @return Returns the configured classpath container entry or <code>null</code> if the dialog has
261          * been canceled by the user.
262          */
263         public static IClasspathEntry configureContainerEntry(Shell shell, IClasspathEntry initialEntry, IJavaProject project, IClasspathEntry[] currentClasspath) {
264                 if (initialEntry == null || currentClasspath == null) {
265                         throw new IllegalArgumentException();
266                 }
267
268                 ClasspathContainerWizard wizard= new ClasspathContainerWizard(initialEntry, project, currentClasspath);
269                 if (ClasspathContainerWizard.openWizard(shell, wizard) == Window.OK) {
270                         IClasspathEntry[] created= wizard.getNewEntries();
271                         if (created != null && created.length == 1) {
272                                 return created[0];
273                         }
274                 }
275                 return null;
276         }
277
278         /**
279          * Shows the UI to choose new classpath container classpath entries. See {@link IClasspathEntry#CPE_CONTAINER} for
280          * details about container classpath entries.
281          * The dialog returns the selected classpath entries or <code>null</code> if the dialog has
282          * been canceled. The dialog does not apply any changes.
283          *
284          * @param shell The parent shell for the dialog.
285          * @param project The project the entry belongs to. The project does not have to exist and
286          * can also be <code>null</code>.
287          * @param currentClasspath The class path entries currently selected to be set as the projects classpath. This can also
288          * include the entry to be edited. The dialog uses these entries as information only; The user still can make changes after the
289          * the classpath container dialog has been closed. See {@link IClasspathContainerPageExtension} for
290          * more information.
291          * @return Returns the selected classpath container entries or <code>null</code> if the dialog has
292          * been canceled by the user.
293          */
294         public static IClasspathEntry[] chooseContainerEntries(Shell shell, IJavaProject project, IClasspathEntry[] currentClasspath) {
295                 if (currentClasspath == null) {
296                         throw new IllegalArgumentException();
297                 }
298
299                 ClasspathContainerWizard wizard= new ClasspathContainerWizard((IClasspathEntry) null, project, currentClasspath);
300                 if (ClasspathContainerWizard.openWizard(shell, wizard) == Window.OK) {
301                         return wizard.getNewEntries();
302                 }
303                 return null;
304         }
305
306
307         /**
308          * Shows the UI to configure a JAR or ZIP archive located in the workspace.
309          * The dialog returns the configured classpath entry path or <code>null</code> if the dialog has
310          * been canceled. The dialog does not apply any changes.
311          *
312          * @param shell The parent shell for the dialog.
313          * @param initialEntry The path of the initial archive entry
314          * @param usedEntries An array of paths that are already on the classpath and therefore should not be
315          * selected again.
316          * @return Returns the configured JAR path or <code>null</code> if the dialog has
317          * been canceled by the user.
318          */
319         public static IPath configureJAREntry(Shell shell, IPath initialEntry, IPath[] usedEntries) {
320                 if (initialEntry == null || usedEntries == null) {
321                         throw new IllegalArgumentException();
322                 }
323
324                 Class<?>[] acceptedClasses= new Class[] { IFile.class };
325                 TypedElementSelectionValidator validator= new TypedElementSelectionValidator(acceptedClasses, false);
326
327                 ArrayList<IResource> usedJars= new ArrayList<IResource>(usedEntries.length);
328                 IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot();
329                 for (int i= 0; i < usedEntries.length; i++) {
330                         IPath curr= usedEntries[i];
331                         if (!curr.equals(initialEntry)) {
332                                 IResource resource= root.findMember(usedEntries[i]);
333                                 if (resource instanceof IFile) {
334                                         usedJars.add(resource);
335                                 }
336                         }
337                 }
338
339                 IResource existing= root.findMember(initialEntry);
340
341                 FilteredElementTreeSelectionDialog dialog= new FilteredElementTreeSelectionDialog(shell, new WorkbenchLabelProvider(), new WorkbenchContentProvider());
342                 dialog.setValidator(validator);
343                 dialog.setTitle(NewWizardMessages.BuildPathDialogAccess_JARArchiveDialog_edit_title);
344                 dialog.setMessage(NewWizardMessages.BuildPathDialogAccess_JARArchiveDialog_edit_description);
345                 dialog.setInitialFilter(ArchiveFileFilter.JARZIP_FILTER_STRING);
346                 dialog.addFilter(new ArchiveFileFilter(usedJars, true, true));
347                 dialog.setInput(root);
348                 dialog.setComparator(new ResourceComparator(ResourceComparator.NAME));
349                 dialog.setInitialSelection(existing);
350
351                 if (dialog.open() == Window.OK) {
352                         IResource element= (IResource) dialog.getFirstResult();
353                         return element.getFullPath();
354                 }
355                 return null;
356         }
357
358         /**
359          * Shows the UI to select new JAR or ZIP archive entries located in the workspace.
360          * The dialog returns the selected entries or <code>null</code> if the dialog has
361          * been canceled. The dialog does not apply any changes.
362          *
363          * @param shell The parent shell for the dialog.
364          * @param initialSelection The path of the element (container or archive) to initially select or <code>null</code> to not select an entry.
365          * @param usedEntries An array of paths that are already on the classpath and therefore should not be
366          * selected again.
367          * @return Returns the new JAR paths or <code>null</code> if the dialog has
368          * been canceled by the user.
369          */
370         public static IPath[] chooseJAREntries(Shell shell, IPath initialSelection, IPath[] usedEntries) {
371                 if (usedEntries == null) {
372                         throw new IllegalArgumentException();
373                 }
374
375                 Class<?>[] acceptedClasses= new Class[] { IFile.class };
376                 TypedElementSelectionValidator validator= new TypedElementSelectionValidator(acceptedClasses, true);
377                 ArrayList<IResource> usedJars= new ArrayList<IResource>(usedEntries.length);
378                 IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot();
379                 for (int i= 0; i < usedEntries.length; i++) {
380                         IResource resource= root.findMember(usedEntries[i]);
381                         if (resource instanceof IFile) {
382                                 usedJars.add(resource);
383                         }
384                 }
385                 IResource focus= initialSelection != null ? root.findMember(initialSelection) : null;
386
387                 FilteredElementTreeSelectionDialog dialog= new FilteredElementTreeSelectionDialog(shell, new WorkbenchLabelProvider(), new WorkbenchContentProvider());
388                 dialog.setHelpAvailable(false);
389                 dialog.setValidator(validator);
390                 dialog.setTitle(NewWizardMessages.BuildPathDialogAccess_JARArchiveDialog_new_title);
391                 dialog.setMessage(NewWizardMessages.BuildPathDialogAccess_JARArchiveDialog_new_description);
392                 dialog.setInitialFilter(ArchiveFileFilter.JARZIP_FILTER_STRING);
393                 dialog.addFilter(new ArchiveFileFilter(usedJars, true, true));
394                 dialog.setInput(root);
395                 dialog.setComparator(new ResourceComparator(ResourceComparator.NAME));
396                 dialog.setInitialSelection(focus);
397
398                 if (dialog.open() == Window.OK) {
399                         Object[] elements= dialog.getResult();
400                         IPath[] res= new IPath[elements.length];
401                         for (int i= 0; i < res.length; i++) {
402                                 IResource elem= (IResource)elements[i];
403                                 res[i]= elem.getFullPath();
404                         }
405                         return res;
406                 }
407                 return null;
408         }
409
410         /**
411          * Shows the UI to configure an external JAR or ZIP archive.
412          * The dialog returns the configured or <code>null</code> if the dialog has
413          * been canceled. The dialog does not apply any changes.
414          *
415          * @param shell The parent shell for the dialog.
416          * @param initialEntry The path of the initial archive entry.
417          * @return Returns the configured external JAR path or <code>null</code> if the dialog has
418          * been canceled by the user.
419          */
420         public static IPath configureExternalJAREntry(Shell shell, IPath initialEntry) {
421                 if (initialEntry == null) {
422                         throw new IllegalArgumentException();
423                 }
424
425                 String lastUsedPath= initialEntry.removeLastSegments(1).toOSString();
426
427                 FileDialog dialog= new FileDialog(shell, SWT.SINGLE);
428                 dialog.setText(NewWizardMessages.BuildPathDialogAccess_ExtJARArchiveDialog_edit_title);
429                 dialog.setFilterExtensions(ArchiveFileFilter.JAR_ZIP_FILTER_EXTENSIONS);
430                 dialog.setFilterPath(lastUsedPath);
431                 dialog.setFileName(initialEntry.lastSegment());
432
433                 String res= dialog.open();
434                 if (res == null) {
435                         return null;
436                 }
437                 JavaPlugin.getDefault().getDialogSettings().put(IUIConstants.DIALOGSTORE_LASTEXTJAR, dialog.getFilterPath());
438
439                 return Path.fromOSString(res).makeAbsolute();
440         }
441
442         /**
443          * Shows the UI to select new external JAR or ZIP archive entries.
444          * The dialog returns the selected entry paths or <code>null</code> if the dialog has
445          * been canceled. The dialog does not apply any changes.
446          *
447          * @param shell The parent shell for the dialog.
448          * @return Returns the new external JAR paths or <code>null</code> if the dialog has
449          * been canceled by the user.
450          */
451         public static IPath[] chooseExternalJAREntries(Shell shell) {
452                 String lastUsedPath= JavaPlugin.getDefault().getDialogSettings().get(IUIConstants.DIALOGSTORE_LASTEXTJAR);
453                 if (lastUsedPath == null) {
454                         lastUsedPath= ""; //$NON-NLS-1$
455                 }
456                 FileDialog dialog= new FileDialog(shell, SWT.MULTI);
457                 dialog.setText(NewWizardMessages.BuildPathDialogAccess_ExtJARArchiveDialog_new_title);
458                 dialog.setFilterExtensions(ArchiveFileFilter.ALL_ARCHIVES_FILTER_EXTENSIONS);
459                 dialog.setFilterPath(lastUsedPath);
460
461                 String res= dialog.open();
462                 if (res == null) {
463                         return null;
464                 }
465                 String[] fileNames= dialog.getFileNames();
466                 int nChosen= fileNames.length;
467
468                 IPath filterPath= Path.fromOSString(dialog.getFilterPath());
469                 IPath[] elems= new IPath[nChosen];
470                 for (int i= 0; i < nChosen; i++) {
471                         elems[i]= filterPath.append(fileNames[i]).makeAbsolute();
472                 }
473                 JavaPlugin.getDefault().getDialogSettings().put(IUIConstants.DIALOGSTORE_LASTEXTJAR, dialog.getFilterPath());
474
475                 return elems;
476         }
477
478         /**
479          * Shows the UI to select new external class folder entries.
480          * The dialog returns the selected entry paths or <code>null</code> if the dialog has
481          * been canceled. The dialog does not apply any changes.
482          *
483          * @param shell The parent shell for the dialog.
484          * @return Returns the new external class folder path or <code>null</code> if the dialog has
485          * been canceled by the user.
486          *
487          * @since 3.4
488          */
489         public static IPath[] chooseExternalClassFolderEntries(Shell shell) {
490                 String lastUsedPath= JavaPlugin.getDefault().getDialogSettings().get(IUIConstants.DIALOGSTORE_LASTEXTJARFOLDER);
491                 if (lastUsedPath == null) {
492                         lastUsedPath= ""; //$NON-NLS-1$
493                 }
494                 DirectoryDialog dialog= new DirectoryDialog(shell, SWT.MULTI);
495                 dialog.setText(NewWizardMessages.BuildPathDialogAccess_ExtClassFolderDialog_new_title);
496                 dialog.setMessage(NewWizardMessages.BuildPathDialogAccess_ExtClassFolderDialog_new_description);
497                 dialog.setFilterPath(lastUsedPath);
498
499                 String res= dialog.open();
500                 if (res == null) {
501                         return null;
502                 }
503
504                 File file= new File(res);
505                 if (file.isDirectory())
506                         return new IPath[] { new Path(file.getAbsolutePath()) };
507
508                 return null;
509         }
510
511         /**
512          * Shows the UI to configure an external class folder.
513          * The dialog returns the configured or <code>null</code> if the dialog has
514          * been canceled. The dialog does not apply any changes.
515          *
516          * @param shell The parent shell for the dialog.
517          * @param initialEntry The path of the initial archive entry.
518          * @return Returns the configured external class folder path or <code>null</code> if the dialog has
519          * been canceled by the user.
520          *
521          * @since 3.4
522          */
523         public static IPath configureExternalClassFolderEntries(Shell shell, IPath initialEntry) {
524                 DirectoryDialog dialog= new DirectoryDialog(shell, SWT.SINGLE);
525                 dialog.setText(NewWizardMessages.BuildPathDialogAccess_ExtClassFolderDialog_edit_title);
526                 dialog.setMessage(NewWizardMessages.BuildPathDialogAccess_ExtClassFolderDialog_edit_description);
527                 dialog.setFilterPath(initialEntry.toString());
528
529                 String res= dialog.open();
530                 if (res == null) {
531                         return null;
532                 }
533
534                 File file= new File(res);
535                 if (file.isDirectory())
536                         return new Path(file.getAbsolutePath());
537
538                 return null;
539         }
540
541         /**
542          * Shows the UI to select new class folders.
543          * The dialog returns the selected class folder entry paths or <code>null</code> if the dialog has
544          * been canceled. The dialog does not apply any changes.
545          *
546          * @param shell The parent shell for the dialog.
547          * @param initialSelection The path of the element to initially select or <code>null</code>.
548          * @param usedEntries An array of paths that are already on the classpath and therefore should not be
549          * selected again.
550          * @return Returns the configured class folder paths or <code>null</code> if the dialog has
551          * been canceled by the user.
552          */
553         public static IPath[] chooseClassFolderEntries(Shell shell, IPath initialSelection, IPath[] usedEntries) {
554                 if (usedEntries == null) {
555                         throw new IllegalArgumentException();
556                 }
557                 String title= NewWizardMessages.BuildPathDialogAccess_ExistingClassFolderDialog_new_title;
558                 String message= NewWizardMessages.BuildPathDialogAccess_ExistingClassFolderDialog_new_description;
559                 return internalChooseFolderEntry(shell, initialSelection, usedEntries, title, message);
560         }
561
562         /**
563          * Shows the UI to select new source folders.
564          * The dialog returns the selected classpath entry paths or <code>null</code> if the dialog has
565          * been canceled. The dialog does not apply any changes.
566          *
567          * @param shell The parent shell for the dialog.
568          * @param initialSelection The path of the element to initially select or <code>null</code>
569          * @param usedEntries An array of paths that are already on the classpath and therefore should not be
570          * selected again.
571          * @return Returns the configured class folder entry paths or <code>null</code> if the dialog has
572          * been canceled by the user.
573          */
574         public static IPath[] chooseSourceFolderEntries(Shell shell, IPath initialSelection, IPath[] usedEntries) {
575                 if (usedEntries == null) {
576                         throw new IllegalArgumentException();
577                 }
578                 String title= NewWizardMessages.BuildPathDialogAccess_ExistingSourceFolderDialog_new_title;
579                 String message= NewWizardMessages.BuildPathDialogAccess_ExistingSourceFolderDialog_new_description;
580                 return internalChooseFolderEntry(shell, initialSelection, usedEntries, title, message);
581         }
582
583
584         private static IPath[] internalChooseFolderEntry(Shell shell, IPath initialSelection, IPath[] usedEntries, String title, String message) {
585                 Class<?>[] acceptedClasses= new Class[] { IProject.class, IFolder.class };
586
587                 ArrayList<IResource> usedContainers= new ArrayList<IResource>(usedEntries.length);
588                 IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot();
589                 for (int i= 0; i < usedEntries.length; i++) {
590                         IResource resource= root.findMember(usedEntries[i]);
591                         if (resource instanceof IContainer) {
592                                 usedContainers.add(resource);
593                         }
594                 }
595
596                 IResource focus= initialSelection != null ? root.findMember(initialSelection) : null;
597                 Object[] used= usedContainers.toArray();
598
599                 MultipleFolderSelectionDialog dialog= new MultipleFolderSelectionDialog(shell, new WorkbenchLabelProvider(), new WorkbenchContentProvider());
600                 dialog.setExisting(used);
601                 dialog.setTitle(title);
602                 dialog.setMessage(message);
603                 dialog.setHelpAvailable(false);
604                 dialog.addFilter(new TypedViewerFilter(acceptedClasses, used));
605                 dialog.setInput(root);
606                 dialog.setInitialFocus(focus);
607
608                 if (dialog.open() == Window.OK) {
609                         Object[] elements= dialog.getResult();
610                         IPath[] res= new IPath[elements.length];
611                         for (int i= 0; i < res.length; i++) {
612                                 IResource elem= (IResource) elements[i];
613                                 res[i]= elem.getFullPath();
614                         }
615                         return res;
616                 }
617                 return null;
618         }
619 }