Skip to content

Commit

Permalink
ValueTransformer#isApplicable and minor code rearrangements
Browse files Browse the repository at this point in the history
  • Loading branch information
ibessonov committed Aug 15, 2018
1 parent 96fbe06 commit 44ed803
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 22 deletions.
3 changes: 3 additions & 0 deletions src/main/java/com/github/ibessonov/cdi/Registrar.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package com.github.ibessonov.cdi;

import com.github.ibessonov.cdi.annotations.MethodTransformer;
import com.github.ibessonov.cdi.annotations.ValueTransformer;

import java.lang.annotation.Annotation;

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.github.ibessonov.cdi;
package com.github.ibessonov.cdi.annotations;

import java.lang.annotation.Annotation;
import java.lang.invoke.MethodHandle;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.github.ibessonov.cdi;
package com.github.ibessonov.cdi.annotations;

import java.lang.annotation.Annotation;

Expand All @@ -9,4 +9,8 @@
public interface ValueTransformer<T extends Annotation> {

Object transform(T annotation, Class<?> clazz, Object object);

default boolean isApplicable(Class<?> clazz) {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ public CdiException(CdiErrorType type, Object... args) {
this.type = type;
}

public CdiException(String message) {
super(message);
this.type = null;
}

public CdiErrorType getType() {
return type;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.github.ibessonov.cdi.runtime;

import com.github.ibessonov.cdi.MethodTransformer;
import com.github.ibessonov.cdi.ValueTransformer;
import com.github.ibessonov.cdi.annotations.MethodTransformer;
import com.github.ibessonov.cdi.annotations.ValueTransformer;
import com.github.ibessonov.cdi.exceptions.ImpossibleError;
import com.github.ibessonov.cdi.internal.$Context;

Expand Down
32 changes: 25 additions & 7 deletions src/main/java/com/github/ibessonov/cdi/runtime/ContextImpl.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package com.github.ibessonov.cdi.runtime;

import com.github.ibessonov.cdi.*;
import com.github.ibessonov.cdi.Extension;
import com.github.ibessonov.cdi.Provider;
import com.github.ibessonov.cdi.Registrar;
import com.github.ibessonov.cdi.annotations.MethodTransformer;
import com.github.ibessonov.cdi.annotations.ValueTransformer;
import com.github.ibessonov.cdi.exceptions.CdiException;
import com.github.ibessonov.cdi.exceptions.ImpossibleError;
import com.github.ibessonov.cdi.internal.$CdiObject;
Expand Down Expand Up @@ -32,8 +36,8 @@ public final class ContextImpl implements $Context {
private static final AtomicInteger counter = new AtomicInteger();
private static final Map<String, WeakReference<ContextImpl>> contexts = new ConcurrentHashMap<>();

final Map<Class, ArrayList<ValueTransformer>> valueTransformers = new HashMap<>();
final Map<Class, ArrayList<MethodTransformer>> methodTransformers = new HashMap<>();
final Map<Class, ArrayList<ValueTransformer<?>>> valueTransformers = new HashMap<>();
final Map<Class, ArrayList<MethodTransformer<?>>> methodTransformers = new HashMap<>();
final Map<Class, Provider> providers = new HashMap<>();
final String contextId = Integer.toString(counter.getAndIncrement());
final InheritorGenerator generator;
Expand All @@ -45,10 +49,10 @@ public ContextImpl(Extension... extensions) {
extension.register(registrar);
}
// reduce memory consumption
for (ArrayList<ValueTransformer> list : valueTransformers.values()) {
for (ArrayList<ValueTransformer<?>> list : valueTransformers.values()) {
list.trimToSize();
}
for (ArrayList<MethodTransformer> list : methodTransformers.values()) {
for (ArrayList<MethodTransformer<?>> list : methodTransformers.values()) {
list.trimToSize();
}
}
Expand Down Expand Up @@ -105,9 +109,23 @@ public boolean valueTransformerRegistered(Class<?> clazz) {
return valueTransformers.containsKey(clazz);
}

public void assertValueCanBeTransformed(Class<? extends Annotation> clazz, Class<?> parameterType) throws CdiException {
ArrayList<ValueTransformer<?>> valueTransformers = this.valueTransformers.get(clazz);
if (valueTransformers != null) {
for (ValueTransformer<?> transformer : valueTransformers) {
if (!transformer.isApplicable(parameterType)) {
String message = "ValueTransformer '" + transformer + "'"
+ " for annotation '" + clazz.getSimpleName() + "'"
+ " cannot be applied to type '" + parameterType.getSimpleName() + "'";
throw new CdiException(message);
}
}
}
}

@SuppressWarnings("unchecked")
public <T extends Annotation> ValueTransformer<T> getValueTransformer(Class<T> clazz) {
ArrayList<ValueTransformer> list = this.valueTransformers.get(clazz);
List<? extends ValueTransformer<T>> list = (List<? extends ValueTransformer<T>>) valueTransformers.get(clazz);
if (list == null) return null;
if (list.size() == 1) {
return list.get(0);
Expand All @@ -127,7 +145,7 @@ public boolean methodTransformerRegistered(Class<?> clazz) {

@SuppressWarnings("unchecked")
public <T extends Annotation> MethodTransformer<T> getMethodTransformer(Class<T> clazz) {
ArrayList<MethodTransformer> list = this.methodTransformers.get(clazz);
List<? extends MethodTransformer<T>> list = (List<? extends MethodTransformer<T>>) methodTransformers.get(clazz);
if (list == null) return null;
if (list.size() == 1) {
return list.get(0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ public ClassInfo getClassInfo(Class<?> clazz) {
private StMethod generateTransformedMethod(ClassInfo ci, Method method, StExpression methodBody) {
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
Type[] genericParameterTypes = method.getGenericParameterTypes();
Class<?>[] parameterTypes = method.getParameterTypes();
List<StStatement> statements = new ArrayList<>();
boolean override = false;
for (int i = 0, parametersCount = parameterAnnotations.length; i < parametersCount; i++) {
Expand All @@ -211,6 +212,7 @@ private StMethod generateTransformedMethod(ClassInfo ci, Method method, StExpres
statements.add(_assignMethodParam(i, getLookupExpression(ci, genericParameterTypes[i])));
override = true;
}
context.assertValueCanBeTransformed(parameterAnnotation.annotationType(), parameterTypes[i]);
if (!override && context.valueTransformerRegistered(parameterAnnotation.annotationType())) {
override = true;
}
Expand Down
31 changes: 20 additions & 11 deletions src/test/java/com/github/ibessonov/cdi/ContextTest.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package com.github.ibessonov.cdi;

import com.github.ibessonov.cdi.annotations.Inject;
import com.github.ibessonov.cdi.annotations.NotNull;
import com.github.ibessonov.cdi.annotations.Scoped;
import com.github.ibessonov.cdi.annotations.Trimmed;
import com.github.ibessonov.cdi.annotations.*;
import com.github.ibessonov.cdi.exceptions.CdiException;
import com.github.ibessonov.cdi.internal.$CdiObject;
import com.github.ibessonov.cdi.internal.$Descriptor;
Expand Down Expand Up @@ -65,14 +62,26 @@ public static class TestExtension implements Extension {

@Override
public void register(Registrar registrar) {
registrar.registerValueTransformer(NotNull.class, (annotation, clazz, object) ->
Objects.requireNonNull(object, annotation.value())
);
registrar.registerValueTransformer(Trimmed.class, (annotation, clazz, object) -> {
if (String.class == clazz) {
registrar.registerValueTransformer(NotNull.class, new ValueTransformer<NotNull>() {
@Override
public Object transform(NotNull annotation, Class<?> clazz, Object object) {
return Objects.requireNonNull(object, annotation.value());
}

@Override
public boolean isApplicable(Class<?> clazz) {
return !clazz.isPrimitive();
}
});
registrar.registerValueTransformer(Trimmed.class, new ValueTransformer<Trimmed>() {
@Override
public Object transform(Trimmed annotation, Class<?> clazz, Object object) {
return ((String) object).trim();
} else {
throw new IllegalArgumentException(clazz.getName());
}

@Override
public boolean isApplicable(Class<?> clazz) {
return clazz == String.class;
}
});
registrar.registerMethodTransformer(Traced.class, (annotation, method, handle) -> {
Expand Down

0 comments on commit 44ed803

Please sign in to comment.