|
Lines 14-39
Link Here
|
| 14 |
import java.lang.reflect.InvocationTargetException; |
14 |
import java.lang.reflect.InvocationTargetException; |
| 15 |
import java.net.MalformedURLException; |
15 |
import java.net.MalformedURLException; |
| 16 |
import java.net.URL; |
16 |
import java.net.URL; |
| 17 |
import java.util.*; |
17 |
import java.util.ArrayList; |
|
|
18 |
import java.util.Collections; |
| 19 |
import java.util.Comparator; |
| 20 |
import java.util.HashMap; |
| 21 |
import java.util.HashSet; |
| 22 |
import java.util.Iterator; |
| 18 |
import java.util.List; |
23 |
import java.util.List; |
| 19 |
import org.eclipse.core.runtime.*; |
24 |
import java.util.Map; |
|
|
25 |
import java.util.Map.Entry; |
| 26 |
import java.util.Set; |
| 27 |
import org.eclipse.core.runtime.CoreException; |
| 28 |
import org.eclipse.core.runtime.IConfigurationElement; |
| 29 |
import org.eclipse.core.runtime.IExtensionPoint; |
| 30 |
import org.eclipse.core.runtime.IPath; |
| 31 |
import org.eclipse.core.runtime.IProgressMonitor; |
| 32 |
import org.eclipse.core.runtime.Path; |
| 33 |
import org.eclipse.core.runtime.Platform; |
| 34 |
import org.eclipse.core.runtime.SubProgressMonitor; |
| 20 |
import org.eclipse.jface.dialogs.Dialog; |
35 |
import org.eclipse.jface.dialogs.Dialog; |
| 21 |
import org.eclipse.jface.dialogs.IDialogSettings; |
36 |
import org.eclipse.jface.dialogs.IDialogSettings; |
| 22 |
import org.eclipse.jface.operation.IRunnableWithProgress; |
37 |
import org.eclipse.jface.operation.IRunnableWithProgress; |
| 23 |
import org.eclipse.jface.preference.*; |
38 |
import org.eclipse.jface.preference.IPreferenceNode; |
|
|
39 |
import org.eclipse.jface.preference.PreferenceDialog; |
| 40 |
import org.eclipse.jface.preference.PreferenceManager; |
| 24 |
import org.eclipse.jface.window.Window; |
41 |
import org.eclipse.jface.window.Window; |
|
|
42 |
import org.eclipse.jface.wizard.IWizardPage; |
| 43 |
import org.eclipse.jface.wizard.Wizard; |
| 25 |
import org.eclipse.jface.wizard.WizardPage; |
44 |
import org.eclipse.jface.wizard.WizardPage; |
| 26 |
import org.eclipse.pde.core.plugin.*; |
45 |
import org.eclipse.pde.core.importing.BundleImportDescription; |
| 27 |
import org.eclipse.pde.internal.core.*; |
46 |
import org.eclipse.pde.core.importing.IBundleImporter; |
| 28 |
import org.eclipse.pde.internal.core.target.provisional.*; |
47 |
import org.eclipse.pde.core.plugin.IPluginBase; |
| 29 |
import org.eclipse.pde.internal.ui.*; |
48 |
import org.eclipse.pde.core.plugin.IPluginModelBase; |
|
|
49 |
import org.eclipse.pde.core.plugin.PluginRegistry; |
| 50 |
import org.eclipse.pde.core.plugin.TargetPlatform; |
| 51 |
import org.eclipse.pde.internal.core.ICoreConstants; |
| 52 |
import org.eclipse.pde.internal.core.PDECore; |
| 53 |
import org.eclipse.pde.internal.core.PDEPreferencesManager; |
| 54 |
import org.eclipse.pde.internal.core.PDEState; |
| 55 |
import org.eclipse.pde.internal.core.SourceLocationKey; |
| 56 |
import org.eclipse.pde.internal.core.SourceLocationManager; |
| 57 |
import org.eclipse.pde.internal.core.project.BundleProjectService; |
| 58 |
import org.eclipse.pde.internal.core.target.provisional.IBundleContainer; |
| 59 |
import org.eclipse.pde.internal.core.target.provisional.IResolvedBundle; |
| 60 |
import org.eclipse.pde.internal.core.target.provisional.ITargetDefinition; |
| 61 |
import org.eclipse.pde.internal.core.target.provisional.ITargetHandle; |
| 62 |
import org.eclipse.pde.internal.core.target.provisional.ITargetPlatformService; |
| 63 |
import org.eclipse.pde.internal.ui.IHelpContextIds; |
| 64 |
import org.eclipse.pde.internal.ui.IPDEUIConstants; |
| 65 |
import org.eclipse.pde.internal.ui.PDEPlugin; |
| 66 |
import org.eclipse.pde.internal.ui.PDEUIMessages; |
| 67 |
import org.eclipse.pde.internal.ui.SWTFactory; |
| 30 |
import org.eclipse.pde.internal.ui.preferences.TargetPlatformPreferenceNode; |
68 |
import org.eclipse.pde.internal.ui.preferences.TargetPlatformPreferenceNode; |
|
|
69 |
import org.eclipse.pde.ui.IBundeImportWizardPage; |
| 31 |
import org.eclipse.swt.SWT; |
70 |
import org.eclipse.swt.SWT; |
| 32 |
import org.eclipse.swt.custom.BusyIndicator; |
71 |
import org.eclipse.swt.custom.BusyIndicator; |
| 33 |
import org.eclipse.swt.events.*; |
72 |
import org.eclipse.swt.events.ModifyEvent; |
|
|
73 |
import org.eclipse.swt.events.ModifyListener; |
| 74 |
import org.eclipse.swt.events.SelectionAdapter; |
| 75 |
import org.eclipse.swt.events.SelectionEvent; |
| 34 |
import org.eclipse.swt.layout.GridData; |
76 |
import org.eclipse.swt.layout.GridData; |
| 35 |
import org.eclipse.swt.layout.GridLayout; |
77 |
import org.eclipse.swt.layout.GridLayout; |
| 36 |
import org.eclipse.swt.widgets.*; |
78 |
import org.eclipse.swt.widgets.Button; |
|
|
79 |
import org.eclipse.swt.widgets.Combo; |
| 80 |
import org.eclipse.swt.widgets.Composite; |
| 81 |
import org.eclipse.swt.widgets.DirectoryDialog; |
| 82 |
import org.eclipse.swt.widgets.Group; |
| 83 |
import org.eclipse.swt.widgets.Shell; |
| 37 |
import org.eclipse.ui.PlatformUI; |
84 |
import org.eclipse.ui.PlatformUI; |
| 38 |
import org.osgi.framework.Version; |
85 |
import org.osgi.framework.Version; |
| 39 |
|
86 |
|
|
Lines 65-70
Link Here
|
| 65 |
private Button binaryButton; |
112 |
private Button binaryButton; |
| 66 |
private Button binaryWithLinksButton; |
113 |
private Button binaryWithLinksButton; |
| 67 |
private Button sourceButton; |
114 |
private Button sourceButton; |
|
|
115 |
private Button repositoryButton; |
| 68 |
|
116 |
|
| 69 |
public static String TARGET_PLATFORM = "targetPlatform"; //$NON-NLS-1$ |
117 |
public static String TARGET_PLATFORM = "targetPlatform"; //$NON-NLS-1$ |
| 70 |
private IPluginModelBase[] models = new IPluginModelBase[0]; |
118 |
private IPluginModelBase[] models = new IPluginModelBase[0]; |
|
Lines 75-80
Link Here
|
| 75 |
private PDEState state; |
123 |
private PDEState state; |
| 76 |
private boolean canceled = false; |
124 |
private boolean canceled = false; |
| 77 |
|
125 |
|
|
|
126 |
/** |
| 127 |
* Models that can be imported from a repository |
| 128 |
*/ |
| 129 |
protected Set repositoryModels = null; |
| 130 |
|
| 131 |
/** |
| 132 |
* Maps bundle importers to import instructions |
| 133 |
*/ |
| 134 |
private Map importerToInstructions = null; |
| 135 |
|
| 136 |
/** |
| 137 |
* Map of bundle importer extension id to associated wizard page |
| 138 |
*/ |
| 139 |
private Map importIdToWizardPage = new HashMap(); |
| 140 |
|
| 141 |
/** |
| 142 |
* Array of next wizard pages (in order) |
| 143 |
*/ |
| 144 |
private List nextPages = new ArrayList(); |
| 145 |
|
| 78 |
public PluginImportWizardFirstPage(String name) { |
146 |
public PluginImportWizardFirstPage(String name) { |
| 79 |
super(name); |
147 |
super(name); |
| 80 |
setTitle(PDEUIMessages.ImportWizard_FirstPage_title); |
148 |
setTitle(PDEUIMessages.ImportWizard_FirstPage_title); |
|
Lines 120-125
Link Here
|
| 120 |
binaryButton = SWTFactory.createRadioButton(options, PDEUIMessages.ImportWizard_FirstPage_binary); |
188 |
binaryButton = SWTFactory.createRadioButton(options, PDEUIMessages.ImportWizard_FirstPage_binary); |
| 121 |
binaryWithLinksButton = SWTFactory.createRadioButton(options, PDEUIMessages.ImportWizard_FirstPage_binaryLinks); |
189 |
binaryWithLinksButton = SWTFactory.createRadioButton(options, PDEUIMessages.ImportWizard_FirstPage_binaryLinks); |
| 122 |
sourceButton = SWTFactory.createRadioButton(options, PDEUIMessages.ImportWizard_FirstPage_source); |
190 |
sourceButton = SWTFactory.createRadioButton(options, PDEUIMessages.ImportWizard_FirstPage_source); |
|
|
191 |
repositoryButton = SWTFactory.createRadioButton(options, "Projects from a &repository"); |
| 123 |
} |
192 |
} |
| 124 |
|
193 |
|
| 125 |
/** |
194 |
/** |
|
Lines 156-163
Link Here
|
| 156 |
binaryButton.setSelection(true); |
225 |
binaryButton.setSelection(true); |
| 157 |
} else if (importType == PluginImportOperation.IMPORT_BINARY_WITH_LINKS) { |
226 |
} else if (importType == PluginImportOperation.IMPORT_BINARY_WITH_LINKS) { |
| 158 |
binaryWithLinksButton.setSelection(true); |
227 |
binaryWithLinksButton.setSelection(true); |
| 159 |
} else { |
228 |
} else if (importType == PluginImportOperation.IMPORT_WITH_SOURCE) { |
| 160 |
sourceButton.setSelection(true); |
229 |
sourceButton.setSelection(true); |
|
|
230 |
} else { |
| 231 |
repositoryButton.setSelection(true); |
| 161 |
} |
232 |
} |
| 162 |
|
233 |
|
| 163 |
boolean scan = true; |
234 |
boolean scan = true; |
|
Lines 384-390
Link Here
|
| 384 |
if (binaryWithLinksButton.getSelection()) { |
455 |
if (binaryWithLinksButton.getSelection()) { |
| 385 |
return PluginImportOperation.IMPORT_BINARY_WITH_LINKS; |
456 |
return PluginImportOperation.IMPORT_BINARY_WITH_LINKS; |
| 386 |
} |
457 |
} |
| 387 |
|
458 |
if (repositoryButton.getSelection()) { |
|
|
459 |
return PluginImportOperation.IMPORT_FROM_REPOSITORY; |
| 460 |
} |
| 388 |
return PluginImportOperation.IMPORT_WITH_SOURCE; |
461 |
return PluginImportOperation.IMPORT_WITH_SOURCE; |
| 389 |
} |
462 |
} |
| 390 |
|
463 |
|
|
Lines 481-493
Link Here
|
| 481 |
|
554 |
|
| 482 |
/** |
555 |
/** |
| 483 |
* Resolves the target platform |
556 |
* Resolves the target platform |
|
|
557 |
* @param type import type |
| 484 |
*/ |
558 |
*/ |
| 485 |
private void resolveTargetPlatform() { |
559 |
private void resolveTargetPlatform(final int type) { |
| 486 |
IRunnableWithProgress op = new IRunnableWithProgress() { |
560 |
IRunnableWithProgress op = new IRunnableWithProgress() { |
| 487 |
public void run(IProgressMonitor monitor) { |
561 |
public void run(IProgressMonitor monitor) throws InvocationTargetException { |
| 488 |
models = PluginRegistry.getExternalModels(); |
562 |
models = PluginRegistry.getExternalModels(); |
| 489 |
state = PDECore.getDefault().getModelManager().getState(); |
563 |
state = PDECore.getDefault().getModelManager().getState(); |
| 490 |
alternateSource = null; |
564 |
alternateSource = null; |
|
|
565 |
try { |
| 566 |
buildImportDescriptions(monitor, type); |
| 567 |
} catch (CoreException e) { |
| 568 |
throw new InvocationTargetException(e); |
| 569 |
} |
| 491 |
monitor.done(); |
570 |
monitor.done(); |
| 492 |
} |
571 |
} |
| 493 |
}; |
572 |
}; |
|
Lines 516-522
Link Here
|
| 516 |
} |
595 |
} |
| 517 |
ITargetDefinition target = service.newTarget(); // temporary target |
596 |
ITargetDefinition target = service.newTarget(); // temporary target |
| 518 |
target.setBundleContainers(new IBundleContainer[] {container}); |
597 |
target.setBundleContainers(new IBundleContainer[] {container}); |
| 519 |
resolveTargetDefinition(target); |
598 |
resolveTargetDefinition(target, getImportType()); |
| 520 |
} |
599 |
} |
| 521 |
} |
600 |
} |
| 522 |
|
601 |
|
|
Lines 524-533
Link Here
|
| 524 |
* Resolves the plug-in locations for a target definition. |
603 |
* Resolves the plug-in locations for a target definition. |
| 525 |
* |
604 |
* |
| 526 |
* @param target target definition |
605 |
* @param target target definition |
|
|
606 |
* @param type import operation type |
| 527 |
*/ |
607 |
*/ |
| 528 |
private void resolveTargetDefinition(final ITargetDefinition target) { |
608 |
private void resolveTargetDefinition(final ITargetDefinition target, final int type) { |
| 529 |
IRunnableWithProgress op = new IRunnableWithProgress() { |
609 |
IRunnableWithProgress op = new IRunnableWithProgress() { |
| 530 |
public void run(IProgressMonitor monitor) { |
610 |
public void run(IProgressMonitor monitor) throws InvocationTargetException { |
| 531 |
monitor.beginTask(PDEUIMessages.PluginImportWizardFirstPage_1, 100); |
611 |
monitor.beginTask(PDEUIMessages.PluginImportWizardFirstPage_1, 100); |
| 532 |
SubProgressMonitor pm = new SubProgressMonitor(monitor, 50); |
612 |
SubProgressMonitor pm = new SubProgressMonitor(monitor, 50); |
| 533 |
target.resolve(pm); |
613 |
target.resolve(pm); |
|
Lines 567-572
Link Here
|
| 567 |
} |
647 |
} |
| 568 |
} |
648 |
} |
| 569 |
alternateSource = new AlternateSourceLocations((IPluginModelBase[]) sourceModels.toArray(new IPluginModelBase[sourceModels.size()]), (IResolvedBundle[]) sourceBundles.toArray(new IResolvedBundle[sourceBundles.size()])); |
649 |
alternateSource = new AlternateSourceLocations((IPluginModelBase[]) sourceModels.toArray(new IPluginModelBase[sourceModels.size()]), (IResolvedBundle[]) sourceBundles.toArray(new IResolvedBundle[sourceBundles.size()])); |
|
|
650 |
try { |
| 651 |
buildImportDescriptions(pm, type); |
| 652 |
} catch (CoreException e) { |
| 653 |
throw new InvocationTargetException(e); |
| 654 |
} |
| 570 |
pm.done(); |
655 |
pm.done(); |
| 571 |
canceled = monitor.isCanceled(); |
656 |
canceled = monitor.isCanceled(); |
| 572 |
monitor.done(); |
657 |
monitor.done(); |
|
Lines 580-595
Link Here
|
| 580 |
} |
665 |
} |
| 581 |
} |
666 |
} |
| 582 |
|
667 |
|
|
|
668 |
private void buildImportDescriptions(IProgressMonitor monitor, int type) throws CoreException { |
| 669 |
// build import instructions |
| 670 |
BundleProjectService service = (BundleProjectService) BundleProjectService.getDefault(); |
| 671 |
if (type == PluginImportOperation.IMPORT_FROM_REPOSITORY) { |
| 672 |
if (models != null) { |
| 673 |
repositoryModels = new HashSet(); |
| 674 |
importerToInstructions = service.getImportDescriptions(models); |
| 675 |
Iterator iterator = importerToInstructions.entrySet().iterator(); |
| 676 |
while (iterator.hasNext()) { |
| 677 |
if (!monitor.isCanceled()) { |
| 678 |
Entry entry = (Entry) iterator.next(); |
| 679 |
BundleImportDescription[] descriptions = (BundleImportDescription[]) entry.getValue(); |
| 680 |
for (int i = 0; i < descriptions.length; i++) { |
| 681 |
repositoryModels.add(descriptions[i].getProperty(BundleProjectService.PLUGIN)); |
| 682 |
} |
| 683 |
} |
| 684 |
} |
| 685 |
} |
| 686 |
} |
| 687 |
if (monitor.isCanceled()) { |
| 688 |
importerToInstructions.clear(); |
| 689 |
repositoryModels.clear(); |
| 690 |
} else { |
| 691 |
// contributed wizard pages |
| 692 |
Iterator iterator = importerToInstructions.entrySet().iterator(); |
| 693 |
nextPages.clear(); |
| 694 |
while (iterator.hasNext()) { |
| 695 |
Entry entry = (Entry) iterator.next(); |
| 696 |
IBundleImporter importer = (IBundleImporter) entry.getKey(); |
| 697 |
IBundeImportWizardPage page = (IBundeImportWizardPage) importIdToWizardPage.get(importer.getId()); |
| 698 |
if (page == null) { |
| 699 |
page = getPage(importer.getId()); |
| 700 |
if (page != null) { |
| 701 |
importIdToWizardPage.put(importer.getId(), page); |
| 702 |
((Wizard) getWizard()).addPage(page); |
| 703 |
} |
| 704 |
} |
| 705 |
if (page != null) { |
| 706 |
nextPages.add(page); |
| 707 |
page.setSelection((BundleImportDescription[]) entry.getValue()); |
| 708 |
} |
| 709 |
} |
| 710 |
} |
| 711 |
} |
| 712 |
|
| 713 |
/** |
| 714 |
* Returns whether the contributed pages are complete. |
| 715 |
* |
| 716 |
* @return whether the contributed pages are complete |
| 717 |
*/ |
| 718 |
boolean arePagesComplete() { |
| 719 |
Iterator iterator = nextPages.iterator(); |
| 720 |
while (iterator.hasNext()) { |
| 721 |
IBundeImportWizardPage page = (IBundeImportWizardPage) iterator.next(); |
| 722 |
if (!page.isPageComplete()) { |
| 723 |
return false; |
| 724 |
} |
| 725 |
} |
| 726 |
return true; |
| 727 |
} |
| 728 |
|
| 729 |
/** |
| 730 |
* Finishes contributed pages. |
| 731 |
* |
| 732 |
* @return whether finish was successful |
| 733 |
*/ |
| 734 |
boolean finishPages() { |
| 735 |
Iterator iterator = nextPages.iterator(); |
| 736 |
while (iterator.hasNext()) { |
| 737 |
IBundeImportWizardPage page = (IBundeImportWizardPage) iterator.next(); |
| 738 |
if (!page.finish()) { |
| 739 |
return false; |
| 740 |
} |
| 741 |
} |
| 742 |
return true; |
| 743 |
} |
| 744 |
|
| 745 |
/** |
| 746 |
* Returns a map of importers to their bundle import descriptions to process. |
| 747 |
* |
| 748 |
* @return map of bundle import descriptions to process, by importers |
| 749 |
*/ |
| 750 |
Map getImportDescriptions() { |
| 751 |
Map map = new HashMap(); |
| 752 |
IBundleImporter[] importers = ((BundleProjectService) BundleProjectService.getDefault()).getBundleImporters(); |
| 753 |
for (int i = 0; i < importers.length; i++) { |
| 754 |
IBundleImporter importer = importers[i]; |
| 755 |
if (importerToInstructions.containsKey(importer)) { |
| 756 |
IBundeImportWizardPage page = (IBundeImportWizardPage) importIdToWizardPage.get(importer.getId()); |
| 757 |
if (page != null && nextPages.contains(page)) { |
| 758 |
map.put(importer, page.getSelection()); |
| 759 |
} |
| 760 |
} |
| 761 |
} |
| 762 |
return map; |
| 763 |
} |
| 764 |
|
| 765 |
/** |
| 766 |
* Returns the next page to display or <code>null</code> if none. |
| 767 |
* |
| 768 |
* @param page current page |
| 769 |
* @return next page or <code>null</code> |
| 770 |
*/ |
| 771 |
IWizardPage getNextPage(IWizardPage page) { |
| 772 |
if (nextPages.isEmpty()) { |
| 773 |
return null; |
| 774 |
} |
| 775 |
if (page instanceof IBundeImportWizardPage) { |
| 776 |
int index = nextPages.indexOf(page); |
| 777 |
if (index >= 0 && index < (nextPages.size() - 2)) { |
| 778 |
return (IWizardPage) nextPages.get(index + 1); |
| 779 |
} |
| 780 |
} |
| 781 |
if (page instanceof PluginImportWizardDetailedPage) { |
| 782 |
return (IWizardPage) nextPages.get(0); |
| 783 |
} |
| 784 |
return null; |
| 785 |
} |
| 786 |
|
| 787 |
/** |
| 788 |
* Returns the previous page to display or <code>null</code> if none. |
| 789 |
* |
| 790 |
* @param page current page |
| 791 |
* @return previous page or <code>null</code> |
| 792 |
*/ |
| 793 |
IWizardPage getPreviousPage(IWizardPage page) { |
| 794 |
if (page instanceof IBundeImportWizardPage) { |
| 795 |
int index = nextPages.indexOf(page); |
| 796 |
if (index > 0) { |
| 797 |
return (IWizardPage) nextPages.get(index - 1); |
| 798 |
} |
| 799 |
} |
| 800 |
return null; |
| 801 |
} |
| 802 |
|
| 803 |
/** |
| 804 |
* Creates and returns a wizard page associated with the given bundle importer extension identifier |
| 805 |
* or <code>null</code> of none. |
| 806 |
* |
| 807 |
* @param importerId org.eclipse.pde.core.bundleImporters extension identifier |
| 808 |
* @return associated bundle import wizard page or <code>null</code> |
| 809 |
*/ |
| 810 |
private IBundeImportWizardPage getPage(String importerId) { |
| 811 |
IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(IPDEUIConstants.EXTENSION_POINT_BUNDLE_IMPORT_PAGES); |
| 812 |
if (point != null) { |
| 813 |
IConfigurationElement[] infos = point.getConfigurationElements(); |
| 814 |
for (int i = 0; i < infos.length; i++) { |
| 815 |
IConfigurationElement element = infos[i]; |
| 816 |
String id = element.getAttribute("bundleImporter"); //$NON-NLS-1$ |
| 817 |
if (id != null && importerId.equals(id)) { |
| 818 |
try { |
| 819 |
return (IBundeImportWizardPage) element.createExecutableExtension("class"); //$NON-NLS-1$ |
| 820 |
} catch (CoreException e) { |
| 821 |
PDEPlugin.log(e); |
| 822 |
} |
| 823 |
} |
| 824 |
} |
| 825 |
} |
| 826 |
return null; |
| 827 |
} |
| 828 |
|
| 583 |
/** |
829 |
/** |
| 584 |
* @return the complete set of {@link IPluginModelBase}s for the given drop location |
830 |
* @return the complete set of {@link IPluginModelBase}s for the given drop location |
| 585 |
*/ |
831 |
*/ |
| 586 |
public IPluginModelBase[] getModels() { |
832 |
public IPluginModelBase[] getModels() { |
| 587 |
switch (getImportOrigin()) { |
833 |
switch (getImportOrigin()) { |
| 588 |
case FROM_ACTIVE_PLATFORM : |
834 |
case FROM_ACTIVE_PLATFORM : |
| 589 |
resolveTargetPlatform(); |
835 |
resolveTargetPlatform(getImportType()); |
| 590 |
break; |
836 |
break; |
| 591 |
case FROM_TARGET_DEFINITION : |
837 |
case FROM_TARGET_DEFINITION : |
| 592 |
resolveTargetDefinition(getTargetDefinition()); |
838 |
resolveTargetDefinition(getTargetDefinition(), getImportType()); |
| 593 |
break; |
839 |
break; |
| 594 |
case FROM_DIRECTORY : |
840 |
case FROM_DIRECTORY : |
| 595 |
resolveArbitraryLocation(getDropLocation()); |
841 |
resolveArbitraryLocation(getDropLocation()); |