Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: b252c58488bc61e38d82a329472e9fb3e4071e69 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
/*******************************************************************************
 * Copyright (c) 2000, 2012 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.ui.wizards;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;

import org.eclipse.jface.window.Window;

import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import org.eclipse.ui.views.navigator.ResourceComparator;

import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;

import org.eclipse.jdt.ui.JavaUI;

import org.eclipse.jdt.internal.ui.IUIConstants;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels;
import org.eclipse.jdt.internal.ui.viewsupport.FilteredElementTreeSelectionDialog;
import org.eclipse.jdt.internal.ui.wizards.NewWizardMessages;
import org.eclipse.jdt.internal.ui.wizards.TypedElementSelectionValidator;
import org.eclipse.jdt.internal.ui.wizards.TypedViewerFilter;
import org.eclipse.jdt.internal.ui.wizards.buildpaths.ArchiveFileFilter;
import org.eclipse.jdt.internal.ui.wizards.buildpaths.CPListElement;
import org.eclipse.jdt.internal.ui.wizards.buildpaths.ClasspathContainerWizard;
import org.eclipse.jdt.internal.ui.wizards.buildpaths.EditVariableEntryDialog;
import org.eclipse.jdt.internal.ui.wizards.buildpaths.IndexLocationDialog;
import org.eclipse.jdt.internal.ui.wizards.buildpaths.JavadocLocationDialog;
import org.eclipse.jdt.internal.ui.wizards.buildpaths.MultipleFolderSelectionDialog;
import org.eclipse.jdt.internal.ui.wizards.buildpaths.NewVariableEntryDialog;
import org.eclipse.jdt.internal.ui.wizards.buildpaths.SourceAttachmentDialog;

/**
 * Class that gives access to dialogs used by the Java build path page to configure classpath entries
 * and properties of classpath entries.
 * Static methods are provided to show dialogs for:
 * <ul>
 *  <li> configuration of source attachments</li>
 *  <li> configuration of Javadoc locations</li>
 *  <li> configuration and selection of classpath variable entries</li>
 *  <li> configuration and selection of classpath container entries</li>
 *  <li> configuration and selection of JAR and external JAR entries</li>
 *  <li> selection of class and source folders</li>
 * </ul>
 * <p>
 * This class is not intended to be instantiated or subclassed by clients.
 * </p>
 * @since 3.0
 *
 * @noinstantiate This class is not intended to be instantiated by clients.
 */
public final class BuildPathDialogAccess {

	private BuildPathDialogAccess() {
		// do not instantiate
	}

	/**
	 * Shows the UI for configuring source attachments. <code>null</code> is returned
	 * if the user cancels the dialog. The dialog does not apply any changes.
	 *
	 * @param shell The parent shell for the dialog
	 * @param initialEntry The entry to edit. The kind of the classpath entry must be either
	 * <code>IClasspathEntry.CPE_LIBRARY</code> or <code>IClasspathEntry.CPE_VARIABLE</code>.
	 * @return Returns the resulting classpath entry containing a potentially modified source attachment path and
	 * source attachment root. The resulting entry can be used to replace the original entry on the classpath.
	 * Note that the dialog does not make any changes on the passed entry nor on the classpath that
	 * contains it.
	 */
	public static IClasspathEntry configureSourceAttachment(Shell shell, IClasspathEntry initialEntry) {
		if (initialEntry == null) {
			throw new IllegalArgumentException();
		}
		int entryKind= initialEntry.getEntryKind();
		if (entryKind != IClasspathEntry.CPE_LIBRARY && entryKind != IClasspathEntry.CPE_VARIABLE) {
			throw new IllegalArgumentException();
		}

		SourceAttachmentDialog dialog=  new SourceAttachmentDialog(shell, initialEntry);
		if (dialog.open() == Window.OK) {
			return dialog.getResult();
		}
		return null;
	}

	/**
	 * Shows the UI for configuring a javadoc location. <code>null</code> is returned
	 * if the user cancels the dialog. If OK is pressed, an array of length 1 containing the configured URL is
	 * returned. Note that the configured URL can be <code>null</code> when the user
	 * wishes to have no URL location specified. The dialog does not apply any changes.
	 * Use {@link org.eclipse.jdt.ui.JavaUI} to access and configure
	 * Javadoc locations.
	 *
	 * @param shell The parent shell for the dialog.
	 * @param libraryName Name of of the library to which configured javadoc location belongs.
	 * @param initialURL The initial URL or <code>null</code>.
	 * @return Returns an array of size 1 that contains the resulting javadoc location or
	 * <code>null</code> if the dialog has been canceled. Note that the configured URL can be <code>null</code> when the user
	 * wishes to have no URL location specified.
	 */
	public static URL[] configureJavadocLocation(Shell shell, String libraryName, URL initialURL) {
		if (libraryName == null) {
			throw new IllegalArgumentException();
		}

		JavadocLocationDialog dialog=  new JavadocLocationDialog(shell, libraryName, initialURL);
		if (dialog.open() == Window.OK) {
			return new URL[] { dialog.getResult() };
		}
		return null;
	}

	/**
	 * Shows the UI for configuring a index location. <code>null</code> is returned if the user
	 * cancels the dialog. If OK is pressed, an array of length 1 containing the configured URL is
	 * returned. Note that the configured URL can be <code>null</code> when the user wishes to have
	 * no URL location specified. The dialog does not apply any changes. Use
	 * {@link org.eclipse.jdt.ui.JavaUI} to access and configure index locations.
	 * 
	 * @param shell The parent shell for the dialog.
	 * @param libraryName Name of of the library to which configured index location belongs.
	 * @param initialURL The initial URL or <code>null</code>.
	 * @return Returns an array of size 1 that contains the resulting index location or
	 *         <code>null</code> if the dialog has been canceled. Note that the configured URL can
	 *         be <code>null</code> when the user wishes to have no URL location specified.
	 */
	public static URL[] configureIndexLocation(Shell shell, String libraryName, URL initialURL) {
		if (libraryName == null) {
			throw new IllegalArgumentException();
		}

		IndexLocationDialog dialog= new IndexLocationDialog(shell, libraryName, initialURL);
		if (dialog.open() == Window.OK) {
			return new URL[] { dialog.getResult() };
		}
		return null;
	}

	/**
	 * Shows the UI for configuring a javadoc location attribute of the classpath entry. <code>null</code> is returned
	 * if the user cancels the dialog. The dialog does not apply any changes.
	 *
	 * @param shell The parent shell for the dialog.
	 * @param initialEntry The entry to edit. The kind of the classpath entry must be either
	 * <code>IClasspathEntry.CPE_LIBRARY</code> or <code>IClasspathEntry.CPE_VARIABLE</code>.
	 * @return Returns the resulting classpath entry containing a potentially modified javadoc location attribute
	 * The resulting entry can be used to replace the original entry on the classpath.
	 * Note that the dialog does not make any changes on the passed entry nor on the classpath that
	 * contains it.
	 *
	 * @since 3.1
	 */
	public static IClasspathEntry configureJavadocLocation(Shell shell, IClasspathEntry initialEntry) {
		if (initialEntry == null) {
			throw new IllegalArgumentException();
		}
		int entryKind= initialEntry.getEntryKind();
		if (entryKind != IClasspathEntry.CPE_LIBRARY && entryKind != IClasspathEntry.CPE_VARIABLE) {
			throw new IllegalArgumentException();
		}

		URL location= JavaUI.getLibraryJavadocLocation(initialEntry);
		JavadocLocationDialog dialog=  new JavadocLocationDialog(shell, BasicElementLabels.getPathLabel(initialEntry.getPath(), false), location);
		if (dialog.open() == Window.OK) {
			CPListElement element= CPListElement.createFromExisting(initialEntry, null);
			URL res= dialog.getResult();
			element.setAttribute(CPListElement.JAVADOC, res != null ? res.toExternalForm() : null);
			return element.getClasspathEntry();
		}
		return null;
	}

	/**
	 * Shows the UI for configuring a variable classpath entry. See {@link IClasspathEntry#CPE_VARIABLE} for
	 * details about variable classpath entries.
	 * The dialog returns the configured classpath entry path or <code>null</code> if the dialog has
	 * been canceled. The dialog does not apply any changes.
	 *
	 * @param shell The parent shell for the dialog.
	 * @param initialEntryPath The initial variable classpath variable path or <code>null</code> to use
	 * an empty path.
	 * @param existingPaths An array of paths that are already on the classpath and therefore should not be
	 * selected again.
	 * @return Returns the configures classpath entry path or <code>null</code> if the dialog has
	 * been canceled.
	 */
	public static IPath configureVariableEntry(Shell shell, IPath initialEntryPath, IPath[] existingPaths) {
		if (existingPaths == null) {
			throw new IllegalArgumentException();
		}

		EditVariableEntryDialog dialog= new EditVariableEntryDialog(shell, initialEntryPath, existingPaths);
		if (dialog.open() == Window.OK) {
			return dialog.getPath();
		}
		return null;
	}

	/**
	 * Shows the UI for selecting new variable classpath entries. See {@link IClasspathEntry#CPE_VARIABLE} for
	 * details about variable classpath entries.
	 * The dialog returns an array of the selected variable entries or <code>null</code> if the dialog has
	 * been canceled. The dialog does not apply any changes.
	 *
	 * @param shell The parent shell for the dialog.
	 * @param existingPaths An array of paths that are already on the classpath and therefore should not be
	 * selected again.
	 * @return Returns an non empty array of the selected variable entries or <code>null</code> if the dialog has
	 * been canceled.
	 */
	public static IPath[] chooseVariableEntries(Shell shell, IPath[] existingPaths) {
		if (existingPaths == null) {
			throw new IllegalArgumentException();
		}
		NewVariableEntryDialog dialog= new NewVariableEntryDialog(shell);
		if (dialog.open() == Window.OK) {
			return dialog.getResult();
		}
		return null;
	}

	/**
	 * Shows the UI to configure a classpath container classpath entry. See {@link IClasspathEntry#CPE_CONTAINER} for
	 * details about container classpath entries.
	 * The dialog returns the configured classpath entry or <code>null</code> if the dialog has
	 * been canceled. The dialog does not apply any changes.
	 *
	 * @param shell The parent shell for the dialog.
	 * @param initialEntry The initial classpath container entry.
	 * @param project The project the entry belongs to. The project does not have to exist and can also be <code>null</code>.
	 * @param currentClasspath The class path entries currently selected to be set as the projects classpath. This can also
	 * 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
	 * the classpath container dialog has been closed. See {@link IClasspathContainerPageExtension} for
	 * more information.
	 * @return Returns the configured classpath container entry or <code>null</code> if the dialog has
	 * been canceled by the user.
	 */
	public static IClasspathEntry configureContainerEntry(Shell shell, IClasspathEntry initialEntry, IJavaProject project, IClasspathEntry[] currentClasspath) {
		if (initialEntry == null || currentClasspath == null) {
			throw new IllegalArgumentException();
		}

		ClasspathContainerWizard wizard= new ClasspathContainerWizard(initialEntry, project, currentClasspath);
		if (ClasspathContainerWizard.openWizard(shell, wizard) == Window.OK) {
			IClasspathEntry[] created= wizard.getNewEntries();
			if (created != null && created.length == 1) {
				return created[0];
			}
		}
		return null;
	}

	/**
	 * Shows the UI to choose new classpath container classpath entries. See {@link IClasspathEntry#CPE_CONTAINER} for
	 * details about container classpath entries.
	 * The dialog returns the selected classpath entries or <code>null</code> if the dialog has
	 * been canceled. The dialog does not apply any changes.
	 *
	 * @param shell The parent shell for the dialog.
	 * @param project The project the entry belongs to. The project does not have to exist and
	 * can also be <code>null</code>.
	 * @param currentClasspath The class path entries currently selected to be set as the projects classpath. This can also
	 * include the entry to be edited. The dialog uses these entries as information only; The user still can make changes after the
	 * the classpath container dialog has been closed. See {@link IClasspathContainerPageExtension} for
	 * more information.
	 * @return Returns the selected classpath container entries or <code>null</code> if the dialog has
	 * been canceled by the user.
	 */
	public static IClasspathEntry[] chooseContainerEntries(Shell shell, IJavaProject project, IClasspathEntry[] currentClasspath) {
		if (currentClasspath == null) {
			throw new IllegalArgumentException();
		}

		ClasspathContainerWizard wizard= new ClasspathContainerWizard((IClasspathEntry) null, project, currentClasspath);
		if (ClasspathContainerWizard.openWizard(shell, wizard) == Window.OK) {
			return wizard.getNewEntries();
		}
		return null;
	}


	/**
	 * Shows the UI to configure a JAR or ZIP archive located in the workspace.
	 * The dialog returns the configured classpath entry path or <code>null</code> if the dialog has
	 * been canceled. The dialog does not apply any changes.
	 *
	 * @param shell The parent shell for the dialog.
	 * @param initialEntry The path of the initial archive entry
	 * @param usedEntries An array of paths that are already on the classpath and therefore should not be
	 * selected again.
	 * @return Returns the configured JAR path or <code>null</code> if the dialog has
	 * been canceled by the user.
	 */
	public static IPath configureJAREntry(Shell shell, IPath initialEntry, IPath[] usedEntries) {
		if (initialEntry == null || usedEntries == null) {
			throw new IllegalArgumentException();
		}

		Class<?>[] acceptedClasses= new Class[] { IFile.class };
		TypedElementSelectionValidator validator= new TypedElementSelectionValidator(acceptedClasses, false);

		ArrayList<IResource> usedJars= new ArrayList<IResource>(usedEntries.length);
		IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot();
		for (int i= 0; i < usedEntries.length; i++) {
			IPath curr= usedEntries[i];
			if (!curr.equals(initialEntry)) {
				IResource resource= root.findMember(usedEntries[i]);
				if (resource instanceof IFile) {
					usedJars.add(resource);
				}
			}
		}

		IResource existing= root.findMember(initialEntry);

		FilteredElementTreeSelectionDialog dialog= new FilteredElementTreeSelectionDialog(shell, new WorkbenchLabelProvider(), new WorkbenchContentProvider());
		dialog.setValidator(validator);
		dialog.setTitle(NewWizardMessages.BuildPathDialogAccess_JARArchiveDialog_edit_title);
		dialog.setMessage(NewWizardMessages.BuildPathDialogAccess_JARArchiveDialog_edit_description);
		dialog.setInitialFilter(ArchiveFileFilter.JARZIP_FILTER_STRING);
		dialog.addFilter(new ArchiveFileFilter(usedJars, true, true));
		dialog.setInput(root);
		dialog.setComparator(new ResourceComparator(ResourceComparator.NAME));
		dialog.setInitialSelection(existing);

		if (dialog.open() == Window.OK) {
			IResource element= (IResource) dialog.getFirstResult();
			return element.getFullPath();
		}
		return null;
	}

	/**
	 * Shows the UI to select new JAR or ZIP archive entries located in the workspace.
	 * The dialog returns the selected entries or <code>null</code> if the dialog has
	 * been canceled. The dialog does not apply any changes.
	 *
	 * @param shell The parent shell for the dialog.
	 * @param initialSelection The path of the element (container or archive) to initially select or <code>null</code> to not select an entry.
	 * @param usedEntries An array of paths that are already on the classpath and therefore should not be
	 * selected again.
	 * @return Returns the new JAR paths or <code>null</code> if the dialog has
	 * been canceled by the user.
	 */
	public static IPath[] chooseJAREntries(Shell shell, IPath initialSelection, IPath[] usedEntries) {
		if (usedEntries == null) {
			throw new IllegalArgumentException();
		}

		Class<?>[] acceptedClasses= new Class[] { IFile.class };
		TypedElementSelectionValidator validator= new TypedElementSelectionValidator(acceptedClasses, true);
		ArrayList<IResource> usedJars= new ArrayList<IResource>(usedEntries.length);
		IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot();
		for (int i= 0; i < usedEntries.length; i++) {
			IResource resource= root.findMember(usedEntries[i]);
			if (resource instanceof IFile) {
				usedJars.add(resource);
			}
		}
		IResource focus= initialSelection != null ? root.findMember(initialSelection) : null;

		FilteredElementTreeSelectionDialog dialog= new FilteredElementTreeSelectionDialog(shell, new WorkbenchLabelProvider(), new WorkbenchContentProvider());
		dialog.setHelpAvailable(false);
		dialog.setValidator(validator);
		dialog.setTitle(NewWizardMessages.BuildPathDialogAccess_JARArchiveDialog_new_title);
		dialog.setMessage(NewWizardMessages.BuildPathDialogAccess_JARArchiveDialog_new_description);
		dialog.setInitialFilter(ArchiveFileFilter.JARZIP_FILTER_STRING);
		dialog.addFilter(new ArchiveFileFilter(usedJars, true, true));
		dialog.setInput(root);
		dialog.setComparator(new ResourceComparator(ResourceComparator.NAME));
		dialog.setInitialSelection(focus);

		if (dialog.open() == Window.OK) {
			Object[] elements= dialog.getResult();
			IPath[] res= new IPath[elements.length];
			for (int i= 0; i < res.length; i++) {
				IResource elem= (IResource)elements[i];
				res[i]= elem.getFullPath();
			}
			return res;
		}
		return null;
	}

	/**
	 * Shows the UI to configure an external JAR or ZIP archive.
	 * The dialog returns the configured or <code>null</code> if the dialog has
	 * been canceled. The dialog does not apply any changes.
	 *
	 * @param shell The parent shell for the dialog.
	 * @param initialEntry The path of the initial archive entry.
	 * @return Returns the configured external JAR path or <code>null</code> if the dialog has
	 * been canceled by the user.
	 */
	public static IPath configureExternalJAREntry(Shell shell, IPath initialEntry) {
		if (initialEntry == null) {
			throw new IllegalArgumentException();
		}

		String lastUsedPath= initialEntry.removeLastSegments(1).toOSString();

		FileDialog dialog= new FileDialog(shell, SWT.SINGLE);
		dialog.setText(NewWizardMessages.BuildPathDialogAccess_ExtJARArchiveDialog_edit_title);
		dialog.setFilterExtensions(ArchiveFileFilter.JAR_ZIP_FILTER_EXTENSIONS);
		dialog.setFilterPath(lastUsedPath);
		dialog.setFileName(initialEntry.lastSegment());

		String res= dialog.open();
		if (res == null) {
			return null;
		}
		JavaPlugin.getDefault().getDialogSettings().put(IUIConstants.DIALOGSTORE_LASTEXTJAR, dialog.getFilterPath());

		return Path.fromOSString(res).makeAbsolute();
	}

	/**
	 * Shows the UI to select new external JAR or ZIP archive entries.
	 * The dialog returns the selected entry paths or <code>null</code> if the dialog has
	 * been canceled. The dialog does not apply any changes.
	 *
	 * @param shell The parent shell for the dialog.
	 * @return Returns the new external JAR paths or <code>null</code> if the dialog has
	 * been canceled by the user.
	 */
	public static IPath[] chooseExternalJAREntries(Shell shell) {
		String lastUsedPath= JavaPlugin.getDefault().getDialogSettings().get(IUIConstants.DIALOGSTORE_LASTEXTJAR);
		if (lastUsedPath == null) {
			lastUsedPath= ""; //$NON-NLS-1$
		}
		FileDialog dialog= new FileDialog(shell, SWT.MULTI);
		dialog.setText(NewWizardMessages.BuildPathDialogAccess_ExtJARArchiveDialog_new_title);
		dialog.setFilterExtensions(ArchiveFileFilter.ALL_ARCHIVES_FILTER_EXTENSIONS);
		dialog.setFilterPath(lastUsedPath);

		String res= dialog.open();
		if (res == null) {
			return null;
		}
		String[] fileNames= dialog.getFileNames();
		int nChosen= fileNames.length;

		IPath filterPath= Path.fromOSString(dialog.getFilterPath());
		IPath[] elems= new IPath[nChosen];
		for (int i= 0; i < nChosen; i++) {
			elems[i]= filterPath.append(fileNames[i]).makeAbsolute();
		}
		JavaPlugin.getDefault().getDialogSettings().put(IUIConstants.DIALOGSTORE_LASTEXTJAR, dialog.getFilterPath());

		return elems;
	}

	/**
	 * Shows the UI to select new external class folder entries.
	 * The dialog returns the selected entry paths or <code>null</code> if the dialog has
	 * been canceled. The dialog does not apply any changes.
	 *
	 * @param shell The parent shell for the dialog.
	 * @return Returns the new external class folder path or <code>null</code> if the dialog has
	 * been canceled by the user.
	 *
	 * @since 3.4
	 */
	public static IPath[] chooseExternalClassFolderEntries(Shell shell) {
		String lastUsedPath= JavaPlugin.getDefault().getDialogSettings().get(IUIConstants.DIALOGSTORE_LASTEXTJARFOLDER);
		if (lastUsedPath == null) {
			lastUsedPath= ""; //$NON-NLS-1$
		}
		DirectoryDialog dialog= new DirectoryDialog(shell, SWT.MULTI);
		dialog.setText(NewWizardMessages.BuildPathDialogAccess_ExtClassFolderDialog_new_title);
		dialog.setMessage(NewWizardMessages.BuildPathDialogAccess_ExtClassFolderDialog_new_description);
		dialog.setFilterPath(lastUsedPath);

		String res= dialog.open();
		if (res == null) {
			return null;
		}

		File file= new File(res);
		if (file.isDirectory())
			return new IPath[] { new Path(file.getAbsolutePath()) };

		return null;
	}

	/**
	 * Shows the UI to configure an external class folder.
	 * The dialog returns the configured or <code>null</code> if the dialog has
	 * been canceled. The dialog does not apply any changes.
	 *
	 * @param shell The parent shell for the dialog.
	 * @param initialEntry The path of the initial archive entry.
	 * @return Returns the configured external class folder path or <code>null</code> if the dialog has
	 * been canceled by the user.
	 *
	 * @since 3.4
	 */
	public static IPath configureExternalClassFolderEntries(Shell shell, IPath initialEntry) {
		DirectoryDialog dialog= new DirectoryDialog(shell, SWT.SINGLE);
		dialog.setText(NewWizardMessages.BuildPathDialogAccess_ExtClassFolderDialog_edit_title);
		dialog.setMessage(NewWizardMessages.BuildPathDialogAccess_ExtClassFolderDialog_edit_description);
		dialog.setFilterPath(initialEntry.toString());

		String res= dialog.open();
		if (res == null) {
			return null;
		}

		File file= new File(res);
		if (file.isDirectory())
			return new Path(file.getAbsolutePath());

		return null;
	}

	/**
	 * Shows the UI to select new class folders.
	 * The dialog returns the selected class folder entry paths or <code>null</code> if the dialog has
	 * been canceled. The dialog does not apply any changes.
	 *
	 * @param shell The parent shell for the dialog.
	 * @param initialSelection The path of the element to initially select or <code>null</code>.
	 * @param usedEntries An array of paths that are already on the classpath and therefore should not be
	 * selected again.
	 * @return Returns the configured class folder paths or <code>null</code> if the dialog has
	 * been canceled by the user.
	 */
	public static IPath[] chooseClassFolderEntries(Shell shell, IPath initialSelection, IPath[] usedEntries) {
		if (usedEntries == null) {
			throw new IllegalArgumentException();
		}
		String title= NewWizardMessages.BuildPathDialogAccess_ExistingClassFolderDialog_new_title;
		String message= NewWizardMessages.BuildPathDialogAccess_ExistingClassFolderDialog_new_description;
		return internalChooseFolderEntry(shell, initialSelection, usedEntries, title, message);
	}

	/**
	 * Shows the UI to select new source folders.
	 * The dialog returns the selected classpath entry paths or <code>null</code> if the dialog has
	 * been canceled. The dialog does not apply any changes.
	 *
	 * @param shell The parent shell for the dialog.
	 * @param initialSelection The path of the element to initially select or <code>null</code>
	 * @param usedEntries An array of paths that are already on the classpath and therefore should not be
	 * selected again.
	 * @return Returns the configured class folder entry paths or <code>null</code> if the dialog has
	 * been canceled by the user.
	 */
	public static IPath[] chooseSourceFolderEntries(Shell shell, IPath initialSelection, IPath[] usedEntries) {
		if (usedEntries == null) {
			throw new IllegalArgumentException();
		}
		String title= NewWizardMessages.BuildPathDialogAccess_ExistingSourceFolderDialog_new_title;
		String message= NewWizardMessages.BuildPathDialogAccess_ExistingSourceFolderDialog_new_description;
		return internalChooseFolderEntry(shell, initialSelection, usedEntries, title, message);
	}


	private static IPath[] internalChooseFolderEntry(Shell shell, IPath initialSelection, IPath[] usedEntries, String title, String message) {
		Class<?>[] acceptedClasses= new Class[] { IProject.class, IFolder.class };

		ArrayList<IResource> usedContainers= new ArrayList<IResource>(usedEntries.length);
		IWorkspaceRoot root= ResourcesPlugin.getWorkspace().getRoot();
		for (int i= 0; i < usedEntries.length; i++) {
			IResource resource= root.findMember(usedEntries[i]);
			if (resource instanceof IContainer) {
				usedContainers.add(resource);
			}
		}

		IResource focus= initialSelection != null ? root.findMember(initialSelection) : null;
		Object[] used= usedContainers.toArray();

		MultipleFolderSelectionDialog dialog= new MultipleFolderSelectionDialog(shell, new WorkbenchLabelProvider(), new WorkbenchContentProvider());
		dialog.setExisting(used);
		dialog.setTitle(title);
		dialog.setMessage(message);
		dialog.setHelpAvailable(false);
		dialog.addFilter(new TypedViewerFilter(acceptedClasses, used));
		dialog.setInput(root);
		dialog.setInitialFocus(focus);

		if (dialog.open() == Window.OK) {
			Object[] elements= dialog.getResult();
			IPath[] res= new IPath[elements.length];
			for (int i= 0; i < res.length; i++) {
				IResource elem= (IResource) elements[i];
				res[i]= elem.getFullPath();
			}
			return res;
		}
		return null;
	}
}

Back to the top