-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Put DefaultPicoRegistry in it's own class. Added cache for class lookup.
- Loading branch information
Showing
2 changed files
with
87 additions
and
70 deletions.
There are no files selected for viewing
86 changes: 86 additions & 0 deletions
86
src/main/java/de/adito/picoservice/DefaultPicoRegistry.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package de.adito.picoservice; | ||
|
||
import javax.annotation.Nonnull; | ||
import java.lang.annotation.Annotation; | ||
import java.util.*; | ||
import java.util.function.Function; | ||
import java.util.stream.Stream; | ||
|
||
/** | ||
* @author j.boesl, 21.04.17 | ||
*/ | ||
public class DefaultPicoRegistry implements IPicoRegistry | ||
{ | ||
|
||
private final Collection<IPicoRegistration> loadedServices; | ||
private final Map<Class<?>, Collection<Class<?>>> searchedTypeToAnnotatedClassesMap; | ||
|
||
|
||
protected DefaultPicoRegistry() | ||
{ | ||
loadedServices = _loadServices(); | ||
searchedTypeToAnnotatedClassesMap = new HashMap<>(); | ||
} | ||
|
||
@Nonnull | ||
@Override | ||
public <C, A extends Annotation> Map<Class<? extends C>, A> find(@Nonnull Class<C> pSearchedType, | ||
@Nonnull Class<A> pAnnotationClass) | ||
{ | ||
Map<Class<? extends C>, A> map = new HashMap<>(); | ||
for (Class<? extends C> cls : _getSearchedTypes(pSearchedType)) { | ||
A annotation = cls.getAnnotation(pAnnotationClass); | ||
if (annotation != null) | ||
map.put(cls, annotation); | ||
} | ||
return map; | ||
} | ||
|
||
@Nonnull | ||
@Override | ||
public <T, C> Stream<T> find(@Nonnull Class<C> pSearchedType, | ||
@Nonnull Function<Class<? extends C>, T> pResolverFunction) | ||
{ | ||
Collection<Class<? extends C>> searchedTypes = _getSearchedTypes(pSearchedType); | ||
return searchedTypes.stream() | ||
.map(pResolverFunction) | ||
.filter(Objects::nonNull); | ||
} | ||
|
||
@SuppressWarnings("unchecked") | ||
private <T> Collection<Class<? extends T>> _getSearchedTypes(Class<T> pSearchedType) | ||
{ | ||
return (Collection) searchedTypeToAnnotatedClassesMap.computeIfAbsent(pSearchedType, searchedType -> { | ||
ArrayList<Class<? extends T>> st = new ArrayList<>(); | ||
for (IPicoRegistration registration : loadedServices) { | ||
Class<?> annotatedClass = registration.getAnnotatedClass(); | ||
if (searchedType.isAssignableFrom(annotatedClass)) | ||
st.add((Class<? extends T>) annotatedClass); | ||
} | ||
if (st.isEmpty()) | ||
return Collections.emptySet(); | ||
st.trimToSize(); | ||
return Collections.unmodifiableCollection(st); | ||
}); | ||
} | ||
|
||
/** | ||
* We have to load all of our PicoServices into a separate collection, because | ||
* the Java-ServiceLoader throws a ConcurrentModificationException if >1 iterators | ||
* are iterated at the same time. | ||
* Reloading of cached Registrations is currently not supported yet. | ||
* | ||
* @see <a href="https://anydoby.com/jblog/en/java/2128">https://anydoby.com/jblog/en/java/2128</a> | ||
* @see <a href="https://issues.apache.org/jira/browse/SIS-193">https://issues.apache.org/jira/browse/SIS-193</a> | ||
*/ | ||
@Nonnull | ||
private Collection<IPicoRegistration> _loadServices() | ||
{ | ||
ServiceLoader<IPicoRegistration> serviceLoader = ServiceLoader.load(IPicoRegistration.class); | ||
Set<IPicoRegistration> foundServices = new HashSet<>(); | ||
for (IPicoRegistration registration : serviceLoader) | ||
foundServices.add(registration); | ||
return Collections.unmodifiableSet(foundServices); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters