Skip to content

Commit

Permalink
#48 Introduce ObjectIdentifier into the contexts
Browse files Browse the repository at this point in the history
- Create ObjectIdentifier (initial version)
- Shorten context names
- Remove generic info from context
  • Loading branch information
ljacqu committed Jun 17, 2017
1 parent 4c29a38 commit f4f6e0d
Show file tree
Hide file tree
Showing 38 changed files with 321 additions and 298 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package ch.jalu.injector.extras.handlers;

import ch.jalu.injector.Injector;
import ch.jalu.injector.context.ResolvedInstantiationContext;
import ch.jalu.injector.context.ResolvedContext;
import ch.jalu.injector.exceptions.InjectorException;
import ch.jalu.injector.extras.AllInstances;
import ch.jalu.injector.handlers.dependency.TypeSafeAnnotationHandler;
Expand Down Expand Up @@ -34,7 +34,7 @@ protected Class<AllInstances> getAnnotationType() {
}

@Override
public Object resolveValueSafely(ResolvedInstantiationContext<?> context, AllInstances annotation,
public Object resolveValueSafely(ResolvedContext context, AllInstances annotation,
DependencyDescription dependencyDescription) {
// The raw type, e.g. List or array
final Class<?> rawType = dependencyDescription.getTypeAsClass();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package ch.jalu.injector.extras.handlers;

import ch.jalu.injector.context.ResolvedInstantiationContext;
import ch.jalu.injector.context.ResolvedContext;
import ch.jalu.injector.extras.AllTypes;
import ch.jalu.injector.handlers.dependency.TypeSafeAnnotationHandler;
import ch.jalu.injector.handlers.instantiation.DependencyDescription;
Expand Down Expand Up @@ -31,7 +31,7 @@ protected Class<AllTypes> getAnnotationType() {
}

@Override
public Object resolveValueSafely(ResolvedInstantiationContext<?> context, AllTypes annotation,
public Object resolveValueSafely(ResolvedContext context, AllTypes annotation,
DependencyDescription dependencyDescription) {
InjectorUtils.checkNotNull(annotation.value(), "Annotation value may not be null");
Set<?> subTypes = reflections.getSubTypesOf(annotation.value());
Expand Down
46 changes: 23 additions & 23 deletions injector/src/main/java/ch/jalu/injector/InjectorImpl.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package ch.jalu.injector;

import ch.jalu.injector.context.ResolvedInstantiationContext;
import ch.jalu.injector.context.UnresolvedInstantiationContext;
import ch.jalu.injector.context.ObjectIdentifier;
import ch.jalu.injector.context.ResolvedContext;
import ch.jalu.injector.context.UnresolvedContext;
import ch.jalu.injector.exceptions.InjectorException;
import ch.jalu.injector.handlers.Handler;
import ch.jalu.injector.handlers.instantiation.DependencyDescription;
Expand Down Expand Up @@ -74,8 +75,8 @@ public void provide(Class<? extends Annotation> clazz, Object object) {

@Override
public <T> T newInstance(Class<T> clazz) {
return instantiate(
new UnresolvedInstantiationContext<>(this, REQUEST_SCOPED, clazz),
return (T) instantiate(
new UnresolvedContext(this, REQUEST_SCOPED, new ObjectIdentifier(clazz)),
new HashSet<>());
}

Expand All @@ -86,8 +87,8 @@ public <T> T getIfAvailable(Class<T> clazz) {

@Override
public <T> T createIfHasDependencies(Class<T> clazz) {
return instantiate(
new UnresolvedInstantiationContext<>(this, REQUEST_SCOPED_IF_HAS_DEPENDENCIES, clazz),
return (T) instantiate(
new UnresolvedContext(this, REQUEST_SCOPED_IF_HAS_DEPENDENCIES, new ObjectIdentifier(clazz)),
new HashSet<>());
}

Expand Down Expand Up @@ -145,9 +146,9 @@ private <T> T get(Class<T> clazz, Set<Class<?>> traversedClasses) {
return clazz.cast(objects.get(clazz));
}

UnresolvedInstantiationContext<T> context = new UnresolvedInstantiationContext<>(this, SINGLETON, clazz);
UnresolvedContext context = new UnresolvedContext(this, SINGLETON, new ObjectIdentifier(clazz));
// Add the clazz to the list of traversed classes in a new Set, so each path we take has its own Set.
T object = instantiate(context, new HashSet<>(traversedClasses));
T object = (T) instantiate(context, new HashSet<>(traversedClasses));
register(clazz, object);
return object;
}
Expand All @@ -158,22 +159,21 @@ private <T> T get(Class<T> clazz, Set<Class<?>> traversedClasses) {
*
* @param context the instantiation context
* @param traversedClasses collection of classes already traversed
* @param <T> the class' type
* @return the instantiated object, or {@code null} if dependency lookup returned {@code null}
*/
@Nullable
private <T> T instantiate(UnresolvedInstantiationContext<T> context, Set<Class<?>> traversedClasses) {
private Object instantiate(UnresolvedContext context, Set<Class<?>> traversedClasses) {
processPreConstructorHandlers(context);
Instantiation<? extends T> instantiation = getInstantiation(context);
traversedClasses.add(context.getMappedClass());
Instantiation<?> instantiation = getInstantiation(context);
traversedClasses.add(context.getIdentifier().getType());
validateInjectionHasNoCircularDependencies(instantiation.getDependencies(), traversedClasses);

ResolvedInstantiationContext<T> resolvedContext = context.buildResolvedContext(instantiation);
ResolvedContext resolvedContext = context.buildResolvedContext(instantiation);
Object[] dependencies = resolveDependencies(resolvedContext, traversedClasses);
if (dependencies == null) {
return null;
}
T object = instantiation.instantiateWith(dependencies);
Object object = instantiation.instantiateWith(dependencies);
return runPostConstructHandlers(object, resolvedContext);
}

Expand All @@ -188,7 +188,7 @@ private <T> T instantiate(UnresolvedInstantiationContext<T> context, Set<Class<?
* resolution type
*/
@Nullable
private Object[] resolveDependencies(ResolvedInstantiationContext<?> resolvedContext,
private Object[] resolveDependencies(ResolvedContext resolvedContext,
Set<Class<?>> traversedClasses) {
List<? extends DependencyDescription> dependencies = resolvedContext.getInstantiation().getDependencies();
Object[] values = new Object[dependencies.size()];
Expand All @@ -207,9 +207,9 @@ private Object[] resolveDependencies(ResolvedInstantiationContext<?> resolvedCon
return values;
}

private <T> Instantiation<? extends T> getInstantiation(UnresolvedInstantiationContext<T> context) {
private Instantiation<?> getInstantiation(UnresolvedContext context) {
for (Handler handler : config.getHandlers()) {
Instantiation<? extends T> instantiation = handler.get(context);
Instantiation<?> instantiation = handler.get(context);
if (instantiation != null) {
return instantiation;
}
Expand All @@ -220,11 +220,11 @@ private <T> Instantiation<? extends T> getInstantiation(UnresolvedInstantiationC
// if (config.getInstantiationProviders().isEmpty()) {
// throw new InjectorException("You did not register any instantiation methods!");
// } else
if (!InjectorUtils.canInstantiate(context.getMappedClass())) {
throw new InjectorException("Did not find instantiation method for '" + context.getMappedClass()
if (!InjectorUtils.canInstantiate(context.getIdentifier().getType())) {
throw new InjectorException("Did not find instantiation method for '" + context.getIdentifier().getType()
+ "'. This class cannot be instantiated directly, please check the class or your handlers.");
}
throw new InjectorException("Did not find instantiation method for '" + context.getMappedClass()
throw new InjectorException("Did not find instantiation method for '" + context.getIdentifier().getType()
+ "'. Make sure your class conforms to one of the registered instantiations. If default: "
+ "make sure you have a constructor with @Inject or fields with @Inject. Fields with @Inject "
+ "require the default constructor");
Expand All @@ -235,7 +235,7 @@ private <T> Instantiation<? extends T> getInstantiation(UnresolvedInstantiationC
*
* @param unresolvedContext the instantiation context
*/
private void processPreConstructorHandlers(UnresolvedInstantiationContext<?> unresolvedContext) {
private void processPreConstructorHandlers(UnresolvedContext unresolvedContext) {
for (Handler handler : config.getHandlers()) {
try {
handler.preProcess(unresolvedContext);
Expand All @@ -245,7 +245,7 @@ private void processPreConstructorHandlers(UnresolvedInstantiationContext<?> unr
}
}

private <T> T runPostConstructHandlers(T instance, ResolvedInstantiationContext<T> resolvedContext) {
private <T> T runPostConstructHandlers(T instance, ResolvedContext resolvedContext) {
T object = instance;
for (Handler handler : config.getHandlers()) {
try {
Expand All @@ -258,7 +258,7 @@ private <T> T runPostConstructHandlers(T instance, ResolvedInstantiationContext<
}

@Nullable
private Object resolveDependency(ResolvedInstantiationContext<?> resolvedContext,
private Object resolveDependency(ResolvedContext resolvedContext,
DependencyDescription dependencyDescription) {
Object o;
for (Handler handler : config.getHandlers()) {
Expand Down

This file was deleted.

48 changes: 48 additions & 0 deletions injector/src/main/java/ch/jalu/injector/context/ObjectContext.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package ch.jalu.injector.context;

import ch.jalu.injector.Injector;

/**
* Context of instantiation.
*/
public abstract class ObjectContext {

protected final Injector injector;
protected final ResolutionType resolutionType;
protected final ObjectIdentifier originalIdentifier;
protected ObjectIdentifier identifier;

public ObjectContext(Injector injector, ResolutionType resolutionType, ObjectIdentifier objectIdentifier) {
this(injector, resolutionType, objectIdentifier, objectIdentifier);
}

public ObjectContext(Injector injector, ResolutionType resolutionType, ObjectIdentifier originalIdentifier,
ObjectIdentifier identifier) {
this.injector = injector;
this.resolutionType = resolutionType;
this.originalIdentifier = originalIdentifier;
this.identifier = identifier;
}

/**
* @return the injector
*/
public Injector getInjector() {
return injector;
}

/**
* @return the context in which the object should be instantiated
*/
public ResolutionType getResolutionType() {
return resolutionType;
}

public ObjectIdentifier getOriginalIdentifier() {
return originalIdentifier;
}

public ObjectIdentifier getIdentifier() {
return identifier;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package ch.jalu.injector.context;

import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.List;

/**
* Identifies objects.
*/
public class ObjectIdentifier {

private final Class<?> type;
private final List<Annotation> annotations;

public ObjectIdentifier(Class<?> type, Annotation... annotations) {
this.type = type;
this.annotations = Arrays.asList(annotations);
}

public Class<?> getType() {
return type;
}

public List<Annotation> getAnnotations() {
return annotations;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package ch.jalu.injector.context;

import ch.jalu.injector.Injector;
import ch.jalu.injector.handlers.instantiation.Instantiation;

/**
* Instantiation context after the class has been resolved, i.e. it is known what
* instantiation method is used for it.
*/
public class ResolvedContext extends ObjectContext {

private final Instantiation<?> instantiation;

/**
* Constructor.
* <p>
* The type of {@link #identifier} and {@link #instantiation} should be identical.
*
* @param injector the injector
* @param resolutionType the resolution type
* @param originalIdentifier the class that was originally requested
* @param identifier the class that was mapped to be instantiated
* @param instantiation the instantiation method
*/
public ResolvedContext(Injector injector, ResolutionType resolutionType, ObjectIdentifier originalIdentifier,
ObjectIdentifier identifier, Instantiation<?> instantiation) {
super(injector, resolutionType, originalIdentifier, identifier);
this.instantiation = instantiation;
}

/**
* @return the instantiation method with which the object should be created
*/
public Instantiation<?> getInstantiation() {
return instantiation;
}
}

This file was deleted.

Loading

0 comments on commit f4f6e0d

Please sign in to comment.