From 430f62cff674c2ca568c0770ee3055cdbad7a4a0 Mon Sep 17 00:00:00 2001 From: dzikoysk Date: Mon, 23 Mar 2020 14:40:43 +0100 Subject: [PATCH] GH-392 Add example for the DI Wiki post --- .../annotations/adapter/JavassistAdapter.java | 11 ++- .../annotations/adapter/MetadataAdapter.java | 2 +- .../utilities/inject/InjectorAnnotation.java | 11 +++ .../utilities/inject/InjectorResources.java | 6 +- .../inject/DependencyInjectionWikiTest.java | 69 +++++++++++++++++++ 5 files changed, 88 insertions(+), 11 deletions(-) create mode 100644 panda-utilities/src/test/java/org/panda_lang/utilities/inject/DependencyInjectionWikiTest.java diff --git a/panda-utilities/src/main/java/org/panda_lang/utilities/annotations/adapter/JavassistAdapter.java b/panda-utilities/src/main/java/org/panda_lang/utilities/annotations/adapter/JavassistAdapter.java index ae582ef16..90769750b 100644 --- a/panda-utilities/src/main/java/org/panda_lang/utilities/annotations/adapter/JavassistAdapter.java +++ b/panda-utilities/src/main/java/org/panda_lang/utilities/annotations/adapter/JavassistAdapter.java @@ -38,13 +38,15 @@ import java.util.Arrays; import java.util.List; + + public final class JavassistAdapter implements MetadataAdapter { public static final boolean includeInvisibleTag = true; @Override public boolean acceptsInput(String file) { - return file.endsWith(".class"); + return file.endsWith(".class") && !file.contains("module-info.class"); } private List splitDescriptorToTypeNames(String descriptors) { @@ -171,21 +173,16 @@ public String getFieldName(FieldInfo field) { } @Override - public @Nullable ClassFile getOfCreateClassObject(AnnotationsScanner scanner, AnnotationsScannerFile file) { + public ClassFile getOfCreateClassObject(AnnotationsScanner scanner, AnnotationsScannerFile file) throws Exception { InputStream inputStream = null; try { inputStream = file.openInputStream(); DataInputStream dis = new DataInputStream(new BufferedInputStream(inputStream)); return new ClassFile(dis); - } catch (Exception e) { - scanner.getLogger().exception(e); - scanner.getLogger().error("Could not create class file from " + file.getInternalPath()); } finally { IOUtils.close(inputStream); } - - return null; } @Override diff --git a/panda-utilities/src/main/java/org/panda_lang/utilities/annotations/adapter/MetadataAdapter.java b/panda-utilities/src/main/java/org/panda_lang/utilities/annotations/adapter/MetadataAdapter.java index 0bd0fbc7a..92c70cb1d 100644 --- a/panda-utilities/src/main/java/org/panda_lang/utilities/annotations/adapter/MetadataAdapter.java +++ b/panda-utilities/src/main/java/org/panda_lang/utilities/annotations/adapter/MetadataAdapter.java @@ -53,7 +53,7 @@ public interface MetadataAdapter { String getFieldName(F field); - C getOfCreateClassObject(AnnotationsScanner scanner, AnnotationsScannerFile file); + C getOfCreateClassObject(AnnotationsScanner scanner, AnnotationsScannerFile file) throws Exception; String getMethodModifier(M method); diff --git a/panda-utilities/src/main/java/org/panda_lang/utilities/inject/InjectorAnnotation.java b/panda-utilities/src/main/java/org/panda_lang/utilities/inject/InjectorAnnotation.java index 6457ab967..df72bf898 100644 --- a/panda-utilities/src/main/java/org/panda_lang/utilities/inject/InjectorAnnotation.java +++ b/panda-utilities/src/main/java/org/panda_lang/utilities/inject/InjectorAnnotation.java @@ -22,6 +22,12 @@ import java.util.HashMap; import java.util.Map; +/** + * Annotation data wrapper. + * Stores data about the annotation in {@link org.panda_lang.utilities.inject.InjectorAnnotation.Metadata} container. + * + * @param annotation type + */ public final class InjectorAnnotation { private final T annotation; @@ -53,6 +59,11 @@ public T getAnnotation() { return annotation; } + /** + * Stores in key-value format data about the associated annotation + * + * @param + */ public static final class Metadata { private final Class annotationType; diff --git a/panda-utilities/src/main/java/org/panda_lang/utilities/inject/InjectorResources.java b/panda-utilities/src/main/java/org/panda_lang/utilities/inject/InjectorResources.java index b78df83f7..fb159f4be 100644 --- a/panda-utilities/src/main/java/org/panda_lang/utilities/inject/InjectorResources.java +++ b/panda-utilities/src/main/java/org/panda_lang/utilities/inject/InjectorResources.java @@ -35,16 +35,16 @@ public interface InjectorResources { * * @param annotation the annotation to bind * @param type of annotation - * @return the bind based on associate annotation + * @return the bind based on associated annotation */ InjectorResourceBind annotatedWith(Class annotation); /** - * Create bind for parameters annotated with the specified annotation with no + * Create bind for parameters annotated with the specified annotation converted into to {@link org.panda_lang.utilities.inject.InjectorAnnotation} * * @param annotation the annotation to bind * @param type of annotation - * @return the bind based on associate annotation + * @return the bind based on associated annotation */ InjectorResourceBind> annotatedWithMetadata(Class annotation); diff --git a/panda-utilities/src/test/java/org/panda_lang/utilities/inject/DependencyInjectionWikiTest.java b/panda-utilities/src/test/java/org/panda_lang/utilities/inject/DependencyInjectionWikiTest.java new file mode 100644 index 000000000..abf60171c --- /dev/null +++ b/panda-utilities/src/test/java/org/panda_lang/utilities/inject/DependencyInjectionWikiTest.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2015-2020 Dzikoysk + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.panda_lang.utilities.inject; + +import org.junit.jupiter.api.Test; +import org.panda_lang.utilities.inject.annotations.Inject; +import org.panda_lang.utilities.inject.annotations.Injectable; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.UUID; + +final class DependencyInjectionWikiTest { + + @Test + void testWikiExample() throws Exception { + Injector injector = DependencyInjection.createInjector(resources -> { + resources.annotatedWith(AwesomeRandom.class).assignHandler((expectedType, annotation) -> { + if (expectedType.equals(String.class)) { + return UUID.randomUUID().toString(); + } + + if (expectedType.equals(UUID.class)) { + return UUID.randomUUID(); + } + + throw new IllegalArgumentException("Unsupported type " + expectedType); + }); + }); + + Entity entityA = injector.newInstance(Entity.class); + Entity entityB = injector.newInstance(Entity.class); + + System.out.println(entityA.getId()); + System.out.println(entityB.getId()); + } + + @Injectable // mark annotation as DI ready annotation + @Retention(RetentionPolicy.RUNTIME) // make sure that the annotation is visible at runtime + @interface AwesomeRandom { } + + private static final class Entity { + private final UUID id; + + @Inject //it's not required, but it might be useful to disable "unused method" warnings/scanning for annotations + private Entity(@AwesomeRandom UUID random) { + this.id = random; + } + + public UUID getId() { + return id; + } + } + +}