/*
* Copyright (C) 2006-2016 DLR, Germany
*
* All rights reserved
*
* http://www.rcenvironment.de/
*/
package de.rcenvironment.core.toolkitbridge.api;
import org.apache.commons.logging.LogFactory;
import de.rcenvironment.core.toolkitbridge.internal.DefaultToolkitConfiguration;
import de.rcenvironment.toolkit.core.api.Toolkit;
import de.rcenvironment.toolkit.core.api.ToolkitException;
import de.rcenvironment.toolkit.core.setup.ToolkitFactory;
/**
* @author Robert Mischke
*/
public final class StaticToolkitHolder {
private static Toolkit instance; // access synchronized via "sharedInstanceLock"
private static final Object sharedInstanceLock = StaticToolkitHolder.class;
private StaticToolkitHolder() {}
private static Toolkit getInstance() {
synchronized (sharedInstanceLock) {
if (instance == null) {
throw new IllegalStateException(
"No toolkit instance available - most likely, the code tried to access a service before the toolkit "
+ "was initialized or after it has been shut down");
}
return instance;
}
}
/**
* Injects a {@link Toolkit} instance. If there already is an instance, an exception is thrown. Setting "null" is allowed to remove an
* existing instance.
*
* @param newinstance the new instance to set, or null to remove any existing instance
*/
public static void setInstance(Toolkit newinstance) {
synchronized (sharedInstanceLock) {
if (newinstance != null && instance != null) {
throw new IllegalStateException("Duplicate toolkit initialization");
}
instance = newinstance;
}
}
/**
* @param <T> the interface class of the requested service
* @param serviceClass the interface class of the requested service
* @return the service instance for the given interface; if no such service exists, an {@link IllegalStateException} is thrown
*/
public static <T> T getService(Class<T> serviceClass) {
T service = getInstance().getServiceRegistry().getService(serviceClass);
if (service == null) {
throw new IllegalStateException("The registered toolkit does not contain a service for interface " + serviceClass);
}
return service;
}
/**
* A variant of {@link #getService(Class)} that allows explicit fallback handling in contexts where no toolkit is available (e.g. static
* delegate classes being used by unit tests).
*
* @param <T> the interface class of the requested service
* @param serviceClass the interface class of the requested service
* @return the service instance for the given interface; if no toolkit is available, this method returns null; it a toolkit is
* available, but no such service exists, an {@link IllegalStateException} is thrown
*/
public static <T> T getServiceIfInitialized(Class<T> serviceClass) {
synchronized (sharedInstanceLock) {
if (instance != null) {
return getService(serviceClass);
} else {
return null;
}
}
}
/**
* A variant of {@link #getService(Class)} that creates an implicit {@link Toolkit} instance if none has been initialized before.
*
* @param <T> the interface class of the requested service
* @param serviceClass the interface class of the requested service
* @return the service instance for the given interface; if no such service exists, an {@link IllegalStateException} is thrown
*/
public static <T> T getServiceWithUnitTestFallback(Class<T> serviceClass) {
synchronized (sharedInstanceLock) {
if (instance == null) {
instance = createImplicitToolkit();
}
}
return getService(serviceClass);
}
private static Toolkit createImplicitToolkit() {
LogFactory.getLog(StaticToolkitHolder.class).info("Creating an implicit toolkit instance (usually as part of a unit test)");
try {
return ToolkitFactory.create(new DefaultToolkitConfiguration());
} catch (ToolkitException e) {
throw new IllegalStateException("Error creating implicit toolkit instance", e);
}
}
}