/**
* Copyright 2014 the staff of 52°North Initiative for Geospatial Open
* Source Software GmbH in their free time
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package spare.n52.yadarts.common;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Convenience class and Cache for {@link ServiceLoader} enabled interfaces.
*/
public class Services {
private static final Logger logger = LoggerFactory.getLogger(Services.class);
private static Map<Class<?>, List<Object>> interfaceImplementations = new HashMap<>();
/**
* @param theClazz the interface class
* @return the list of all available interface impls
*/
@SuppressWarnings("unchecked")
public static synchronized <T> List<T> getImplementations(Class<? extends T> theClazz) {
if (interfaceImplementations.containsKey(theClazz)) {
return (List<T>) interfaceImplementations.get(theClazz);
}
ServiceLoader<? extends T> l = ServiceLoader.load(theClazz);
List<T> result = new ArrayList<>();
for (T t : l) {
result.add(t);
}
interfaceImplementations.put(theClazz, (List<Object>) result);
logger.info(String.format("Implementations for %s: %s",theClazz, result));
logger.info(String.format("Default Implementations for %s: %s",theClazz, result.get(0)));
return result;
}
/**
* @param theClazz the interface class
* @return the first found interface impl
*/
public static synchronized <T> T getImplementation(Class<? extends T> theClazz) {
List<T> result = getImplementations(theClazz);
if (result != null && !result.isEmpty()) {
return result.get(0);
}
return null;
}
/**
* goes through all interface impls created with
* {@link #getImplementation(Class)} or
* {@link #getImplementations(Class)}, checks
* if they extends {@link Disposable}. If so, the instances
* are closed via {@link Disposable#shutdown()}.
*/
public static synchronized void shutdownDisposables() {
for (Class<?> c : interfaceImplementations.keySet()) {
if (Disposable.class.isAssignableFrom(c)) {
List<Object> list = interfaceImplementations.get(c);
for (Object object : list) {
try {
((Disposable) object).shutdown();
}
catch (RuntimeException e) {
logger.warn(e.getMessage(), e);
}
}
}
}
}
}