
br.com.objectos.code.pojo.BuilderClass Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2015 Objectos, Fábrica de Software LTDA.
*
* 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 br.com.objectos.code.pojo;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.lang.model.element.Modifier;
import br.com.objectos.code.ConstructorInfo;
import br.com.objectos.code.ParameterInfo;
import br.com.objectos.core.util.MoreCollectors;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;
/**
* @author [email protected] (Marcio Endo)
*/
class BuilderClass extends AbstractHasPojoInfo {
private final List constructorList;
public BuilderClass(PojoInfo info) {
super(info);
List constructorInfoList = constructorInfoList();
int size = constructorInfoList.size();
constructorList = constructorInfoList.stream()
.map(constructor -> new BuilderClassConstructor(constructor, size))
.collect(MoreCollectors.toImmutableList());
}
public JavaFile generate(Configuration configuration) {
return generate(type(configuration));
}
MethodSpec build(Configuration configuration) {
MethodSpec.Builder b = MethodSpec.methodBuilder("build")
.addAnnotation(Override.class)
.addModifiers(Modifier.PUBLIC)
.returns(naming().superClassTypeNameUnbounded());
AtomicInteger index = new AtomicInteger();
List codeBlockList = constructorList.stream()
.map(constructor -> constructor.build(configuration, index.getAndIncrement()))
.collect(MoreCollectors.toImmutableList());
for (CodeBlock codeBlock : codeBlockList) {
b.addCode(codeBlock);
}
return b.build();
}
List constructor(Configuration configuration) {
AtomicInteger index = new AtomicInteger();
return constructorList.stream()
.map(constructor -> constructor.constructor(configuration, index.getAndIncrement()))
.collect(Collectors.toList());
}
List field(Configuration configuration) {
Stream stream0 = configuration.builderClassField();
Stream stream1 = fieldConstructor();
Stream stream2 = fieldMethod();
Stream stream01 = Stream.concat(stream0, stream1);
return Stream.concat(stream01, stream2).collect(Collectors.toList());
}
List getter() {
return builderMethodStream()
.map(AttributeMethod::builderClassGetter)
.collect(Collectors.toList());
}
List setter() {
return builderMethodStream()
.flatMap(AttributeMethod::builderClassSetter)
.collect(Collectors.toList());
}
TypeSpec type(Configuration configuration) {
TypeSpec.Builder type = TypeSpec.classBuilder(naming().builderClassSimpleName())
.addModifiers(Modifier.FINAL)
.addAnnotation(configuration.annotationSpec())
.addSuperinterface(naming().builderInterfaceTypeNameUnbounded());
naming().typeVariableNameListTo(type);
for (AttributeMethod methodInfo : builderMethodList()) {
TypeName innerTypeName = naming().builderInnerTypeName(methodInfo);
type.addSuperinterface(innerTypeName);
}
return type
.addFields(field(configuration))
.addMethods(constructor(configuration))
.addMethod(build(configuration))
.addMethods(setter())
.addMethods(getter())
.build();
}
private String constructorPrefix(int index) {
return "___constructor" + index + "___";
}
private Stream fieldConstructor() {
List constructorInfoList = constructorInfoList();
return constructorInfoList().stream()
.flatMap(new ConstructorInfoToFieldSpec(constructorInfoList.size()));
}
private Stream fieldMethod() {
return builderMethodStream()
.map(method -> method.builderClassFieldSpec());
}
private class ConstructorInfoToFieldSpec implements Function> {
private final int size;
private int index = 0;
public ConstructorInfoToFieldSpec(int size) {
this.size = size;
}
@Override
public Stream apply(ConstructorInfo input) {
Stream parameter = input.parameterInfoStream()
.map(new ParameterInfoToFieldSpec(index));
Stream res = Stream.concat(parameter, marker());
index++;
return res;
}
private Stream marker() {
if (size == 1) {
return Stream.empty();
}
if (index + 1 == size) {
return Stream.empty();
}
FieldSpec marker = FieldSpec.builder(boolean.class, constructorPrefix(index), Modifier.PRIVATE).build();
return Stream.of(marker);
}
}
private class ParameterInfoToFieldSpec implements Function {
private final String prefix;
public ParameterInfoToFieldSpec(int index) {
prefix = constructorPrefix(index);
}
@Override
public FieldSpec apply(ParameterInfo input) {
return input.fieldWriter()
.modifiers(Modifier.PRIVATE)
.prefixNameWith(prefix)
.write();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy