-
Notifications
You must be signed in to change notification settings - Fork 173
/
ActorClassFinder.java
116 lines (101 loc) · 3.78 KB
/
ActorClassFinder.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package com.ea.orbit.actors.runtime;
import com.ea.orbit.actors.IActor;
import com.ea.orbit.actors.providers.IActorClassFinder;
import com.ea.orbit.concurrent.Task;
import com.ea.orbit.exception.UncheckedException;
import com.ea.orbit.util.ClassPath;
import com.ea.orbit.util.IOUtils;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
public class ActorClassFinder implements IActorClassFinder
{
private static final ClassPathSearch search = new ClassPathSearch(IActor.class);
private ConcurrentHashMap<Class<?>, Class<?>> cache = new ConcurrentHashMap<>();
private Execution execution;
public ActorClassFinder(Execution execution)
{
this.execution = execution;
}
public ActorClassFinder()
{
}
@Override
public <T extends IActor> Class<? extends T> findActorImplementation(Class<T> iActorInterface)
{
Class<?> r = cache.get(iActorInterface);
return r != null ? (Class<? extends T>) r : search.findImplementation(iActorInterface);
}
@Override
public Task<?> start()
{
if (execution == null)
{
return Task.done();
}
try
{
if (execution.getAutoDiscovery())
{
final List<ClassPath.ResourceInfo> actorInterfacesRes = ClassPath.get().getAllResources().stream()
.filter(r -> r.getResourceName().startsWith("META-INF/orbit/actors/interfaces")).collect(Collectors.toList());
final List<ClassPath.ResourceInfo> actorClassesRes = ClassPath.get().getAllResources().stream()
.filter(r -> r.getResourceName().startsWith("META-INF/orbit/actors/classes")).collect(Collectors.toList());
for (ClassPath.ResourceInfo irs : actorInterfacesRes)
{
// pre register factories
String nameFactoryName = IOUtils.toString(irs.url().openStream());
ActorFactory<?> factory = (ActorFactory<?>) classForName(nameFactoryName).newInstance();
execution.registerFactory(factory);
}
for (ClassPath.ResourceInfo irs : actorClassesRes)
{
String className = irs.getResourceName().substring("META-INF/orbit/actors/classes".length() + 1);
Class<?> actorClass = classForName(className);
cacheBestInterface(actorClass);
}
}
List<Class<?>> actorClasses = execution.getActorClasses();
if (actorClasses != null && !actorClasses.isEmpty())
{
for (Class<?> actorClass : actorClasses)
{
cacheBestInterface(actorClass);
}
}
}
catch (Throwable e)
{
throw new UncheckedException(e);
}
return Task.done();
}
private void cacheBestInterface(Class<?> actorClass)
{
Class<?> bestInterface = null;
for (Class<?> interfaceClass : actorClass.getInterfaces())
{
if (IActor.class.isAssignableFrom(interfaceClass) && interfaceClass != IActor.class)
{
bestInterface = (bestInterface == null) ? interfaceClass
: bestInterface.isAssignableFrom(interfaceClass) ? interfaceClass
: bestInterface;
}
}
if (bestInterface != null)
{
cache.put(actorClass, bestInterface);
}
}
private Class<?> classForName(String className)
{
try
{
return Class.forName(className);
}
catch (ClassNotFoundException e)
{
throw new UncheckedException(e);
}
}
}