Skip to content

#253 - Fix for @Secondary and @Primary not used with @Factory @Bean methods #254

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jan 11, 2023
Merged
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
package org.example.myapp.config;

import io.avaje.inject.Bean;
import io.avaje.inject.Component;
import io.avaje.inject.Factory;
import io.avaje.inject.Prototype;
import io.avaje.inject.*;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.inject.Named;
import org.example.myapp.HelloData;

import java.util.Optional;

@Factory
public class AppConfig {

Expand Down Expand Up @@ -35,19 +34,74 @@ Generated newGenerated() {
return new Generated();
}

@Secondary
@Bean
public MySecType generalSecondary() {
return new MySecType();
}

@Secondary
@Bean
public Optional<MySecOptType> optionalSecondary() {
return Optional.of(new MySecOptType());
}

@Primary
@Bean
public MyPrim primaryBean() {
return new MyPrim("prime");
}

@Named("notPrimary")
@Bean
public MyPrim notPrimaryBean() {
return new MyPrim("notPrimary");
}

@Bean
public Provider provider() {
return new Provider();
}

@Bean
public MyGen<String> myGen() {
return new MyGen<String>();
}

public static class Builder {
}

public static class Generated {
}

public static class MySecType {
}

public static class MySecOptType {
}

public static class Provider {

}

public static class MyGen<T> {

}

public static class MyPrim {
public final String val;
public MyPrim(String val) {
this.val = val;
}
}

@Component
public static class BuilderUser {

final Provider<Builder> builderProvider;
final jakarta.inject.Provider<Builder> builderProvider;

@Inject
public BuilderUser(Provider<Builder> builderProvider) {
public BuilderUser(jakarta.inject.Provider<Builder> builderProvider) {
this.builderProvider = builderProvider;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.example.myapp.config;

import io.avaje.inject.Bean;
import io.avaje.inject.Factory;

@Factory
public class DupShortNameFactory {

@Bean
MyDup one() {
return new MyDup();
}

/**
* Requires fully qualified name as short name of MyDup clashes.
*/
@Bean
org.example.myapp.config.MyDup two() {
return new org.example.myapp.config.MyDup();
}

public static class MyDup {

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package org.example.myapp.config;

public class MyDup {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.example.myapp.config;

import io.avaje.inject.BeanScope;
import org.junit.jupiter.api.Test;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertNotNull;

class AppConfigTest {

@Test
void factorySecondaryAsProvider() {
try (BeanScope testScope = BeanScope.builder().build()) {
assertNotNull(testScope.get(AppConfig.class));

var one = testScope.get(AppConfig.MySecType.class);
var two = testScope.get(AppConfig.MySecType.class);
assertThat(one).describedAs("Secondary Bean provided once").isSameAs(two);

var optOne = testScope.get(AppConfig.MySecOptType.class);
var optTwo = testScope.get(AppConfig.MySecOptType.class);
assertThat(optOne).describedAs("Secondary optional Bean provided once").isSameAs(optTwo);

var myPrim = testScope.get(AppConfig.MyPrim.class);
assertThat(myPrim.val).isEqualTo("prime");

var notPrimary = testScope.get(AppConfig.MyPrim.class, "notPrimary");
assertThat(notPrimary.val).isEqualTo("notPrimary");

List<AppConfig.MyPrim> list = testScope.list(AppConfig.MyPrim.class);
assertThat(list).hasSize(2);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.example.myapp.config;

import io.avaje.inject.BeanScope;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*;

class DupShortNameFactoryTest {

@Test
void factoryBeanRequiringFullyQualifiedName() {
try (BeanScope testScope = BeanScope.builder().build()) {
// both have short name of MyDup
var one = testScope.get(org.example.myapp.config.MyDup.class);
var two = testScope.get(DupShortNameFactory.MyDup.class);

assertNotNull(one);
assertNotNull(two);
assertThat(one).isNotSameAs(two);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import java.util.List;
import java.util.Map;

class AllScopes {
final class AllScopes {

private final Map<String, Data> scopeAnnotations = new HashMap<>();
private final ProcessingContext context;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;

class AnnotationUtil {
final class AnnotationUtil {

static boolean hasAnnotationWithName(Element element, String matchShortName) {
for (AnnotationMirror mirror : element.getAnnotationMirrors()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
/**
* Helper that wraps a writer with some useful methods to append content.
*/
class Append {
final class Append {

private final Writer writer;
private int nameIndex;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
/**
* Read the annotations on the type.
*/
class AspectAnnotationReader {
final class AspectAnnotationReader {

private static final String ASPECT = Constants.ASPECT;
private final TypeElement baseType;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import javax.lang.model.type.TypeMirror;
import java.util.*;

class AspectMethod {
final class AspectMethod {

private final List<AspectPair> aspectPairs;
private final ExecutableElement method;
Expand Down Expand Up @@ -49,7 +49,7 @@ boolean isVoid() {
return rawReturn.equals("void");
}

void addImports(Set<String> importTypes) {
void addImports(ImportTypeMap importTypes) {
for (AspectPair aspect : aspectPairs) {
aspect.addImports(importTypes);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package io.avaje.inject.generator;

import javax.lang.model.element.Element;
import java.util.Set;

class AspectPair implements Comparable<AspectPair> {
final class AspectPair implements Comparable<AspectPair> {

private final String target;
private final int ordering;
Expand All @@ -21,7 +20,7 @@ String target() {
return target;
}

void addImports(Set<String> importTypes) {
void addImports(ImportTypeMap importTypes) {
importTypes.add(target);
importTypes.add(annotationFullName);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import java.util.List;
import java.util.Set;

class BeanAspects {
final class BeanAspects {

static final BeanAspects EMPTY = new BeanAspects();

Expand All @@ -30,7 +30,7 @@ Set<String> targets() {
return targets;
}

void extraImports(Set<String> importTypes) {
void extraImports(ImportTypeMap importTypes) {
for (AspectMethod aspectMethod : aspectMethods) {
aspectMethod.addImports(importTypes);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import javax.lang.model.element.TypeElement;
import java.util.*;

class BeanReader {
final class BeanReader {

private final TypeElement beanType;
private final String shortName;
Expand All @@ -23,7 +23,7 @@ class BeanReader {
private final Element postConstructMethod;
private final Element preDestroyMethod;

private final Set<String> importTypes = new TreeSet<>();
private final ImportTypeMap importTypes = new ImportTypeMap();
private final BeanRequestParams requestParams;
private final TypeReader typeReader;
private final boolean prototype;
Expand Down Expand Up @@ -205,10 +205,15 @@ void buildRegister(Append writer) {
}
writer.append(" ");
if (isExtraInjectionRequired() || hasLifecycleMethods()) {
writer.append("%s $bean = ", shortName);
writer.append("var $bean = ");
}
String flags = primary ? "Primary" : secondary ? "Secondary" : "";
writer.append("builder.register%s(bean);", flags).eol();
writer.append("builder.");
if (primary) {
writer.append("asPrimary().");
} else if (secondary) {
writer.append("asSecondary().");
}
writer.append("register(bean);").eol();
}

void addLifecycleCallbacks(Append writer, String indent) {
Expand Down Expand Up @@ -248,10 +253,7 @@ private Set<String> importTypes() {
if (!genericTypes.isEmpty()) {
importTypes.add(Constants.TYPE);
importTypes.add(Constants.GENERICTYPE);
importTypes.add(Constants.PROVIDER);
for (GenericType genericType : genericTypes) {
genericType.addImports(importTypes);
}
// TYPE_ generic types are fully qualified
}
}
checkImports();
Expand All @@ -261,17 +263,12 @@ private Set<String> importTypes() {
if (!suppressBuilderImport) {
importTypes.add(Constants.BUILDER);
}
return importTypes;
return importTypes.forImport();
}

private void checkImports() {
for (String type : importTypes) {
if (type.endsWith(".Builder")) {
suppressBuilderImport = true;
} else if (type.endsWith(".Generated")) {
suppressGeneratedImport = true;
}
}
suppressBuilderImport = importTypes.containsShortName("Builder");
suppressGeneratedImport = importTypes.containsShortName("Generated");
}

String builderType() {
Expand Down Expand Up @@ -343,7 +340,7 @@ void writeRequestCreate(Append writer) {
}
requestParams.writeRequestCreate(writer);
writer.resetNextName();
writer.append(" %s bean = new %s(", shortName, shortName);
writer.append(" var bean = new %s(", shortName);
if (constructor != null) {
constructor.writeRequestConstructor(writer);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package io.avaje.inject.generator;


import java.util.Set;

/**
* Holds detection and details of request scoped dependencies.
*/
class BeanRequestParams {
final class BeanRequestParams {

private final String parentType;
private RequestScope.Handler reqScopeHandler;
Expand Down Expand Up @@ -39,7 +37,7 @@ void factoryInterface(Append writer) {
reqScopeHandler.factoryInterface(writer, nm(parentType));
}

void addImports(Set<String> importTypes) {
void addImports(ImportTypeMap importTypes) {
if (reqScopeHandler != null) {
importTypes.add(Constants.SINGLETON);
importTypes.add(Constants.INJECT);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.avaje.inject.generator;

class Constants {
final class Constants {

static final int ORDERING_DEFAULT = 1000;

Expand Down
Loading