/*
* CREDIT SUISSE IS WILLING TO LICENSE THIS SPECIFICATION TO YOU ONLY UPON THE CONDITION THAT YOU
* ACCEPT ALL OF THE TERMS CONTAINED IN THIS AGREEMENT. PLEASE READ THE TERMS AND CONDITIONS OF THIS
* AGREEMENT CAREFULLY. BY DOWNLOADING THIS SPECIFICATION, YOU ACCEPT THE TERMS AND CONDITIONS OF
* THE AGREEMENT. IF YOU ARE NOT WILLING TO BE BOUND BY IT, SELECT THE "DECLINE" BUTTON AT THE
* BOTTOM OF THIS PAGE. Specification: JSR-354 Money and Currency API ("Specification") Copyright
* (c) 2012-2013, Credit Suisse All rights reserved.
*/
package javax.money.spi;
import java.util.*;
import java.util.concurrent.
ConcurrentHashMap;
import java.util.logging.
Level;
import java.util.logging.
Logger;
/**
* This class implements the (default) {@link ServiceProvider} interface and hereby uses the JDK
* {@link ServiceLoader} to load the services required.
*
* @author Anatole Tresch
*/
class
DefaultServiceProvider implements
ServiceProvider {
/** List of services loaded, per class. */
private final
ConcurrentHashMap<
Class<?>,
List<
Object>>
servicesLoaded = new
ConcurrentHashMap<>();
@
Override
public int
getPriority() {
return 0;
}
/**
* Loads and registers services.
*
* @param serviceType
* The service type.
* @param <T>
* the concrete type.
* @return the items found, never {@code null}.
*/
@
Override
public <T>
List<T>
getServices(final
Class<T>
serviceType) {
@
SuppressWarnings("unchecked")
List<T>
found = (
List<T>)
servicesLoaded.
get(
serviceType);
if (
found != null) {
return
found;
}
return
loadServices(
serviceType);
}
/**
* Loads and registers services.
*
* @param serviceType The service type.
* @param <T> the concrete type.
*
* @return the items found, never {@code null}.
*/
private <T>
List<T>
loadServices(final
Class<T>
serviceType) {
List<T>
services = new
ArrayList<>();
try {
for (T
t :
ServiceLoader.
load(
serviceType)) {
services.
add(
t);
}
services.
sort(
Comparator.
comparing(
o ->
o.
getClass().
getSimpleName()));
@
SuppressWarnings("unchecked")
final
List<T>
previousServices = (
List<T>)
servicesLoaded.
putIfAbsent(
serviceType, (
List<
Object>)
services);
return
Collections.
unmodifiableList(
previousServices != null ?
previousServices :
services);
} catch (
Exception e) {
Logger.
getLogger(
DefaultServiceProvider.class.
getName()).
log(
Level.
WARNING,
"Error loading services of type " +
serviceType,
e);
return
services;
}
}
}