Skip to content

Instantly share code, notes, and snippets.

@johnou
Created June 23, 2016 14:09
Show Gist options
  • Save johnou/03c3677cd72f40d3778ea1f7b39df9d3 to your computer and use it in GitHub Desktop.
Save johnou/03c3677cd72f40d3778ea1f7b39df9d3 to your computer and use it in GitHub Desktop.
SpringActorClassFinder entire classpath
import cloud.orbit.actors.Actor;
import cloud.orbit.actors.Remindable;
import cloud.orbit.actors.extensions.ActorClassFinder;
import cloud.orbit.actors.runtime.ReminderController;
import cloud.orbit.actors.runtime.ReminderControllerActor;
import cloud.orbit.actors.streams.simple.SimpleStream;
import cloud.orbit.actors.streams.simple.SimpleStreamActor;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.AssignableTypeFilter;
import org.springframework.stereotype.Component;
import org.springframework.util.ClassUtils;
import javax.annotation.PostConstruct;
import java.util.*;
import java.util.function.Predicate;
/**
* {@link SpringActorClassFinder} uses Spring utility classes to locate actor implementations.
*
* @author Johno Crawford (johno@sulake.com)
*/
@Component
public class SpringActorClassFinder implements ActorClassFinder {
private static final Logger logger = Logger.getLogger(SpringActorClassFinder.class);
@Autowired
private ActorImplementationProvider actorImplementationProvider;
private Map<Class<?>, Class<?>> concreteImplementations = new HashMap<>();
@PostConstruct
public void initialize() {
long start = System.currentTimeMillis();
Map<Class<?>, Class<?>> implementations = actorImplementationProvider.getActorImplementations();
logger.info("Took " + (System.currentTimeMillis() - start) + "ms to scan for Actor implementations.");
implementations.put(ReminderController.class, ReminderControllerActor.class); // built in Orbit actor
implementations.put(SimpleStream.class, SimpleStreamActor.class); // built in Orbit actor
this.concreteImplementations = implementations;
}
@Override
@SuppressWarnings("unchecked")
public <T extends Actor> Class<? extends T> findActorImplementation(Class<T> clazz) {
return (Class<T>) concreteImplementations.get(clazz);
}
@Override
public <T extends Actor> Collection<Class<? extends T>> findActorInterfaces(Predicate<Class<T>> predicate) {
List<Class<? extends T>> interfaces = null;
for (Class<?> concreteInterface : concreteImplementations.keySet())
{
if (predicate.test((Class<T>) concreteInterface))
{
if (interfaces == null) {
interfaces = new ArrayList<>();
}
interfaces.add((Class<T>) concreteInterface);
}
}
return interfaces != null ? interfaces : Collections.emptyList();
}
@Component
private class ActorImplementationProvider extends ClassPathScanningCandidateComponentProvider {
@Autowired
public ActorImplementationProvider() {
super(false);
addIncludeFilter(new AssignableTypeFilter(Actor.class));
}
public Map<Class<?>, Class<?>> getActorImplementations() {
List<Class<?>> clazzImplementations = new ArrayList<>();
Map<Class<?>, Class<?>> actorImplementations = new HashMap<>();
for (BeanDefinition candidate : findCandidateComponents("")) {
Class<?> implementation = ClassUtils.resolveClassName(candidate.getBeanClassName(), ClassUtils.getDefaultClassLoader());
clazzImplementations.add(implementation);
}
for (Class<?> clazzImplementation : clazzImplementations) {
Class<?>[] implementationInterfaces = clazzImplementation.getInterfaces(); // check interfaces directly to support inheritance
if (implementationInterfaces.length == 0) {
continue;
}
for (Class<?> implementationInterface : implementationInterfaces) {
if (implementationInterface == Remindable.class) {
continue;
}
if (Actor.class.isAssignableFrom(implementationInterface)) {
Class<?> old = actorImplementations.put(implementationInterface, clazzImplementation);
if (old != null) {
logger.warn("Multiple actor implementations found for " + implementationInterface);
}
}
}
}
return actorImplementations;
}
@Override
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
return beanDefinition.getMetadata().isConcrete();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment