All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.peachjean.commons.base.service.ServiceLoader Maven / Gradle / Ivy

The newest version!
package net.peachjean.commons.base.service;

import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;

import com.google.common.base.Charsets;
import com.google.common.base.Throwables;
import com.google.common.collect.Maps;
import com.google.common.io.Resources;

/**
 * Utility used by generated {service}Factory classes.
 * @param 
 */
public class ServiceLoader
{
	private Class serviceType;
	private Map> nameMap;

	public ServiceLoader(final Class serviceType)
	{
		this.serviceType = serviceType;
		this.nameMap = loadNameMap(serviceType);
	}

	private static  Map> loadNameMap(final Class serviceType)
	{
		final ConcurrentMap> nameMap = Maps.newConcurrentMap();

		try
		{
			final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
			Enumeration serviceDescriptors = classLoader.getResources(serviceType.getName());
			while(serviceDescriptors.hasMoreElements())
			{
				for(String line: Resources.readLines(serviceDescriptors.nextElement(), Charsets.UTF_8))
				{
					Class implementationType = (Class) classLoader.loadClass(line);
					if(!serviceType.isAssignableFrom(implementationType))
					{
						throw new ServiceLookupException(serviceType, implementationType);
					}
					if(implementationType.isAnnotationPresent(ServiceName.class))
					{
						nameMap.put(implementationType.getAnnotation(ServiceName.class).value(), implementationType);
					}
					nameMap.put(implementationType.getName(), implementationType);
				}
			}
		}
		catch (IOException e)
		{
			throw Throwables.propagate(e);
		}
		catch (ClassNotFoundException e)
		{
			throw Throwables.propagate(e);
		}

		return nameMap;
	}

	public ServiceImplementation lookup(String name) throws ServiceLookupException
	{
		if(nameMap.containsKey(name))
		{
			return new ServiceImplementation(serviceType, nameMap.get(name));
		}
		else
		{
			try
			{
				Class fqcn = loadAsFQCN(name);
				if(!serviceType.isAssignableFrom(fqcn))
				{
					throw new ServiceLookupException(serviceType, fqcn);
				}
				nameMap.put(name, fqcn);
				return new ServiceImplementation(serviceType, fqcn);
			}
			catch (ClassNotFoundException e)
			{
				throw new ServiceLookupException(serviceType, name);
			}
		}
	}

	@SuppressWarnings({"unchecked"})
	private Class loadAsFQCN(final String name) throws ClassNotFoundException
	{
		return (Class) Thread.currentThread().getContextClassLoader().loadClass(name);
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy