1515
1616import java .util .ArrayList ;
1717import java .util .Collection ;
18- import java .util .LinkedHashSet ;
18+ import java .util .HashSet ;
1919import java .util .List ;
2020import java .util .Map ;
2121import java .util .Optional ;
3333import org .eclipse .pde .internal .core .DependencyManager ;
3434import org .eclipse .pde .internal .core .PDECore ;
3535import org .eclipse .pde .internal .launching .launcher .BundleLauncherHelper ;
36- import org .osgi .framework .wiring .BundleRevision ;
36+ import org .osgi .framework .Version ;
37+ import org .osgi .resource .Resource ;
3738
3839public class JUnitLaunchRequirements {
3940
@@ -43,9 +44,16 @@ public class JUnitLaunchRequirements {
4344
4445 public static void addRequiredJunitRuntimePlugins (ILaunchConfiguration configuration , Map <String , List <IPluginModelBase >> collectedModels , Map <IPluginModelBase , String > startLevelMap ) throws CoreException {
4546 Collection <String > runtimePlugins = getRequiredJunitRuntimeEclipsePlugins (configuration );
46- Set <BundleDescription > addedRuntimeBundles = addAbsentRequirements (runtimePlugins , collectedModels , startLevelMap );
47- Set <BundleDescription > runtimeRequirements = DependencyManager .findRequirementsClosure (addedRuntimeBundles );
48- addAbsentRequirements (runtimeRequirements , collectedModels , startLevelMap );
47+ //We first need to collect the runtime, either by adding it or take it from the already selected bundles
48+ Collection <IPluginModelBase > collected = new HashSet <>();
49+ for (String id : runtimePlugins ) {
50+ addIfAbsent (id , collectedModels , startLevelMap ).or (() -> collectedModels .getOrDefault (id , List .of ()).stream ().filter (m -> m .getBundleDescription ().isResolved ()).findFirst ()).ifPresent (collected ::add );
51+ }
52+ //now compute the closure and add them to the collection
53+ Set <BundleDescription > closure = DependencyManager .findRequirementsClosure (collected .stream ().map (IPluginModelBase ::getBundleDescription ).toList ());
54+ for (BundleDescription description : closure ) {
55+ collected .add (addIfAbsent (description , collectedModels , startLevelMap ));
56+ }
4957 }
5058
5159 @ SuppressWarnings ("restriction" )
@@ -59,7 +67,7 @@ public static Collection<String> getRequiredJunitRuntimeEclipsePlugins(ILaunchCo
5967 return List .of (PDE_JUNIT_RUNTIME );
6068 } // Nothing to add for JUnit-3
6169 case org .eclipse .jdt .internal .junit .launcher .TestKindRegistry .JUNIT4_TEST_KIND_ID -> {
62- return List .of (PDE_JUNIT_RUNTIME ,JUNIT4_JDT_RUNTIME_PLUGIN );
70+ return List .of (PDE_JUNIT_RUNTIME , JUNIT4_JDT_RUNTIME_PLUGIN );
6371 }
6472 case org .eclipse .jdt .internal .junit .launcher .TestKindRegistry .JUNIT5_TEST_KIND_ID -> {
6573 return List .of (PDE_JUNIT_RUNTIME , JUNIT5_JDT_RUNTIME_PLUGIN );
@@ -68,37 +76,36 @@ public static Collection<String> getRequiredJunitRuntimeEclipsePlugins(ILaunchCo
6876 }
6977 }
7078
71- private static Set <BundleDescription > addAbsentRequirements (Collection <String > requirements , Map <String , List <IPluginModelBase >> collectedModels , Map <IPluginModelBase , String > startLevelMap ) throws CoreException {
72- Set <BundleDescription > addedRequirements = new LinkedHashSet <>();
73- for (String id : requirements ) {
74- List <IPluginModelBase > models = collectedModels .computeIfAbsent (id , k -> new ArrayList <>());
75- if (models .stream ().noneMatch (p -> p .getBundleDescription ().isResolved ())) {
76- IPluginModelBase model = findRequiredPluginInTargetOrHost (PluginRegistry .findModel (id ), plugins -> plugins .max (PDECore .VERSION ), id );
77- models .add (model );
78- BundleLauncherHelper .addDefaultStartingBundle (startLevelMap , model );
79- addedRequirements .add (model .getBundleDescription ());
80- }
79+ private static IPluginModelBase findRequiredPluginInTargetOrHost (IPluginModelBase model , Function <Stream <IPluginModelBase >, Optional <IPluginModelBase >> pluginSelector , String id ) throws CoreException {
80+ if (model == null || !model .getBundleDescription ().isResolved ()) {
81+ // prefer bundle from host over unresolved bundle from target
82+ model = pluginSelector .apply (PDECore .getDefault ().findPluginsInHost (id )) //
83+ .orElseThrow (() -> new CoreException (Status .error (NLS .bind (PDEMessages .JUnitLaunchConfiguration_error_missingPlugin , id ))));
8184 }
82- return addedRequirements ;
85+ return model ;
8386 }
8487
85- private static void addAbsentRequirements (Set <BundleDescription > requirements , Map <String , List <IPluginModelBase >> collectedModels , Map <IPluginModelBase , String > startLevelMap ) throws CoreException {
86- for (BundleRevision bundle : requirements ) {
87- String id = bundle .getSymbolicName ();
88- List <IPluginModelBase > models = collectedModels .computeIfAbsent (id , k -> new ArrayList <>());
89- if (models .stream ().map (IPluginModelBase ::getBundleDescription ).noneMatch (b -> b .isResolved () && b .getVersion ().equals (bundle .getVersion ()))) {
90- IPluginModelBase model = findRequiredPluginInTargetOrHost (PluginRegistry .findModel (bundle ), plgs -> plgs .filter (p -> p .getBundleDescription () == bundle ).findFirst (), id );
91- models .add (model );
92- BundleLauncherHelper .addDefaultStartingBundle (startLevelMap , model );
93- }
88+ private static Optional <IPluginModelBase > addIfAbsent (String id , Map <String , List <IPluginModelBase >> fAllBundles , Map <IPluginModelBase , String > fModels ) throws CoreException {
89+ List <IPluginModelBase > models = fAllBundles .computeIfAbsent (id , k -> new ArrayList <>());
90+ if (models .stream ().noneMatch (m -> m .getBundleDescription ().isResolved ())) {
91+ IPluginModelBase model = findRequiredPluginInTargetOrHost (PluginRegistry .findModel (id ), plugins -> plugins .max (PDECore .VERSION ), id );
92+ models .add (model );
93+ BundleLauncherHelper .addDefaultStartingBundle (fModels , model );
94+ return Optional .of (model );
9495 }
96+ return Optional .empty ();
9597 }
9698
97- private static IPluginModelBase findRequiredPluginInTargetOrHost (IPluginModelBase model , Function <Stream <IPluginModelBase >, Optional <IPluginModelBase >> pluginSelector , String id ) throws CoreException {
98- if (model == null || !model .getBundleDescription ().isResolved ()) {
99- // prefer bundle from host over unresolved bundle from target
100- model = pluginSelector .apply (PDECore .getDefault ().findPluginsInHost (id )) //
101- .orElseThrow (() -> new CoreException (Status .error (NLS .bind (PDEMessages .JUnitLaunchConfiguration_error_missingPlugin , id ))));
99+ private static IPluginModelBase addIfAbsent (BundleDescription description , Map <String , List <IPluginModelBase >> fAllBundles , Map <IPluginModelBase , String > fModels ) throws CoreException {
100+ IPluginModelBase model = PluginRegistry .findModel ((Resource ) description );
101+ if (model == null ) {
102+ Version version = description .getVersion ();
103+ model = PDECore .getDefault ().findPluginsInHost (description .getSymbolicName ()).filter (m -> version .equals (PDECore .getOSGiVersion (m ))).findFirst ().orElseThrow (() -> new CoreException (Status .error ("Resolved bundle description " + description + " not found in target or host!" ))); //$NON-NLS-1$//$NON-NLS-2$
104+ }
105+ List <IPluginModelBase > models = fAllBundles .computeIfAbsent (description .getSymbolicName (), k -> new ArrayList <>());
106+ if (!models .contains (model )) {
107+ models .add (model );
108+ BundleLauncherHelper .addDefaultStartingBundle (fModels , model );
102109 }
103110 return model ;
104111 }
0 commit comments