Skip to content

Commit 0d6216a

Browse files
committed
distinguish provider classes and component classes
1 parent d57a4b3 commit 0d6216a

File tree

1 file changed

+34
-31
lines changed

1 file changed

+34
-31
lines changed

cucumber-picocontainer/src/main/java/io/cucumber/picocontainer/PicoFactory.java

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
public final class PicoFactory implements ObjectFactory {
2121

2222
private final Set<Class<?>> classes = new HashSet<>();
23+
private final Set<Class<Provider>> providers = new HashSet<>();
2324
private MutablePicoContainer pico;
2425

2526
private static boolean isInstantiable(Class<?> clazz) {
@@ -35,23 +36,18 @@ public void start() {
3536
.withCaching()
3637
.withLifecycle()
3738
.build();
38-
Set<Class<?>> providers = new HashSet<>();
3939
Set<Class<?>> providedClasses = new HashSet<>();
40-
for (Class<?> clazz : classes) {
41-
if (isProvider(clazz)) {
42-
providers.add(clazz);
43-
ProviderAdapter adapter = adapterForProviderClass(clazz);
44-
pico.addAdapter(adapter);
45-
providedClasses.add(adapter.getComponentImplementation());
46-
}
40+
for (Class<Provider> clazz : providers) {
41+
ProviderAdapter adapter = adapterForProviderClass(clazz);
42+
pico.addAdapter(adapter);
43+
providedClasses.add(adapter.getComponentImplementation());
4744
}
4845
for (Class<?> clazz : classes) {
49-
// do not add the classes that represent a picocontainer
50-
// Provider, and also do not add those raw classes that are
51-
// already provided (otherwise this causes exceptional
52-
// situations, e.g. PicoCompositionException with message
53-
// "Duplicate Keys not allowed. Duplicate for 'class XXX'")
54-
if (!providers.contains(clazz) && !providedClasses.contains(clazz)) {
46+
// do not add classes that are already provided (otherwise this
47+
// causes exceptional situations, e.g. PicoCompositionException
48+
// with message "Duplicate Keys not allowed. Duplicate for
49+
// 'class XXX'")
50+
if (!providedClasses.contains(clazz)) {
5551
pico.addComponent(clazz);
5652
}
5753
}
@@ -69,6 +65,10 @@ public void start() {
6965
pico.start();
7066
}
7167

68+
static boolean hasCucumberPicoProvider(Class<?> clazz) {
69+
return clazz.isAnnotationPresent(CucumberPicoProvider.class);
70+
}
71+
7272
static boolean isProvider(Class<?> clazz) {
7373
return Provider.class.isAssignableFrom(clazz);
7474
}
@@ -77,9 +77,9 @@ static boolean isProviderAdapter(Class<?> clazz) {
7777
return ProviderAdapter.class.isAssignableFrom(clazz);
7878
}
7979

80-
private static ProviderAdapter adapterForProviderClass(Class<?> clazz) {
80+
private static ProviderAdapter adapterForProviderClass(Class<Provider> clazz) {
8181
try {
82-
Provider provider = (Provider) clazz.getDeclaredConstructor().newInstance();
82+
Provider provider = clazz.getDeclaredConstructor().newInstance();
8383
return isProviderAdapter(clazz) ? (ProviderAdapter) provider : new ProviderAdapter(provider);
8484
} catch (ReflectiveOperationException | IllegalArgumentException | SecurityException | PicoException e) {
8585
throw new CucumberBackendException(e.getMessage(), e);
@@ -96,9 +96,12 @@ public void stop() {
9696

9797
@Override
9898
public boolean addClass(Class<?> clazz) {
99-
checkMeaningfulPicoAnnotation(clazz);
100-
if (isInstantiable(clazz) && classes.add(clazz)) {
101-
addConstructorDependencies(clazz);
99+
if (hasCucumberPicoProvider(clazz)) {
100+
providers.add(checkProperPicoProvider(clazz));
101+
} else {
102+
if (isInstantiable(clazz) && classes.add(clazz)) {
103+
addConstructorDependencies(clazz);
104+
}
102105
}
103106
return true;
104107
}
@@ -112,19 +115,19 @@ private static boolean hasDefaultConstructor(Class<?> clazz) {
112115
return false;
113116
}
114117

115-
private static void checkMeaningfulPicoAnnotation(Class<?> clazz) {
116-
if (clazz.isAnnotationPresent(CucumberPicoProvider.class)) {
117-
if (!isProvider(clazz) || !hasDefaultConstructor(clazz)) {
118-
throw new CucumberBackendException(String.format("" +
119-
"Glue class %1$s was annotated with @CucumberPicoProvider; marking it as a candidate for declaring a"
120-
+
121-
"PicoContainer Provider instance. Please ensure that all the following requirements are satisfied:\n"
122-
+
123-
"1) the class implements org.picocontainer.injectors.Provider\n" +
124-
"2) the class provides a default constructor.",
125-
clazz.getName()));
126-
}
118+
@SuppressWarnings("unchecked")
119+
private static Class<Provider> checkProperPicoProvider(Class<?> clazz) {
120+
if (!isProvider(clazz) || !hasDefaultConstructor(clazz)) {
121+
throw new CucumberBackendException(String.format("" +
122+
"Glue class %1$s was annotated with @CucumberPicoProvider; marking it as a candidate for declaring a"
123+
+
124+
"PicoContainer Provider instance. Please ensure that all the following requirements are satisfied:\n"
125+
+
126+
"1) the class implements org.picocontainer.injectors.Provider\n" +
127+
"2) the class provides a default constructor.",
128+
clazz.getName()));
127129
}
130+
return (Class<Provider>) clazz;
128131
}
129132

130133
@Override

0 commit comments

Comments
 (0)