Skip to content

Commit 3a11ebb

Browse files
committed
Always consider fragments that specify a platform filter
A fragment can declare a Eclipse-PlatformFilter to be only installed on a given platform. If such fragment is currently wired to a host bundle, it is quite likely that fragment is needed but the host usually do not declare an Eclipse-ExtensibleAPI so we currently miss to add such fragment making the native code loading fails. This now adds some code to store the platform filter and if one is given the fragment is always included. Fix #1929
1 parent d9ad053 commit 3a11ebb

File tree

12 files changed

+203
-26
lines changed

12 files changed

+203
-26
lines changed

ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/ClasspathUtilCore.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,17 @@ public static boolean hasExtensibleAPI(IPluginModelBase model) {
224224
return false;
225225
}
226226

227+
public static String getPlatformFilter(IPluginModelBase model) {
228+
IPluginBase pluginBase = model.getPluginBase();
229+
if (pluginBase instanceof BundlePlugin plugin) {
230+
return plugin.getPlatformFilter();
231+
}
232+
if (pluginBase instanceof BundleFragment fragment) {
233+
return fragment.getPlatformFilter();
234+
}
235+
return null;
236+
}
237+
227238
public static boolean isPatchFragment(Resource desc) {
228239
IPluginModelBase model = PluginRegistry.findModel(desc);
229240
return model instanceof IFragmentModel i ? isPatchFragment(i.getFragment()) : false;

ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/DependencyManager.java

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,19 @@ public enum Options {
6868
* Specifies to include all non-test fragments into the closure (must
6969
* not be combined with {@link #INCLUDE_ALL_FRAGMENTS}).
7070
*/
71-
INCLUDE_NON_TEST_FRAGMENTS;
71+
INCLUDE_NON_TEST_FRAGMENTS,
72+
/**
73+
* Option that can be set to include native fragments, that are ones
74+
* that define an {@link ICoreConstants#PLATFORM_FILTER} in their
75+
* manifest.
76+
*/
77+
INCLUDE_PLATFORM_FRAGMENTS,
78+
/**
79+
* Option that can be set to include native fragments, that are ones
80+
* that define an {@link ICoreConstants#PLATFORM_FILTER} in their
81+
* manifest.
82+
*/
83+
INCLUDE_EXTENSIBLE_FRAGMENTS;
7284
}
7385

7486
/**
@@ -168,6 +180,8 @@ public static Set<BundleDescription> findRequirementsClosure(Collection<BundleDe
168180
boolean includeOptional = optionSet.contains(Options.INCLUDE_OPTIONAL_DEPENDENCIES);
169181
boolean includeAllFragments = optionSet.contains(Options.INCLUDE_ALL_FRAGMENTS);
170182
boolean includeNonTestFragments = optionSet.contains(Options.INCLUDE_NON_TEST_FRAGMENTS);
183+
boolean includeNativeFragments = optionSet.contains(Options.INCLUDE_PLATFORM_FRAGMENTS);
184+
boolean includeExtensibleFragments = optionSet.contains(Options.INCLUDE_EXTENSIBLE_FRAGMENTS);
171185
if (includeAllFragments && includeNonTestFragments) {
172186
throw new AssertionError("Cannot combine INCLUDE_ALL_FRAGMENTS and INCLUDE_NON_TEST_FRAGMENTS"); //$NON-NLS-1$
173187
}
@@ -188,14 +202,22 @@ public static Set<BundleDescription> findRequirementsClosure(Collection<BundleDe
188202
if (wiring == null || !wiring.isInUse()) {
189203
continue;
190204
}
191-
if (includeAllFragments || includeNonTestFragments || isExtensibleApi(bundle)) {
205+
if (includeAllFragments || includeNonTestFragments
206+
|| (includeExtensibleFragments && isExtensibleApi(bundle))) {
192207
// A fragment's host is already required by a wire
193208
for (BundleDescription fragment : bundle.getFragments()) {
194209
if (includeAllFragments || !isTestWorkspaceProject(fragment)) {
195210
addNewRequiredBundle(fragment, closure, pending);
196211
}
197212
}
198213
}
214+
if (includeNativeFragments) {
215+
for (BundleDescription fragment : bundle.getFragments()) {
216+
if (isNativeFragment(fragment) && !isTestWorkspaceProject(fragment)) {
217+
addNewRequiredBundle(fragment, closure, pending);
218+
}
219+
}
220+
}
199221

200222
if (isFragment(wiring.getRevision())) {
201223
// Requirements of a fragment are hosted at the host, which
@@ -231,6 +253,14 @@ public static Set<BundleDescription> findRequirementsClosure(Collection<BundleDe
231253
return closure;
232254
}
233255

256+
private static boolean isNativeFragment(BundleDescription fragment) {
257+
Object userObject = fragment.getUserObject();
258+
if (userObject instanceof IPluginModelBase model) {
259+
return ClasspathUtilCore.getPlatformFilter(model) != null;
260+
}
261+
return false;
262+
}
263+
234264
private static boolean isExtensibleApi(BundleDescription bundleDescription) {
235265
if (bundleDescription.getFragments().length == 0) {
236266
return false;

ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/PDEAuxiliaryState.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ static class PluginInfo {
9797
String localization;
9898
String bundleSourceEntry;
9999
boolean exportsExternalAnnotations;
100+
String platformFilter;
100101
}
101102

102103
/**
@@ -379,6 +380,7 @@ protected void addAuxiliaryData(BundleDescription desc, Map<String, String> mani
379380
info.libraries = getClasspath(manifest);
380381
info.hasExtensibleAPI = "true".equals(manifest.get(ICoreConstants.EXTENSIBLE_API)); //$NON-NLS-1$
381382
info.isPatchFragment = "true".equals(manifest.get(ICoreConstants.PATCH_FRAGMENT)); //$NON-NLS-1$
383+
info.platformFilter = manifest.get(ICoreConstants.PLATFORM_FILTER);
382384
info.localization = manifest.get(Constants.BUNDLE_LOCALIZATION);
383385
info.hasBundleStructure = hasBundleStructure;
384386
info.bundleSourceEntry = manifest.get(ICoreConstants.ECLIPSE_SOURCE_BUNDLE);

ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/bundle/BundleFragment.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,8 @@ public boolean isPatch() {
122122
return "true".equals(getValue(ICoreConstants.PATCH_FRAGMENT, false)); //$NON-NLS-1$
123123
}
124124

125+
public String getPlatformFilter() {
126+
return getValue(ICoreConstants.PLATFORM_FILTER, false);
127+
}
128+
125129
}

ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/bundle/BundlePlugin.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,8 @@ public boolean exportsExternalAnnotations() {
5757
return "true".equals(getValue(ICoreConstants.ECLIPSE_EXPORT_EXTERNAL_ANNOTATIONS, false)); //$NON-NLS-1$
5858
}
5959

60+
public String getPlatformFilter() {
61+
return getValue(ICoreConstants.PLATFORM_FILTER, false);
62+
}
63+
6064
}

ui/org.eclipse.pde.launching/src/org/eclipse/pde/internal/launching/ILaunchingPreferenceConstants.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ public interface ILaunchingPreferenceConstants {
2525

2626
// Main preference page
2727
public static final String PROP_AUTO_MANAGE = "Preferences.Launching.automanageDependencies"; //$NON-NLS-1$
28+
public static final String PROP_AUTO_MANAGE_EXTENSIBLE_FRAGMENTS = "Preferences.Launching.automanageDependencies.includeExtensibleFragments"; //$NON-NLS-1$
29+
public static final String PROP_AUTO_MANAGE_PLATFORM_FRAGMENTS = "Preferences.Launching.automanageDependencies.includePlatformFragments"; //$NON-NLS-1$
2830
public static final String PROP_RUNTIME_WORKSPACE_LOCATION = "Preferences.Launching.runtimeWorkspaceLocation"; //$NON-NLS-1$
2931
public static final String PROP_RUNTIME_WORKSPACE_LOCATION_IS_CONTAINER = "Preferences.Launching.runtimeWorkspaceLocationIsContainer"; //$NON-NLS-1$
3032
public static final String PROP_JUNIT_WORKSPACE_LOCATION = "Preferences.Launching.junitWorkspaceLocation"; //$NON-NLS-1$

ui/org.eclipse.pde.launching/src/org/eclipse/pde/internal/launching/PreferenceInitializer.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ public void initializeDefaultPreferences() {
3636
prefs.putBoolean(ILaunchingPreferenceConstants.PROP_JUNIT_ADD_NEW_WORKSPACE_PLUGINS, false);
3737
prefs.putBoolean(ILaunchingPreferenceConstants.PROP_JUNIT_VALIDATE_LAUNCH, true);
3838
prefs.putBoolean(ILaunchingPreferenceConstants.ADD_SWT_NON_DISPOSAL_REPORTING, true);
39+
prefs.putBoolean(ILaunchingPreferenceConstants.PROP_AUTO_MANAGE_EXTENSIBLE_FRAGMENTS, true);
40+
prefs.putBoolean(ILaunchingPreferenceConstants.PROP_AUTO_MANAGE_PLATFORM_FRAGMENTS, true);
3941

4042
// copy over instance scope prefs from UI plugin
4143
IEclipsePreferences oldInstancePrefs = InstanceScope.INSTANCE.getNode(IPDEConstants.UI_PLUGIN_ID);

ui/org.eclipse.pde.launching/src/org/eclipse/pde/internal/launching/launcher/BundleLauncherHelper.java

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
import org.eclipse.pde.internal.core.DependencyManager;
6767
import org.eclipse.pde.internal.core.FeatureModelManager;
6868
import org.eclipse.pde.internal.core.PDECore;
69+
import org.eclipse.pde.internal.core.PDEPreferencesManager;
6970
import org.eclipse.pde.internal.core.PluginModelManager;
7071
import org.eclipse.pde.internal.core.TargetPlatformHelper;
7172
import org.eclipse.pde.internal.core.ifeature.IFeature;
@@ -74,6 +75,7 @@
7475
import org.eclipse.pde.internal.core.ifeature.IFeatureModel;
7576
import org.eclipse.pde.internal.core.ifeature.IFeaturePlugin;
7677
import org.eclipse.pde.internal.core.util.VersionUtil;
78+
import org.eclipse.pde.internal.launching.ILaunchingPreferenceConstants;
7779
import org.eclipse.pde.internal.launching.IPDEConstants;
7880
import org.eclipse.pde.internal.launching.PDELaunchingPlugin;
7981
import org.eclipse.pde.internal.launching.PDEMessages;
@@ -168,11 +170,29 @@ private static void addRequiredBundles(Map<IPluginModelBase, String> bundle2star
168170
List<String> appRequirements = RequirementHelper.getApplicationLaunchRequirements(configuration);
169171
RequirementHelper.addApplicationLaunchRequirements(appRequirements, configuration, bundle2startLevel);
170172

171-
boolean includeOptional = configuration.getAttribute(IPDELauncherConstants.INCLUDE_OPTIONAL, true);
172-
computeDependencies(bundle2startLevel.keySet(), includeOptional, true) //
173+
Set<DependencyManager.Options> options = configurationToOptions(configuration);
174+
computeDependencies(bundle2startLevel.keySet(), options, true) //
173175
.forEach(p -> addDefaultStartingBundle(bundle2startLevel, p));
174176
}
175177

178+
protected static Set<DependencyManager.Options> configurationToOptions(ILaunchConfiguration configuration) throws CoreException {
179+
boolean includeOptional = configuration.getAttribute(IPDELauncherConstants.INCLUDE_OPTIONAL, true);
180+
//TODO read everything from launch config
181+
PDEPreferencesManager launchingStore = PDELaunchingPlugin.getDefault().getPreferenceManager();
182+
183+
Set<DependencyManager.Options> options = new HashSet<>();
184+
if (includeOptional) {
185+
options.add(DependencyManager.Options.INCLUDE_OPTIONAL_DEPENDENCIES);
186+
}
187+
if (launchingStore.getBoolean(ILaunchingPreferenceConstants.PROP_AUTO_MANAGE_EXTENSIBLE_FRAGMENTS)) {
188+
options.add(DependencyManager.Options.INCLUDE_EXTENSIBLE_FRAGMENTS);
189+
}
190+
if (launchingStore.getBoolean(ILaunchingPreferenceConstants.PROP_AUTO_MANAGE_PLATFORM_FRAGMENTS)) {
191+
options.add(DependencyManager.Options.INCLUDE_PLATFORM_FRAGMENTS);
192+
}
193+
return options;
194+
}
195+
176196
// --- feature based launches ---
177197

178198
private static Map<IPluginModelBase, String> getMergedBundleMapFeatureBased(ILaunchConfiguration configuration, Map<IFeature, Boolean> features) throws CoreException {
@@ -221,12 +241,13 @@ private static Map<IPluginModelBase, String> getMergedBundleMapFeatureBased(ILau
221241
launchPlugins.addAll(additionalPlugins.keySet());
222242

223243
if (addRequirements) {
244+
Set<DependencyManager.Options> options = configurationToOptions(configuration);
224245
// Add all missing plug-ins required by the application/product set in the config
225246
List<String> appRequirements = RequirementHelper.getApplicationLaunchRequirements(configuration);
226247
RequirementHelper.addApplicationLaunchRequirements(appRequirements, configuration, launchPlugins, launchPlugins::add);
227248

228249
// Get all required plugins
229-
computeDependencies(launchPlugins, false, isWorkspace(defaultPluginResolution)).forEach(launchPlugins::add);
250+
computeDependencies(launchPlugins, options, isWorkspace(defaultPluginResolution)).forEach(launchPlugins::add);
230251
}
231252

232253
// Create the start levels for the selected plugins and add them to the map
@@ -542,7 +563,7 @@ private static void addBundleToMap(Map<IPluginModelBase, String> map, IPluginMod
542563

543564
// --- dependency resolution ---
544565

545-
private static Stream<IPluginModelBase> computeDependencies(Set<IPluginModelBase> includedPlugins, boolean includeOptional, boolean preferWorkspaceBundles) {
566+
private static Stream<IPluginModelBase> computeDependencies(Set<IPluginModelBase> includedPlugins, Set<DependencyManager.Options> options, boolean preferWorkspaceBundles) {
546567
if (includedPlugins.isEmpty()) {
547568
return Stream.empty();
548569
}
@@ -556,11 +577,7 @@ private static Stream<IPluginModelBase> computeDependencies(Set<IPluginModelBase
556577
Version version = versionStr != null ? Version.parseVersion(versionStr) : null;
557578
return launchState.getBundle(descriptor.getId(), version);
558579
}).forEach(launchBundles::add);
559-
560-
DependencyManager.Options[] options = includeOptional //
561-
? new DependencyManager.Options[] {DependencyManager.Options.INCLUDE_OPTIONAL_DEPENDENCIES}
562-
: new DependencyManager.Options[] {};
563-
Set<BundleDescription> closure = DependencyManager.findRequirementsClosure(launchBundles, options);
580+
Set<BundleDescription> closure = DependencyManager.findRequirementsClosure(launchBundles, options.toArray(DependencyManager.Options[]::new));
564581
return closure.stream().map(launchBundlePlugins::get).map(Objects::requireNonNull) //
565582
.filter(p -> !includedPlugins.contains(p));
566583
}

ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/PDEUIMessages.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2474,6 +2474,14 @@ public class PDEUIMessages extends NLS {
24742474
public static String ConfigurationPageMock_sectionDesc;
24752475
public static String PluginConfigurationSection_tablePluginTitle;
24762476

2477+
public static String AbstractPluginBlock_addRequiredDialogIncludeAllFragments;
2478+
2479+
public static String AbstractPluginBlock_addRequiredDialogIncludeFragmentsWithoutTests;
2480+
2481+
public static String AbstractPluginBlock_addRequiredDialogIncludeOptional;
2482+
2483+
public static String AbstractPluginBlock_addRequiredDialogTitle;
2484+
24772485
public static String AbstractPluginBlock_counter;
24782486

24792487
public static String AbstractRepository_ErrorLoadingImageFromJar;
@@ -2711,6 +2719,12 @@ public class PDEUIMessages extends NLS {
27112719

27122720
public static String LaunchingPreferencePage_description;
27132721

2722+
public static String LaunchingPreferencePage_GroupComputingOptions;
2723+
2724+
public static String LaunchingPreferencePage_IncludeExtensibleFragments;
2725+
2726+
public static String LaunchingPreferencePage_IncludePlatformFragments;
2727+
27142728
public static String RemoveLazyLoadingDirectiveResolution_remove;
27152729

27162730
public static String RemoveAutomaticModuleResolution_remove;

ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/launcher/AbstractPluginBlock.java

Lines changed: 76 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import org.eclipse.debug.core.ILaunchConfiguration;
4343
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
4444
import org.eclipse.jdt.core.IJavaProject;
45+
import org.eclipse.jface.dialogs.Dialog;
4546
import org.eclipse.jface.dialogs.MessageDialog;
4647
import org.eclipse.jface.util.Util;
4748
import org.eclipse.jface.viewers.CheckStateChangedEvent;
@@ -415,11 +416,14 @@ public void createControl(Composite parent, int span, int indent) {
415416
SelectionListener.widgetSelectedAdapter(e -> this.fAutoIncludeRequirementsButtonChanged = true));
416417

417418
if (fTab instanceof PluginsTab) {
418-
fIncludeOptionalButton = createButton(parent, span, indent,PDEUIMessages.AdvancedLauncherTab_includeOptional_plugins);
419+
fIncludeOptionalButton = createButton(parent, span, indent + 15,
420+
PDEUIMessages.AdvancedLauncherTab_includeOptional_plugins);
419421
}else if (fTab instanceof BundlesTab) {
420-
fIncludeOptionalButton = createButton(parent, span, indent, PDEUIMessages.AdvancedLauncherTab_includeOptional_bundles);
422+
fIncludeOptionalButton = createButton(parent, span, indent + 15,
423+
PDEUIMessages.AdvancedLauncherTab_includeOptional_bundles);
421424
}else{
422-
fIncludeOptionalButton = createButton(parent, span, indent, NLS.bind(PDEUIMessages.AdvancedLauncherTab_includeOptional, fTab.getName().toLowerCase(Locale.ENGLISH)));
425+
fIncludeOptionalButton = createButton(parent, span, indent + 15, NLS.bind(
426+
PDEUIMessages.AdvancedLauncherTab_includeOptional, fTab.getName().toLowerCase(Locale.ENGLISH)));
423427
}
424428
if (fTab instanceof PluginsTab) {
425429
fAddWorkspaceButton = createButton(parent, span, indent, PDEUIMessages.AdvancedLauncherTab_addNew_plugins);
@@ -868,22 +872,79 @@ protected void initializeButtonsFrom(ILaunchConfiguration config) throws CoreExc
868872
* then also checked in the tree
869873
*/
870874
protected void addRequiredPlugins() {
871-
Object[] checked = fPluginTreeViewer.getCheckedLeafElements();
872-
List<IPluginModelBase> toCheck = Arrays.stream(checked).filter(IPluginModelBase.class::isInstance)
873-
.map(IPluginModelBase.class::cast).collect(Collectors.toList());
875+
Set<DependencyManager.Options> options = new HashSet<>();
876+
options.add(Options.INCLUDE_NON_TEST_FRAGMENTS);
877+
options.add(Options.INCLUDE_OPTIONAL_DEPENDENCIES);
878+
Dialog dialog = new Dialog(fPluginTreeViewer.getControl().getShell()) {
874879

875-
DependencyManager.Options[] options = fIncludeOptionalButton.getSelection()
876-
? new Options[] { Options.INCLUDE_NON_TEST_FRAGMENTS, Options.INCLUDE_OPTIONAL_DEPENDENCIES }
877-
: new Options[] { Options.INCLUDE_NON_TEST_FRAGMENTS };
878-
Set<BundleDescription> additionalBundles = DependencyManager.getDependencies(toCheck, options);
880+
@Override
881+
protected Control createDialogArea(Composite parent) {
882+
Composite composite = (Composite) super.createDialogArea(parent);
883+
Button buttonFragmentsAll = new Button(composite, SWT.RADIO);
884+
Button buttonFragmentNonTest = new Button(composite, SWT.RADIO);
885+
Button buttonOptional = new Button(composite, SWT.CHECK);
886+
buttonFragmentNonTest.setText(PDEUIMessages.AbstractPluginBlock_addRequiredDialogIncludeFragmentsWithoutTests);
887+
buttonFragmentNonTest.setSelection(true);
888+
SelectionListener radioListener = new SelectionListener() {
889+
890+
@Override
891+
public void widgetSelected(SelectionEvent e) {
892+
if (buttonFragmentNonTest.getSelection()) {
893+
options.add(Options.INCLUDE_NON_TEST_FRAGMENTS);
894+
options.remove(Options.INCLUDE_ALL_FRAGMENTS);
895+
} else {
896+
options.remove(Options.INCLUDE_NON_TEST_FRAGMENTS);
897+
options.add(Options.INCLUDE_ALL_FRAGMENTS);
898+
}
899+
}
900+
901+
@Override
902+
public void widgetDefaultSelected(SelectionEvent e) {
879903

880-
additionalBundles.stream().map(Resource.class::cast).map(PluginRegistry::findModel).filter(Objects::nonNull)
881-
.forEach(toCheck::add);
904+
}
905+
};
906+
buttonFragmentNonTest.addSelectionListener(radioListener);
907+
buttonFragmentsAll.setText(PDEUIMessages.AbstractPluginBlock_addRequiredDialogIncludeAllFragments);
908+
buttonFragmentsAll.addSelectionListener(radioListener);
909+
buttonOptional.setSelection(true);
910+
buttonOptional.setText(PDEUIMessages.AbstractPluginBlock_addRequiredDialogIncludeOptional);
911+
buttonOptional.addSelectionListener(new SelectionListener() {
912+
913+
@Override
914+
public void widgetSelected(SelectionEvent e) {
915+
if (buttonOptional.getSelection()) {
916+
options.add(Options.INCLUDE_OPTIONAL_DEPENDENCIES);
917+
} else {
918+
options.remove(Options.INCLUDE_OPTIONAL_DEPENDENCIES);
919+
}
920+
}
882921

883-
checked = toCheck.toArray();
884-
setCheckedElements(checked);
922+
@Override
923+
public void widgetDefaultSelected(SelectionEvent e) {
885924

886-
countSelectedModels();
925+
}
926+
});
927+
return composite;
928+
}
929+
930+
@Override
931+
protected void configureShell(Shell newShell) {
932+
super.configureShell(newShell);
933+
newShell.setText(PDEUIMessages.AbstractPluginBlock_addRequiredDialogTitle);
934+
}
935+
};
936+
if (dialog.open() == Window.OK) {
937+
Object[] checked = fPluginTreeViewer.getCheckedLeafElements();
938+
List<IPluginModelBase> toCheck = Arrays.stream(checked).filter(IPluginModelBase.class::isInstance)
939+
.map(IPluginModelBase.class::cast).collect(Collectors.toList());
940+
Set<BundleDescription> additionalBundles = DependencyManager.getDependencies(toCheck,
941+
options.toArray(DependencyManager.Options[]::new));
942+
additionalBundles.stream().map(Resource.class::cast).map(PluginRegistry::findModel).filter(Objects::nonNull)
943+
.forEach(toCheck::add);
944+
checked = toCheck.toArray();
945+
setCheckedElements(checked);
946+
countSelectedModels();
947+
}
887948
}
888949

889950
protected IPluginModelBase findPlugin(String id) {

0 commit comments

Comments
 (0)