/* * 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); } } }