package eu.dnetlib.enabling.tools;

import java.util.Collection;

/**
 * This class allows chaining several service locators and return the first one matching. Usually this is usefully when
 * we want a StaticLocator as a fallback if the DynamicLocator cannot find anything.
 * 
 * @author marko
 * 
 * @param <T>
 *            service type
 */
public class ServiceLocatorChain<T> implements ServiceLocator<T> {

	/**
	 * service locators, iterated in order.
	 */
	private Collection<ServiceLocator<T>> locators;

	/**
	 * {@inheritDoc}
	 * 
	 * @see eu.dnetlib.enabling.tools.ServiceLocator#getService()
	 */
	@Override
	public T getService() {
		IllegalStateException lastException = null; // NOPMD

		for (ServiceLocator<T> locator : locators) {
			try {
				return locator.getService();
			} catch (IllegalStateException e) {
				lastException = e;
			}
		}
		if (lastException != null)
			throw new IllegalStateException("cannot find any matching service. Last locator in the chain reported as cause", lastException);
		throw new IllegalStateException("cannot find any matching service: the service locator chain is empty");
	}

	public Collection<ServiceLocator<T>> getLocators() {
		return locators;
	}

	public void setLocators(final Collection<ServiceLocator<T>> locators) {
		this.locators = locators;
	}

}
