Skip to content

Commit dc2d4d4

Browse files
authored
#15 Support inclusion of services (uses/provides) (#16)
1 parent e3b4c60 commit dc2d4d4

File tree

8 files changed

+311
-27
lines changed

8 files changed

+311
-27
lines changed

plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/JavaModuleDescriptor.java

+102-10
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import java.util.Collections;
2323
import java.util.LinkedHashSet;
24+
import java.util.List;
2425
import java.util.Objects;
2526
import java.util.Set;
2627

@@ -38,9 +39,13 @@ public class JavaModuleDescriptor
3839

3940
private boolean automatic;
4041

41-
private Set<JavaRequires> requires = new LinkedHashSet<JavaRequires>();
42+
private Set<JavaRequires> requires = new LinkedHashSet<>();
4243

43-
private Set<JavaExports> exports = new LinkedHashSet<JavaExports>();
44+
private Set<JavaExports> exports = new LinkedHashSet<>();
45+
46+
private Set<String> uses = new LinkedHashSet<>();
47+
48+
private Set<JavaProvides> provides = new LinkedHashSet<>();
4449

4550
public String name()
4651
{
@@ -62,6 +67,16 @@ public Set<JavaExports> exports()
6267
return Collections.unmodifiableSet( exports );
6368
}
6469

70+
public Set<JavaProvides> provides()
71+
{
72+
return Collections.unmodifiableSet( provides );
73+
}
74+
75+
public Set<String> uses()
76+
{
77+
return Collections.unmodifiableSet( uses );
78+
}
79+
6580
public static JavaModuleDescriptor.Builder newModule( String name )
6681
{
6782
return new Builder( name ).setAutomatic( false );
@@ -145,8 +160,7 @@ private Builder setAutomatic( boolean isAutomatic )
145160
*/
146161
public Builder requires​( Set<JavaModuleDescriptor.JavaRequires.JavaModifier> modifiers, String name )
147162
{
148-
JavaRequires requires = new JavaRequires( modifiers, name );
149-
jModule.requires.add( requires );
163+
jModule.requires.add( new JavaRequires( modifiers, name ) );
150164
return this;
151165
}
152166

@@ -158,8 +172,7 @@ private Builder setAutomatic( boolean isAutomatic )
158172
*/
159173
public Builder requires( String name )
160174
{
161-
JavaRequires requires = new JavaRequires( name );
162-
jModule.requires.add( requires );
175+
jModule.requires.add( new JavaRequires( name ) );
163176
return this;
164177
}
165178

@@ -171,8 +184,7 @@ public Builder requires( String name )
171184
*/
172185
public Builder exports( String source )
173186
{
174-
JavaExports exports = new JavaExports( source );
175-
jModule.exports.add( exports );
187+
jModule.exports.add( new JavaExports( source ) );
176188
return this;
177189
}
178190

@@ -185,8 +197,25 @@ public Builder exports( String source )
185197
*/
186198
public Builder exports( String source, Set<String> targets )
187199
{
188-
JavaExports exports = new JavaExports( source, targets );
189-
jModule.exports.add( exports );
200+
jModule.exports.add( new JavaExports( source, targets ) );
201+
return this;
202+
}
203+
204+
/**
205+
* Adds a service dependence.
206+
*
207+
* @param service The service type
208+
* @return This Builder
209+
*/
210+
public Builder uses( String service )
211+
{
212+
jModule.uses.add( service );
213+
return this;
214+
}
215+
216+
public Builder provides​( String service, List<String> providers )
217+
{
218+
jModule.provides.add( new JavaProvides( service, providers ) );
190219
return this;
191220
}
192221

@@ -349,4 +378,67 @@ public boolean equals( Object obj )
349378
return true;
350379
}
351380
}
381+
382+
/**
383+
* Represents Module.Provides
384+
*
385+
* @author Robert Scholte
386+
* @since 1.0.0
387+
*/
388+
public static class JavaProvides
389+
{
390+
private final String service;
391+
392+
private final List<String> providers;
393+
394+
private JavaProvides( String service, List<String> providers )
395+
{
396+
this.service = service;
397+
this.providers = providers;
398+
}
399+
400+
public String service()
401+
{
402+
return service;
403+
}
404+
405+
public List<String> providers()
406+
{
407+
return providers;
408+
}
409+
410+
@Override
411+
public int hashCode()
412+
{
413+
return Objects.hash( service, providers );
414+
}
415+
416+
@Override
417+
public boolean equals( Object obj )
418+
{
419+
if ( this == obj )
420+
{
421+
return true;
422+
}
423+
if ( obj == null )
424+
{
425+
return false;
426+
}
427+
if ( getClass() != obj.getClass() )
428+
{
429+
return false;
430+
}
431+
432+
JavaProvides other = (JavaProvides) obj;
433+
if ( !Objects.equals( service, other.service ) )
434+
{
435+
return false;
436+
}
437+
if ( !Objects.equals( providers, other.providers ) )
438+
{
439+
return false;
440+
}
441+
return true;
442+
}
443+
}
352444
}

plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/LocationManager.java

+75-12
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import javax.inject.Singleton;
3434

3535
import org.codehaus.plexus.component.annotations.Component;
36+
import org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.JavaProvides;
3637

3738
/**
3839
* Maps artifacts to modules and analyzes the type of required modules
@@ -114,7 +115,15 @@ public <T> ResolvePathsResult<T> resolvePaths( final ResolvePathsRequest<T> requ
114115

115116
result.setMainModuleDescriptor( mainModuleDescriptor );
116117

117-
Map<String, JavaModuleDescriptor> availableNamedModules = new HashMap<>();
118+
// key = service, value = names of modules that provide this service
119+
Map<String, Set<String>> availableProviders = new HashMap<>();
120+
121+
if( mainModuleDescriptor != null && request.isIncludeAllProviders() )
122+
{
123+
collectProviders( mainModuleDescriptor, availableProviders );
124+
}
125+
126+
Map<String, JavaModuleDescriptor> availableNamedModules = new HashMap<>();
118127

119128
Map<String, ModuleNameSource> moduleNameSources = new HashMap<>();
120129

@@ -163,6 +172,11 @@ public String extract( Path path )
163172
moduleNameSources.put( moduleDescriptor.name(), source );
164173

165174
availableNamedModules.put( moduleDescriptor.name(), moduleDescriptor );
175+
176+
if ( request.isIncludeAllProviders() )
177+
{
178+
collectProviders( moduleDescriptor, availableProviders );
179+
}
166180
}
167181

168182
pathElements.put( t, moduleDescriptor );
@@ -196,12 +210,21 @@ public String extract( Path path )
196210
if ( mainModuleDescriptor != null )
197211
{
198212
Set<String> requiredNamedModules = new HashSet<>();
199-
213+
200214
requiredNamedModules.add( mainModuleDescriptor.name() );
201215

202-
requiredNamedModules.addAll( request.getAdditionalModules() );
216+
selectRequires( mainModuleDescriptor,
217+
Collections.unmodifiableMap( availableNamedModules ),
218+
Collections.unmodifiableMap( availableProviders ),
219+
requiredNamedModules );
203220

204-
select( mainModuleDescriptor, Collections.unmodifiableMap( availableNamedModules ), requiredNamedModules );
221+
for ( String additionalModule : request.getAdditionalModules() )
222+
{
223+
selectModule( additionalModule,
224+
Collections.unmodifiableMap( availableNamedModules ),
225+
Collections.unmodifiableMap( availableProviders ),
226+
requiredNamedModules );
227+
}
205228

206229
// in case of identical module names, first one wins
207230
Set<String> collectedModules = new HashSet<>( requiredNamedModules.size() );
@@ -258,8 +281,9 @@ else if ( descriptorPath.endsWith( "module-info.class" ) )
258281
private ResolvePathResult resolvePath( Path path, ModuleNameExtractor fileModulenameExtractor ) throws IOException
259282
{
260283
ResolvePathResult result = new ResolvePathResult();
284+
261285
JavaModuleDescriptor moduleDescriptor = null;
262-
286+
263287
// either jar or outputDirectory
264288
if ( Files.isRegularFile( path ) || Files.exists( path.resolve( "module-info.class" ) ) )
265289
{
@@ -293,23 +317,62 @@ private ResolvePathResult resolvePath( Path path, ModuleNameExtractor fileModule
293317
moduleDescriptor = JavaModuleDescriptor.newAutomaticModule( moduleName ).build();
294318
}
295319
}
296-
297320
result.setModuleDescriptor( moduleDescriptor );
321+
298322
return result;
299323
}
300324

301-
private void select( JavaModuleDescriptor module, Map<String, JavaModuleDescriptor> availableModules,
302-
Set<String> namedModules )
325+
private void selectRequires( JavaModuleDescriptor module,
326+
Map<String, JavaModuleDescriptor> availableModules,
327+
Map<String, Set<String>> availableProviders,
328+
Set<String> namedModules )
303329
{
304330
for ( JavaModuleDescriptor.JavaRequires requires : module.requires() )
305331
{
306-
String requiresName = requires.name();
307-
JavaModuleDescriptor requiredModule = availableModules.get( requiresName );
332+
selectModule( requires.name(), availableModules, availableProviders, namedModules );
333+
}
334+
335+
for ( String uses : module.uses() )
336+
{
337+
if ( availableProviders.containsKey( uses ) )
338+
{
339+
for ( String providerModule : availableProviders.get( uses ) )
340+
{
341+
JavaModuleDescriptor requiredModule = availableModules.get( providerModule );
342+
343+
if ( requiredModule != null && namedModules.add( providerModule ) )
344+
{
345+
selectRequires( requiredModule, availableModules, availableProviders, namedModules );
346+
}
347+
}
348+
}
349+
}
350+
}
351+
352+
private void selectModule( String module, Map<String, JavaModuleDescriptor> availableModules, Map<String, Set<String>> availableProviders,
353+
Set<String> namedModules )
354+
{
355+
JavaModuleDescriptor requiredModule = availableModules.get( module );
308356

309-
if ( requiredModule != null && namedModules.add( requiresName ) )
357+
if ( requiredModule != null && namedModules.add( module ) )
358+
{
359+
selectRequires( requiredModule, availableModules, availableProviders, namedModules );
360+
}
361+
}
362+
363+
private void collectProviders( JavaModuleDescriptor moduleDescriptor, Map<String, Set<String>> availableProviders )
364+
{
365+
for ( JavaProvides provides : moduleDescriptor.provides() )
366+
{
367+
Set<String> providingModules = availableProviders.get( provides.service() );
368+
369+
if ( providingModules == null )
310370
{
311-
select( requiredModule, availableModules, namedModules );
371+
providingModules = new HashSet<>();
372+
373+
availableProviders.put( provides.service(), providingModules );
312374
}
375+
providingModules.add( moduleDescriptor.name() );
313376
}
314377
}
315378
}

plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/ResolvePathsRequest.java

+35
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.io.File;
2323
import java.nio.file.Path;
2424
import java.nio.file.Paths;
25+
import java.util.Arrays;
2526
import java.util.Collection;
2627
import java.util.Collections;
2728

@@ -40,6 +41,8 @@ public abstract class ResolvePathsRequest<T>
4041
private Collection<T> pathElements;
4142

4243
private Collection<String> additionalModules;
44+
45+
private boolean includeAllProviders;
4346

4447
private ResolvePathsRequest()
4548
{
@@ -54,6 +57,11 @@ public static ResolvePathsRequest<File> withFiles( Collection<File> files )
5457
return ofFiles( files );
5558
}
5659

60+
public static ResolvePathsRequest<File> ofFiles( File... files )
61+
{
62+
return ofFiles( Arrays.asList( files ) );
63+
}
64+
5765
public static ResolvePathsRequest<File> ofFiles( Collection<File> files )
5866
{
5967
ResolvePathsRequest<File> request = new ResolvePathsRequest<File>()
@@ -78,6 +86,11 @@ public static ResolvePathsRequest<Path> withPaths( Collection<Path> paths )
7886
return ofPaths( paths );
7987
}
8088

89+
public static ResolvePathsRequest<Path> ofPaths( Path... paths )
90+
{
91+
return ofPaths( Arrays.asList( paths ) );
92+
}
93+
8194
public static ResolvePathsRequest<Path> ofPaths( Collection<Path> paths )
8295
{
8396
ResolvePathsRequest<Path> request = new ResolvePathsRequest<Path>() {
@@ -100,6 +113,11 @@ public static ResolvePathsRequest<String> withStrings( Collection<String> string
100113
return ofStrings( strings );
101114
}
102115

116+
public static ResolvePathsRequest<String> ofStrings( String... strings )
117+
{
118+
return ofStrings( Arrays.asList( strings ) );
119+
}
120+
103121
public static ResolvePathsRequest<String> ofStrings( Collection<String> strings )
104122
{
105123
ResolvePathsRequest<String> request = new ResolvePathsRequest<String>() {
@@ -178,4 +196,21 @@ public Collection<String> getAdditionalModules()
178196
}
179197
return additionalModules;
180198
}
199+
200+
/**
201+
* Will also include all modules that contain providers for used services, should only be used at runtime (not during compile nor test)
202+
*
203+
* @param includeAllProviders
204+
* @return this request
205+
*/
206+
public ResolvePathsRequest<T> setIncludeAllProviders( boolean includeAllProviders )
207+
{
208+
this.includeAllProviders = includeAllProviders;
209+
return this;
210+
}
211+
212+
public boolean isIncludeAllProviders()
213+
{
214+
return includeAllProviders;
215+
}
181216
}

plexus-java/src/main/java9/org/codehaus/plexus/languages/java/jpms/BinaryModuleInfoParser.java

+2
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ JavaModuleDescriptor parse( InputStream in ) throws IOException
6161
}
6262
}
6363

64+
65+
6466
return builder.build();
6567
}
6668
}

0 commit comments

Comments
 (0)