|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package jdk.internal.module; |
|
|
|
import java.lang.module.ModuleDescriptor; |
|
import java.lang.module.ModuleDescriptor.Provides; |
|
import java.util.ArrayList; |
|
import java.util.Collections; |
|
import java.util.List; |
|
import java.util.Map; |
|
import java.util.Objects; |
|
import java.util.concurrent.ConcurrentHashMap; |
|
import java.util.concurrent.CopyOnWriteArrayList; |
|
|
|
import jdk.internal.loader.ClassLoaderValue; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public final class ServicesCatalog { |
|
|
|
|
|
|
|
*/ |
|
public final class ServiceProvider { |
|
private final Module module; |
|
private final String providerName; |
|
|
|
public ServiceProvider(Module module, String providerName) { |
|
this.module = module; |
|
this.providerName = providerName; |
|
} |
|
|
|
public Module module() { |
|
return module; |
|
} |
|
|
|
public String providerName() { |
|
return providerName; |
|
} |
|
|
|
@Override |
|
public int hashCode() { |
|
return Objects.hash(module, providerName); |
|
} |
|
|
|
@Override |
|
public boolean equals(Object ob) { |
|
if (!(ob instanceof ServiceProvider)) |
|
return false; |
|
ServiceProvider that = (ServiceProvider)ob; |
|
return Objects.equals(this.module, that.module) |
|
&& Objects.equals(this.providerName, that.providerName); |
|
} |
|
} |
|
|
|
|
|
private final Map<String, List<ServiceProvider>> map = new ConcurrentHashMap<>(); |
|
|
|
private ServicesCatalog() { } |
|
|
|
|
|
|
|
|
|
*/ |
|
public static ServicesCatalog create() { |
|
return new ServicesCatalog(); |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
private List<ServiceProvider> providers(String service) { |
|
|
|
List<ServiceProvider> list = map.get(service); |
|
if (list == null) { |
|
list = new CopyOnWriteArrayList<>(); |
|
List<ServiceProvider> prev = map.putIfAbsent(service, list); |
|
if (prev != null) |
|
list = prev; |
|
} |
|
return list; |
|
} |
|
|
|
|
|
|
|
*/ |
|
public void register(Module module) { |
|
ModuleDescriptor descriptor = module.getDescriptor(); |
|
for (Provides provides : descriptor.provides()) { |
|
String service = provides.service(); |
|
List<String> providerNames = provides.providers(); |
|
int count = providerNames.size(); |
|
if (count == 1) { |
|
String pn = providerNames.get(0); |
|
providers(service).add(new ServiceProvider(module, pn)); |
|
} else { |
|
List<ServiceProvider> list = new ArrayList<>(count); |
|
for (String pn : providerNames) { |
|
list.add(new ServiceProvider(module, pn)); |
|
} |
|
providers(service).addAll(list); |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public void addProvider(Module module, Class<?> service, Class<?> impl) { |
|
List<ServiceProvider> list = providers(service.getName()); |
|
list.add(new ServiceProvider(module, impl.getName())); |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public List<ServiceProvider> findServices(String service) { |
|
return map.getOrDefault(service, Collections.emptyList()); |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public static ServicesCatalog getServicesCatalogOrNull(ClassLoader loader) { |
|
return CLV.get(loader); |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public static ServicesCatalog getServicesCatalog(ClassLoader loader) { |
|
|
|
ServicesCatalog catalog = CLV.get(loader); |
|
if (catalog == null) { |
|
catalog = create(); |
|
ServicesCatalog previous = CLV.putIfAbsent(loader, catalog); |
|
if (previous != null) catalog = previous; |
|
} |
|
return catalog; |
|
} |
|
|
|
|
|
private static final ClassLoaderValue<ServicesCatalog> CLV = new ClassLoaderValue<>(); |
|
} |