Skip to content

Commit 727158b

Browse files
authored
ISSUES-4 refactoring, extract BuilderImpl and FactoryImpl (#12)
1 parent bb08399 commit 727158b

File tree

4 files changed

+232
-85
lines changed

4 files changed

+232
-85
lines changed
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package io.jbock.simple.processor.writing;
2+
3+
import io.jbock.javapoet.CodeBlock;
4+
import io.jbock.javapoet.FieldSpec;
5+
import io.jbock.javapoet.MethodSpec;
6+
import io.jbock.javapoet.ParameterSpec;
7+
import io.jbock.javapoet.TypeName;
8+
import io.jbock.javapoet.TypeSpec;
9+
import io.jbock.simple.Inject;
10+
import io.jbock.simple.processor.binding.Binding;
11+
import io.jbock.simple.processor.binding.BuilderElement;
12+
import io.jbock.simple.processor.binding.ComponentElement;
13+
import io.jbock.simple.processor.binding.Key;
14+
import io.jbock.simple.processor.binding.ParameterBinding;
15+
16+
import javax.lang.model.type.TypeMirror;
17+
import java.util.ArrayList;
18+
import java.util.List;
19+
import java.util.Map;
20+
import java.util.function.Function;
21+
import java.util.stream.Collectors;
22+
23+
import static javax.lang.model.element.Modifier.FINAL;
24+
import static javax.lang.model.element.Modifier.PRIVATE;
25+
import static javax.lang.model.element.Modifier.PROTECTED;
26+
import static javax.lang.model.element.Modifier.PUBLIC;
27+
import static javax.lang.model.element.Modifier.STATIC;
28+
29+
public class BuilderImpl {
30+
31+
private final ComponentElement component;
32+
private final Map<Key, NamedBinding> sorted;
33+
private final Function<Key, ParameterSpec> names;
34+
35+
private BuilderImpl(
36+
ComponentElement component,
37+
Map<Key, NamedBinding> sorted,
38+
Function<Key, ParameterSpec> names) {
39+
this.component = component;
40+
this.sorted = sorted;
41+
this.names = names;
42+
}
43+
44+
TypeSpec generate(BuilderElement builder) {
45+
TypeMirror builderType = builder.element().asType();
46+
TypeSpec.Builder spec = TypeSpec.classBuilder(builder.generatedClass());
47+
MethodSpec.Builder buildMethod = MethodSpec.methodBuilder(builder.buildMethod().getSimpleName().toString());
48+
List<CodeBlock> constructorParameters = new ArrayList<>();
49+
for (NamedBinding namedBinding : sorted.values()) {
50+
Binding b = namedBinding.binding();
51+
Key key = b.key();
52+
CodeBlock invocation = b.invocation(names);
53+
ParameterSpec param = names.apply(key);
54+
if (namedBinding.isComponentRequest()) {
55+
constructorParameters.add(CodeBlock.of("$N", names.apply(key)));
56+
}
57+
if (b instanceof ParameterBinding) {
58+
spec.addField(FieldSpec.builder(b.key().typeName(), names.apply(b.key()).name).build());
59+
MethodSpec.Builder setterMethod = MethodSpec.methodBuilder(b.element().getSimpleName().toString());
60+
setterMethod.addAnnotation(Override.class);
61+
setterMethod.addParameter(names.apply(b.key()));
62+
setterMethod.addStatement("this.$N = $N", names.apply(b.key()), names.apply(b.key()));
63+
setterMethod.addStatement("return this");
64+
setterMethod.returns(TypeName.get(builderType));
65+
setterMethod.addModifiers(b.element().getModifiers().stream()
66+
.filter(m -> m == PUBLIC || m == PROTECTED).collect(Collectors.toList()));
67+
spec.addMethod(setterMethod.build());
68+
} else {
69+
buildMethod.addStatement("$T $N = $L", key.typeName(), param, invocation);
70+
}
71+
}
72+
spec.addModifiers(PRIVATE, STATIC, FINAL);
73+
spec.addSuperinterface(builderType);
74+
buildMethod.addAnnotation(Override.class);
75+
buildMethod.addModifiers(builder.buildMethod().getModifiers().stream()
76+
.filter(m -> m == PUBLIC || m == PROTECTED).collect(Collectors.toList()));
77+
buildMethod.returns(TypeName.get(component.element().asType()));
78+
buildMethod.addStatement("return new $T($L)", component.generatedClass(), constructorParameters.stream()
79+
.collect(CodeBlock.joining(", ")));
80+
spec.addMethod(buildMethod.build());
81+
return spec.build();
82+
}
83+
84+
public static final class Factory {
85+
private final ComponentElement component;
86+
87+
@Inject
88+
public Factory(ComponentElement component) {
89+
this.component = component;
90+
}
91+
92+
BuilderImpl create(
93+
Map<Key, NamedBinding> sorted,
94+
Function<Key, ParameterSpec> names) {
95+
return new BuilderImpl(
96+
component,
97+
sorted,
98+
names);
99+
}
100+
}
101+
}

compiler/src/main/java/io/jbock/simple/processor/writing/ComponentImpl.java

Lines changed: 24 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,19 @@
1010
import io.jbock.simple.Inject;
1111
import io.jbock.simple.processor.SimpleComponentProcessor;
1212
import io.jbock.simple.processor.binding.Binding;
13-
import io.jbock.simple.processor.binding.BuilderElement;
1413
import io.jbock.simple.processor.binding.ComponentElement;
1514
import io.jbock.simple.processor.binding.DependencyRequest;
16-
import io.jbock.simple.processor.binding.FactoryElement;
1715
import io.jbock.simple.processor.binding.Key;
18-
import io.jbock.simple.processor.binding.ParameterBinding;
1916

2017
import javax.annotation.processing.Generated;
21-
import javax.lang.model.element.ExecutableElement;
2218
import javax.lang.model.element.Modifier;
23-
import javax.lang.model.type.TypeMirror;
2419
import java.util.ArrayList;
2520
import java.util.List;
2621
import java.util.Map;
2722
import java.util.function.Function;
28-
import java.util.stream.Collectors;
2923

3024
import static javax.lang.model.element.Modifier.FINAL;
3125
import static javax.lang.model.element.Modifier.PRIVATE;
32-
import static javax.lang.model.element.Modifier.PROTECTED;
3326
import static javax.lang.model.element.Modifier.PUBLIC;
3427
import static javax.lang.model.element.Modifier.STATIC;
3528

@@ -44,19 +37,25 @@ public class ComponentImpl {
4437
private final Map<Key, NamedBinding> sorted;
4538
private final Function<Key, ParameterSpec> names;
4639
private final MockBuilder mockBuilder;
40+
private final BuilderImpl builderImpl;
41+
private final FactoryImpl factoryImpl;
4742
private final Modifier[] modifiers;
4843

4944
private ComponentImpl(
5045
ComponentElement component,
5146
Map<Key, NamedBinding> sorted,
5247
Function<Key, ParameterSpec> names,
53-
MockBuilder mockBuilder) {
48+
MockBuilder mockBuilder,
49+
BuilderImpl builderImpl,
50+
FactoryImpl factoryImpl) {
5451
this.component = component;
5552
this.sorted = sorted;
5653
this.names = names;
5754
this.mockBuilder = mockBuilder;
5855
this.modifiers = component.element().getModifiers().stream()
5956
.filter(m -> m == PUBLIC).toArray(Modifier[]::new);
57+
this.builderImpl = builderImpl;
58+
this.factoryImpl = factoryImpl;
6059
}
6160

6261
TypeSpec generate() {
@@ -79,7 +78,7 @@ TypeSpec generate() {
7978
.returns(TypeName.get(factory.element().asType()))
8079
.addStatement("return new $T()", factory.generatedClass())
8180
.build());
82-
spec.addType(createFactoryImpl(factory));
81+
spec.addType(factoryImpl.generate(factory));
8382
});
8483
component.builderElement().ifPresent(builder -> {
8584
spec.addMethod(MethodSpec.methodBuilder(BUILDER_METHOD)
@@ -88,13 +87,15 @@ TypeSpec generate() {
8887
.returns(TypeName.get(builder.element().asType()))
8988
.addStatement("return new $T()", builder.generatedClass())
9089
.build());
91-
spec.addType(createBuilderImpl(builder));
90+
spec.addType(builderImpl.generate(builder));
9291
});
9392
if (component.factoryElement().isEmpty() && component.builderElement().isEmpty()) {
9493
spec.addMethod(generateCreateMethod());
94+
if (!component.omitMockBuilder()) {
95+
spec.addMethod(generateMockBuilderMethod());
96+
}
9597
}
9698
if (!component.omitMockBuilder()) {
97-
spec.addMethod(generateMockBuilderMethod());
9899
spec.addType(mockBuilder.generate());
99100
}
100101
spec.addAnnotation(AnnotationSpec.builder(Generated.class)
@@ -168,85 +169,22 @@ private MethodSpec generateAllParametersConstructor() {
168169
return constructor.build();
169170
}
170171

171-
private TypeSpec createFactoryImpl(FactoryElement factory) {
172-
TypeSpec.Builder spec = TypeSpec.classBuilder(factory.generatedClass());
173-
spec.addModifiers(PRIVATE, STATIC, FINAL);
174-
spec.addSuperinterface(factory.element().asType());
175-
ExecutableElement abstractMethod = factory.singleAbstractMethod();
176-
MethodSpec.Builder method = MethodSpec.methodBuilder(abstractMethod.getSimpleName().toString());
177-
method.addAnnotation(Override.class);
178-
method.addModifiers(abstractMethod.getModifiers().stream()
179-
.filter(m -> m == PUBLIC || m == PROTECTED).collect(Collectors.toList()));
180-
method.returns(TypeName.get(component.element().asType()));
181-
List<CodeBlock> constructorParameters = new ArrayList<>();
182-
for (NamedBinding namedBinding : sorted.values()) {
183-
Binding b = namedBinding.binding();
184-
Key key = b.key();
185-
CodeBlock invocation = b.invocation(names);
186-
ParameterSpec param = names.apply(key);
187-
if (namedBinding.isComponentRequest()) {
188-
constructorParameters.add(CodeBlock.of("$N", names.apply(key)));
189-
}
190-
if (b instanceof ParameterBinding) {
191-
method.addParameter(names.apply(b.key()));
192-
} else {
193-
method.addStatement("$T $N = $L", key.typeName(), param, invocation);
194-
}
195-
}
196-
method.addStatement("return new $T($L)", component.generatedClass(), constructorParameters.stream()
197-
.collect(CodeBlock.joining(", ")));
198-
spec.addMethod(method.build());
199-
return spec.build();
200-
}
201-
202-
private TypeSpec createBuilderImpl(BuilderElement builder) {
203-
TypeMirror builderType = builder.element().asType();
204-
TypeSpec.Builder spec = TypeSpec.classBuilder(builder.generatedClass());
205-
MethodSpec.Builder buildMethod = MethodSpec.methodBuilder(builder.buildMethod().getSimpleName().toString());
206-
List<CodeBlock> constructorParameters = new ArrayList<>();
207-
for (NamedBinding namedBinding : sorted.values()) {
208-
Binding b = namedBinding.binding();
209-
Key key = b.key();
210-
CodeBlock invocation = b.invocation(names);
211-
ParameterSpec param = names.apply(key);
212-
if (namedBinding.isComponentRequest()) {
213-
constructorParameters.add(CodeBlock.of("$N", names.apply(key)));
214-
}
215-
if (b instanceof ParameterBinding) {
216-
spec.addField(FieldSpec.builder(b.key().typeName(), names.apply(b.key()).name).build());
217-
MethodSpec.Builder setterMethod = MethodSpec.methodBuilder(b.element().getSimpleName().toString());
218-
setterMethod.addAnnotation(Override.class);
219-
setterMethod.addParameter(names.apply(b.key()));
220-
setterMethod.addStatement("this.$N = $N", names.apply(b.key()), names.apply(b.key()));
221-
setterMethod.addStatement("return this");
222-
setterMethod.returns(TypeName.get(builderType));
223-
setterMethod.addModifiers(b.element().getModifiers().stream()
224-
.filter(m -> m == PUBLIC || m == PROTECTED).collect(Collectors.toList()));
225-
spec.addMethod(setterMethod.build());
226-
} else {
227-
buildMethod.addStatement("$T $N = $L", key.typeName(), param, invocation);
228-
}
229-
}
230-
spec.addModifiers(PRIVATE, STATIC, FINAL);
231-
spec.addSuperinterface(builderType);
232-
buildMethod.addAnnotation(Override.class);
233-
buildMethod.addModifiers(builder.buildMethod().getModifiers().stream()
234-
.filter(m -> m == PUBLIC || m == PROTECTED).collect(Collectors.toList()));
235-
buildMethod.returns(TypeName.get(component.element().asType()));
236-
buildMethod.addStatement("return new $T($L)", component.generatedClass(), constructorParameters.stream()
237-
.collect(CodeBlock.joining(", ")));
238-
spec.addMethod(buildMethod.build());
239-
return spec.build();
240-
}
241-
242172
public static final class Factory {
243173
private final ComponentElement component;
244174
private final MockBuilder.Factory mockBuilderFactory;
175+
private final BuilderImpl.Factory builderImplFactory;
176+
private final FactoryImpl.Factory factoryImplFactory;
245177

246178
@Inject
247-
public Factory(ComponentElement component, MockBuilder.Factory mockBuilderFactory) {
179+
public Factory(
180+
ComponentElement component,
181+
MockBuilder.Factory mockBuilderFactory,
182+
BuilderImpl.Factory builderImplFactory,
183+
FactoryImpl.Factory factoryImplFactory) {
248184
this.component = component;
249185
this.mockBuilderFactory = mockBuilderFactory;
186+
this.builderImplFactory = builderImplFactory;
187+
this.factoryImplFactory = factoryImplFactory;
250188
}
251189

252190
ComponentImpl create(
@@ -256,7 +194,9 @@ ComponentImpl create(
256194
component,
257195
sorted,
258196
names,
259-
mockBuilderFactory.create(sorted, names));
197+
mockBuilderFactory.create(sorted, names),
198+
builderImplFactory.create(sorted, names),
199+
factoryImplFactory.create(sorted, names));
260200
}
261201
}
262202
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package io.jbock.simple.processor.writing;
2+
3+
import io.jbock.javapoet.CodeBlock;
4+
import io.jbock.javapoet.MethodSpec;
5+
import io.jbock.javapoet.ParameterSpec;
6+
import io.jbock.javapoet.TypeName;
7+
import io.jbock.javapoet.TypeSpec;
8+
import io.jbock.simple.Inject;
9+
import io.jbock.simple.processor.binding.Binding;
10+
import io.jbock.simple.processor.binding.ComponentElement;
11+
import io.jbock.simple.processor.binding.FactoryElement;
12+
import io.jbock.simple.processor.binding.Key;
13+
import io.jbock.simple.processor.binding.ParameterBinding;
14+
15+
import javax.lang.model.element.ExecutableElement;
16+
import java.util.ArrayList;
17+
import java.util.List;
18+
import java.util.Map;
19+
import java.util.function.Function;
20+
import java.util.stream.Collectors;
21+
22+
import static javax.lang.model.element.Modifier.FINAL;
23+
import static javax.lang.model.element.Modifier.PRIVATE;
24+
import static javax.lang.model.element.Modifier.PROTECTED;
25+
import static javax.lang.model.element.Modifier.PUBLIC;
26+
import static javax.lang.model.element.Modifier.STATIC;
27+
28+
public class FactoryImpl {
29+
30+
private final ComponentElement component;
31+
private final Map<Key, NamedBinding> sorted;
32+
private final Function<Key, ParameterSpec> names;
33+
34+
private FactoryImpl(
35+
ComponentElement component,
36+
Map<Key, NamedBinding> sorted,
37+
Function<Key, ParameterSpec> names) {
38+
this.component = component;
39+
this.sorted = sorted;
40+
this.names = names;
41+
}
42+
43+
TypeSpec generate(FactoryElement factory) {
44+
TypeSpec.Builder spec = TypeSpec.classBuilder(factory.generatedClass());
45+
spec.addModifiers(PRIVATE, STATIC, FINAL);
46+
spec.addSuperinterface(factory.element().asType());
47+
ExecutableElement abstractMethod = factory.singleAbstractMethod();
48+
MethodSpec.Builder method = MethodSpec.methodBuilder(abstractMethod.getSimpleName().toString());
49+
method.addAnnotation(Override.class);
50+
method.addModifiers(abstractMethod.getModifiers().stream()
51+
.filter(m -> m == PUBLIC || m == PROTECTED).collect(Collectors.toList()));
52+
method.returns(TypeName.get(component.element().asType()));
53+
List<CodeBlock> constructorParameters = new ArrayList<>();
54+
for (NamedBinding namedBinding : sorted.values()) {
55+
Binding b = namedBinding.binding();
56+
Key key = b.key();
57+
CodeBlock invocation = b.invocation(names);
58+
ParameterSpec param = names.apply(key);
59+
if (namedBinding.isComponentRequest()) {
60+
constructorParameters.add(CodeBlock.of("$N", names.apply(key)));
61+
}
62+
if (b instanceof ParameterBinding) {
63+
method.addParameter(names.apply(b.key()));
64+
} else {
65+
method.addStatement("$T $N = $L", key.typeName(), param, invocation);
66+
}
67+
}
68+
method.addStatement("return new $T($L)", component.generatedClass(), constructorParameters.stream()
69+
.collect(CodeBlock.joining(", ")));
70+
spec.addMethod(method.build());
71+
return spec.build();
72+
}
73+
74+
public static final class Factory {
75+
private final ComponentElement component;
76+
77+
@Inject
78+
public Factory(ComponentElement component) {
79+
this.component = component;
80+
}
81+
82+
FactoryImpl create(
83+
Map<Key, NamedBinding> sorted,
84+
Function<Key, ParameterSpec> names) {
85+
return new FactoryImpl(
86+
component,
87+
sorted,
88+
names);
89+
}
90+
}
91+
}

0 commit comments

Comments
 (0)