
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 extends T> implementationType = (Class extends T>) 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 extends T> 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 extends T> loadAsFQCN(final String name) throws ClassNotFoundException
{
return (Class extends T>) Thread.currentThread().getContextClassLoader().loadClass(name);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy