net.zerobuilder.compiler.generate.GoalContextFactory Maven / Gradle / Ivy
package net.zerobuilder.compiler.generate;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.TypeName;
import net.zerobuilder.compiler.generate.DtoBeanParameter.AbstractBeanParameter;
import net.zerobuilder.compiler.generate.DtoBeanParameter.AccessorPair;
import net.zerobuilder.compiler.generate.DtoBeanParameter.LoneGetter;
import net.zerobuilder.compiler.generate.DtoBeanStep.AbstractBeanStep;
import net.zerobuilder.compiler.generate.DtoBeanStep.AccessorPairStep;
import net.zerobuilder.compiler.generate.DtoBeanStep.LoneGetterStep;
import net.zerobuilder.compiler.generate.DtoGoal.ConstructorGoalDetails;
import net.zerobuilder.compiler.generate.DtoGoal.MethodGoalDetails;
import net.zerobuilder.compiler.generate.DtoGoal.RegularGoalCases;
import net.zerobuilder.compiler.generate.DtoGoalContext.IGoal;
import net.zerobuilder.compiler.generate.DtoGoalDescription.BeanGoalDescription;
import net.zerobuilder.compiler.generate.DtoGoalDescription.GoalDescription;
import net.zerobuilder.compiler.generate.DtoGoalDescription.GoalDescriptionCases;
import net.zerobuilder.compiler.generate.DtoGoalDescription.RegularGoalDescription;
import net.zerobuilder.compiler.generate.DtoParameter.AbstractParameter;
import net.zerobuilder.compiler.generate.DtoParameter.RegularParameter;
import net.zerobuilder.compiler.generate.DtoRegularGoalContext.ConstructorGoal;
import net.zerobuilder.compiler.generate.DtoRegularGoalContext.MethodGoal;
import net.zerobuilder.compiler.generate.DtoStep.AbstractStep;
import net.zerobuilder.compiler.generate.DtoStep.RegularStep;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import static net.zerobuilder.compiler.generate.DtoGoalContext.contractName;
import static net.zerobuilder.compiler.generate.DtoGoalDescription.asFunction;
import static net.zerobuilder.compiler.generate.DtoGoalDescription.goalName;
import static net.zerobuilder.compiler.generate.DtoGoalDescription.goalType;
import static net.zerobuilder.compiler.generate.DtoParameter.parameterName;
import static net.zerobuilder.compiler.generate.Utilities.reverse;
import static net.zerobuilder.compiler.generate.Utilities.upcase;
final class GoalContextFactory {
static Function prepareGoal(final ClassName generatedType) {
return DtoGoalDescription.asFunction(new GoalDescriptionCases() {
@Override
public IGoal regularGoal(RegularGoalDescription goal) {
return GoalContextFactory.regularGoal(generatedType, goal);
}
@Override
public IGoal beanGoal(BeanGoalDescription goal) {
return GoalContextFactory.beanGoal(goal, generatedType);
}
});
}
private static IGoal beanGoal(BeanGoalDescription goal, ClassName generatedType) {
List extends AbstractBeanStep> steps = steps(goal,
generatedType,
goal.parameters,
beansParameterFactory);
return DtoBeanGoalContext.BeanGoal.create(goal.details, steps);
}
private static IGoal regularGoal(ClassName generatedType,
final RegularGoalDescription validGoal) {
final List steps = steps(validGoal,
generatedType,
validGoal.parameters,
regularParameterFactory);
return DtoGoal.asFunction(new RegularGoalCases() {
@Override
public IGoal method(MethodGoalDetails goal) {
return MethodGoal.create(goal, steps, validGoal.thrownTypes);
}
@Override
public IGoal constructor(ConstructorGoalDetails goal) {
return ConstructorGoal.create(goal, steps, validGoal.thrownTypes);
}
}).apply(validGoal.details);
}
private static
List steps(GoalDescription goal,
ClassName generatedType,
List
parameters,
ParameterFactory
parameterFactory) {
ClassName contractName = contractName(goalName(goal), generatedType);
TypeName nextType = goalType(goal);
List thrownTypes = GoalContextFactory.thrownTypes.apply(goal);
List builder = new ArrayList<>();
for (P parameter : reverse(parameters)) {
String thisName = upcase(parameterName.apply(parameter));
ClassName thisType = contractName.nestedClass(thisName);
builder.add(parameterFactory.create(thisType, nextType, parameter, thrownTypes));
nextType = thisType;
}
return reverse(builder);
}
private static abstract class ParameterFactory {
abstract R create(ClassName typeThisStep, TypeName typeNextStep, P parameter, List declaredExceptions);
}
private static final ParameterFactory beansParameterFactory
= new ParameterFactory() {
@Override
AbstractBeanStep create(final ClassName thisType, final TypeName nextType, final AbstractBeanParameter validParameter, List declaredExceptions) {
return validParameter.accept(new DtoBeanParameter.BeanParameterCases() {
@Override
public AbstractBeanStep accessorPair(AccessorPair pair) {
String setter = "set" + upcase(parameterName.apply(pair));
return AccessorPairStep.create(thisType, nextType, pair, setter);
}
@Override
public AbstractBeanStep loneGetter(LoneGetter loneGetter) {
return LoneGetterStep.create(thisType, nextType, loneGetter);
}
});
}
};
private static final ParameterFactory regularParameterFactory
= new ParameterFactory() {
@Override
RegularStep create(ClassName thisType, TypeName nextType, RegularParameter validParameter, List declaredExceptions) {
return RegularStep.create(thisType, nextType, validParameter, declaredExceptions);
}
};
private static final Function> thrownTypes
= asFunction(new GoalDescriptionCases>() {
@Override
public List regularGoal(RegularGoalDescription goal) {
return goal.thrownTypes;
}
@Override
public List beanGoal(BeanGoalDescription goal) {
return Collections.emptyList();
}
});
}