All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
net.zerobuilder.compiler.generate.BuilderContextV Maven / Gradle / Ivy
package net.zerobuilder.compiler.generate;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.ParameterSpec;
import com.squareup.javapoet.TypeName;
import net.zerobuilder.compiler.generate.DtoRegularGoalContext.ConstructorGoalContext;
import net.zerobuilder.compiler.generate.DtoRegularGoalContext.MethodGoalContext;
import net.zerobuilder.compiler.generate.DtoRegularGoalContext.RegularGoalContext;
import net.zerobuilder.compiler.generate.DtoRegularGoalContext.RegularGoalContextCases;
import net.zerobuilder.compiler.generate.DtoStep.CollectionInfo;
import net.zerobuilder.compiler.generate.DtoStep.RegularStep;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import static com.squareup.javapoet.MethodSpec.methodBuilder;
import static com.squareup.javapoet.TypeName.VOID;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static javax.lang.model.element.Modifier.PUBLIC;
import static net.zerobuilder.compiler.generate.DtoGoal.GoalMethodType.INSTANCE_METHOD;
import static net.zerobuilder.compiler.generate.DtoRegularGoalContext.asFunction;
import static net.zerobuilder.compiler.generate.DtoRegularGoalContext.isInstance;
import static net.zerobuilder.compiler.generate.DtoRegularGoalContext.regularSteps;
import static net.zerobuilder.compiler.generate.DtoStep.declaredExceptions;
import static net.zerobuilder.compiler.generate.StepContext.nullCheck;
import static net.zerobuilder.compiler.generate.Utilities.parameterSpec;
import static net.zerobuilder.compiler.generate.Utilities.presentInstances;
import static net.zerobuilder.compiler.generate.Utilities.statement;
final class BuilderContextV {
static final Function> fields
= goal -> {
List builder = new ArrayList<>();
DtoBuildersContext.BuildersContext buildersContext = DtoRegularGoalContext.buildersContext.apply(goal);
builder.addAll(isInstance.test(goal)
? singletonList(buildersContext.field)
: emptyList());
List steps = regularSteps.apply(goal);
builder.addAll(steps.stream().limit(steps.size() - 1)
.map(RegularStep::field)
.collect(Collectors.toList()));
return builder;
};
static final Function> steps
= goal -> {
List steps = regularSteps.apply(goal);
List builder = new ArrayList<>();
for (RegularStep step : steps.subList(0, steps.size() - 1)) {
builder.addAll(regularMethods(step, goal, false));
}
builder.addAll(regularMethods(steps.get(steps.size() - 1), goal, true));
return builder;
};
private static List regularMethods(
RegularStep step, RegularGoalContext goal, boolean isLast) {
List builder = new ArrayList<>();
builder.add(stepMethod(step, goal, isLast));
builder.addAll(presentInstances(maybeEmptyCollection(step, goal, isLast)));
return builder;
}
private static MethodSpec stepMethod(RegularStep step, RegularGoalContext goal, boolean isLast) {
TypeName type = step.validParameter.type;
String name = step.validParameter.name;
ParameterSpec parameter = parameterSpec(type, name);
return methodBuilder(step.validParameter.name)
.addAnnotation(Override.class)
.addParameter(parameter)
.returns(step.nextType)
.addCode(nullCheck.apply(step))
.addCode(normalAssignment(step, goal, isLast))
.addModifiers(PUBLIC)
.addExceptions(declaredExceptions.apply(step))
.build();
}
private static Optional maybeEmptyCollection(
RegularStep step, RegularGoalContext goal, boolean isLast) {
Optional maybeEmptyOption = step.emptyOption();
if (!maybeEmptyOption.isPresent()) {
return Optional.empty();
}
CollectionInfo collectionInfo = maybeEmptyOption.get();
return Optional.of(methodBuilder(collectionInfo.name)
.addAnnotation(Override.class)
.returns(step.nextType)
.addCode(emptyCollectionAssignment(step, goal, collectionInfo, isLast))
.addModifiers(PUBLIC)
.build());
}
private static CodeBlock normalAssignment(RegularStep step, RegularGoalContext goal, boolean isLast) {
TypeName type = step.validParameter.type;
String name = step.validParameter.name;
ParameterSpec parameter = parameterSpec(type, name);
if (isLast) {
return regularInvoke.apply(goal);
} else {
return CodeBlock.builder()
.addStatement("this.$N = $N", step.field(), parameter)
.addStatement("return this")
.build();
}
}
private static CodeBlock emptyCollectionAssignment(RegularStep step, RegularGoalContext goal,
CollectionInfo collInfo, boolean isLast) {
if (isLast) {
return goal.acceptRegular(emptyCollectionInvoke(step, collInfo));
} else {
return CodeBlock.builder()
.addStatement("this.$N = $L", step.field(), collInfo.initializer)
.addStatement("return this")
.build();
}
}
static final Function regularInvoke
= asFunction(new RegularGoalContextCases() {
@Override
public CodeBlock constructorGoal(ConstructorGoalContext goal) {
CodeBlock parameters = invocationParameters(goal.goal.details.parameterNames);
return statement("return new $T($L)", goal.goal.details.goalType, parameters);
}
@Override
public CodeBlock methodGoal(MethodGoalContext goal) {
CodeBlock parameters = invocationParameters(goal.goal.details.parameterNames);
return methodGoalInvocation(goal, parameters);
}
});
private static RegularGoalContextCases emptyCollectionInvoke(final RegularStep step,
final CollectionInfo collectionInfo) {
return new RegularGoalContextCases() {
@Override
public CodeBlock constructorGoal(ConstructorGoalContext goal) {
CodeBlock parameters = invocationParameters(goal.goal.details.parameterNames);
TypeName type = step.validParameter.type;
String name = step.validParameter.name;
return CodeBlock.builder()
.addStatement("$T $N = $L", type, name, collectionInfo.initializer)
.addStatement("return new $T($L)", goal.goal.details.goalType, parameters)
.build();
}
@Override
public CodeBlock methodGoal(MethodGoalContext goal) {
CodeBlock parameters = invocationParameters(goal.goal.details.parameterNames);
TypeName type = step.validParameter.type;
String name = step.validParameter.name;
return CodeBlock.builder()
.addStatement("$T $N = $L", type, name, collectionInfo.initializer)
.add(methodGoalInvocation(goal, parameters))
.build();
}
};
}
private static CodeBlock methodGoalInvocation(MethodGoalContext goal, CodeBlock parameters) {
CodeBlock.Builder builder = CodeBlock.builder();
TypeName type = goal.goal.details.goalType;
String method = goal.goal.details.methodName;
builder.add(CodeBlock.of(VOID.equals(type) ? "" : "return "));
builder.add(goal.goal.details.methodType == INSTANCE_METHOD
? statement("$N.$N($L)", goal.builders.field, method, parameters)
: statement("$T.$N($L)", goal.builders.type, method, parameters));
return builder.build();
}
private static CodeBlock invocationParameters(List parameterNames) {
return CodeBlock.of(String.join(", ", parameterNames));
}
private BuilderContextV() {
throw new UnsupportedOperationException("no instances");
}
}