Skip to content

Commit

Permalink
Minor code householding (use Java 8 features)
Browse files Browse the repository at this point in the history
  • Loading branch information
ljacqu committed Jun 10, 2017
1 parent fa2fd87 commit 349c59a
Show file tree
Hide file tree
Showing 10 changed files with 50 additions and 59 deletions.
60 changes: 31 additions & 29 deletions src/main/java/ch/jalu/injector/InjectorBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

/**
* Configures and creates an {@link Injector}.
Expand Down Expand Up @@ -115,20 +116,14 @@ public InjectorBuilder addHandlers(Handler... handlers) {
* @since 0.1
*/
public InjectorBuilder addHandlers(Iterable<? extends Handler> handlers) {
HandlerCollector collector = new HandlerCollector(
AnnotationValueHandler.class, ProviderHandler.class, PreConstructHandler.class, InstantiationProvider.class,
DependencyHandler.class, PostConstructHandler.class);

for (Handler handler : handlers) {
collector.process(handler);
}

config.addAnnotationValueHandlers(collector.getList(AnnotationValueHandler.class));
config.addProviderHandlers(collector.getList(ProviderHandler.class));
config.addPreConstructHandlers(collector.getList(PreConstructHandler.class));
config.addInstantiationProviders(collector.getList(InstantiationProvider.class));
config.addDependencyHandlers(collector.getList(DependencyHandler.class));
config.addPostConstructHandlers(collector.getList(PostConstructHandler.class));
new HandlerCollector()
.registerType(AnnotationValueHandler.class, config::addAnnotationValueHandlers)
.registerType(ProviderHandler.class, config::addProviderHandlers)
.registerType(PreConstructHandler.class, config::addPreConstructHandlers)
.registerType(InstantiationProvider.class, config::addInstantiationProviders)
.registerType(DependencyHandler.class, config::addDependencyHandlers)
.registerType(PostConstructHandler.class, config::addPostConstructHandlers)
.process(handlers);
return this;
}

Expand All @@ -145,20 +140,31 @@ public Injector create() {
@SuppressWarnings("unchecked")
private static final class HandlerCollector {

private final Map<Class<? extends Handler>, List<? extends Handler>> handlersByType = new HashMap<>();
private final Class<? extends Handler>[] subtypes;
private final Map<Class, List> handlersByType = new HashMap<>();
private final Map<Class, Consumer<List>> handlerListSetters = new HashMap<>();

@SafeVarargs
HandlerCollector(Class<? extends Handler>... subtypes) {
this.subtypes = subtypes;
for (Class<? extends Handler> subtype : subtypes) {
handlersByType.put(subtype, new ArrayList<Handler>());
<T extends Handler> HandlerCollector registerType(Class<T> subType, Consumer<List<T>> handlerListSetter) {
if (handlersByType.containsKey(subType)) {
throw new IllegalStateException("Already provided " + subType);
}
handlersByType.put(subType, new ArrayList<>());
handlerListSetters.put(subType, (Consumer) handlerListSetter);
return this;
}

void process(Handler handler) {
void process(Iterable<? extends Handler> handlers) {
for (Handler handler : handlers) {
process(handler);
}
for (Map.Entry<Class, Consumer<List>> listSetter : handlerListSetters.entrySet()) {
listSetter.getValue().accept(
handlersByType.get(listSetter.getKey()));
}
}

private void process(Handler handler) {
boolean foundSubtype = false;
for (Class<? extends Handler> subtype : subtypes) {
for (Class subtype : handlersByType.keySet()) {
foundSubtype |= addHandler(subtype, handler);
}
if (!foundSubtype) {
Expand All @@ -167,13 +173,9 @@ void process(Handler handler) {
}
}

<T extends Handler> List<T> getList(Class<T> clazz) {
return (List<T>) handlersByType.get(clazz);
}

private <T extends Handler> boolean addHandler(Class<T> clazz, Handler handler) {
private boolean addHandler(Class clazz, Handler handler) {
if (clazz.isInstance(handler)) {
getList(clazz).add((T) handler);
handlersByType.get(clazz).add(handler);
return true;
}
return false;
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/ch/jalu/injector/InjectorImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ protected InjectorImpl(InjectorConfig config) {

@Override
public <T> T getSingleton(Class<T> clazz) {
return get(clazz, new HashSet<Class<?>>());
return get(clazz, new HashSet<>());
}

@Override
Expand Down Expand Up @@ -81,7 +81,7 @@ public void provide(Class<? extends Annotation> clazz, Object object) {
public <T> T newInstance(Class<T> clazz) {
return instantiate(
new UnresolvedInstantiationContext<>(this, REQUEST_SCOPED, clazz),
new HashSet<Class<?>>());
new HashSet<>());
}

@Override
Expand All @@ -93,7 +93,7 @@ public <T> T getIfAvailable(Class<T> clazz) {
public <T> T createIfHasDependencies(Class<T> clazz) {
return instantiate(
new UnresolvedInstantiationContext<>(this, REQUEST_SCOPED_IF_HAS_DEPENDENCIES, clazz),
new HashSet<Class<?>>());
new HashSet<>());
}

@Override
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/ch/jalu/injector/context/ResolutionType.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

/**
* Resolution type: defines what scope / context an object should be retrieved or instantiated.
*
* @see StandardResolutionType for standard types supported by the injector
*/
public interface ResolutionType {
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public AllInstancesAnnotationHandler(String rootPackage) {
}

@Override
public Class<AllInstances> getAnnotationType() {
protected Class<AllInstances> getAnnotationType() {
return AllInstances.class;
}

Expand All @@ -38,17 +38,16 @@ public Object resolveValueSafely(ResolvedInstantiationContext<?> context, AllIns
// The raw type, e.g. List or array
final Class<?> rawType = dependencyDescription.getTypeAsClass();
// The type of the collection, e.g. String for List<String> or String[]
final Class<?> genericType = ReflectionUtils.getCollectionType(rawType, dependencyDescription.getType());
final Class genericType = ReflectionUtils.getCollectionType(rawType, dependencyDescription.getType());

if (genericType == null) {
throw new InjectorException("Unsupported dependency of type '" + rawType
+ "' annotated with @AllInstances. (Or did you forget the generic type?)");
}

// TODO: Implement detection of cyclic dependencies
// Eclipse complains about Set<Class<? extends ?>>, so we need to cast it to Object first. Should be safe.
@SuppressWarnings("unchecked")
Set<Class<?>> subTypes = (Set<Class<?>>) (Object) reflections.getSubTypesOf(genericType);
Set<Class<?>> subTypes = reflections.getSubTypesOf(genericType);
Set<Object> instances = new HashSet<>(subTypes.size());

final Injector injector = context.getInjector();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public AllTypesAnnotationHandler(String rootPackage) {
}

@Override
public Class<AllTypes> getAnnotationType() {
protected Class<AllTypes> getAnnotationType() {
return AllTypes.class;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/
public class InstantiationCache implements InstantiationProvider, PostConstructHandler {

protected Map<String, WeakReference<Instantiation<?>>> entries = new ConcurrentHashMap<>();
protected Map<String, WeakReference<Instantiation>> entries = new ConcurrentHashMap<>();

@Override
public <T> Instantiation<? extends T> get(UnresolvedInstantiationContext<T> context) {
Expand All @@ -29,16 +29,16 @@ public <T> Instantiation<? extends T> get(UnresolvedInstantiationContext<T> cont
public <T> T process(T object, ResolvedInstantiationContext<T> context) throws Exception {
if (shouldCacheMethod(context) && getInstantiation(context) == null) {
entries.put(context.getMappedClass().getCanonicalName(),
new WeakReference<Instantiation<?>>(context.getInstantiation()));
new WeakReference<>(context.getInstantiation()));
}
return null;
}

@Nullable
@SuppressWarnings("unchecked")
private <T> Instantiation<? extends T> getInstantiation(InstantiationContext<T> context) {
WeakReference<Instantiation<?>> instantiation = entries.get(context.getMappedClass().getCanonicalName());
return instantiation == null ? null : (Instantiation) instantiation.get();
WeakReference<Instantiation> instantiation = entries.get(context.getMappedClass().getCanonicalName());
return instantiation == null ? null : instantiation.get();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,8 @@ public Object resolveValue(ResolvedInstantiationContext<?> context, DependencyDe
return null;
}

private static <T> Provider<T> constructStandardProvider(final Class<T> genericType, final Injector injector) {
return new Provider<T>() {
@Override
public T get() {
return injector.newInstance(genericType);
}
};
private static <T> Provider<T> constructStandardProvider(Class<T> genericType, Injector injector) {
return () -> injector.newInstance(genericType);
}

private <T> void saveConstructedProvider(Class<T> clazz, Provider<? extends T> provider) {
Expand Down
11 changes: 2 additions & 9 deletions src/test/java/ch/jalu/injector/InjectorImplTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@
import ch.jalu.injector.samples.GammaService;
import ch.jalu.injector.samples.InstantiationFallbackClasses;
import ch.jalu.injector.samples.InvalidClass;
import ch.jalu.injector.samples.StaticFieldInjection;
import ch.jalu.injector.samples.ProvidedClass;
import ch.jalu.injector.samples.Reloadable;
import ch.jalu.injector.samples.SampleInstantiationImpl;
import ch.jalu.injector.samples.Size;
import ch.jalu.injector.samples.StaticFieldInjection;
import ch.jalu.injector.samples.inheritance.Child;
import org.junit.Before;
import org.junit.Rule;
Expand All @@ -32,7 +32,6 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import static org.hamcrest.Matchers.empty;
Expand Down Expand Up @@ -442,13 +441,7 @@ public void shouldInstantiateClassWithInheritedInjects() {

private static List<Handler> getAllHandlersExceptInstantiationProviders() {
List<Handler> handlers = InjectorBuilder.createDefaultHandlers("");
Iterator<Handler> iterator = handlers.iterator();
while (iterator.hasNext()) {
Handler next = iterator.next();
if (next instanceof InstantiationProvider) {
iterator.remove();
}
}
handlers.removeIf(next -> next instanceof InstantiationProvider);
return handlers;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,6 @@ public void shouldSetUpProperly() {
assertThat(sampleInjectClass.getStringField(), equalTo(name));
assertThat(sampleInjectClass.getAlphaService().getProvidedClass(), sameInstance(providedClass));
assertThat(sampleInjectClass.getProvidedClass(), sameInstance(providedClass));
assertThat((GammaService) betaManager.getDependencies()[1], sameInstance(gammaService));
assertThat(betaManager.getDependencies()[1], sameInstance(gammaService));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public void shouldGetFieldValue() {
Object result = ReflectionUtils.getFieldValue(field, testClass);

// then
assertThat(result, equalTo((Object) str));
assertThat(result, equalTo(str));
}

@Test(expected = IllegalArgumentException.class)
Expand Down

0 comments on commit 349c59a

Please sign in to comment.