fix #123 allow to specify extra annotations on repositories/methods
[yosql.git] / yosql-codegen / src / main / java / wtf / metio / yosql / codegen / files / DefaultMethodParameterConfigurer.java
blobfaeda2a02d4b4481dd5ef766affeeceb1485006b
1 /*
2 * This file is part of yosql. It is subject to the license terms in the LICENSE file found in the top-level
3 * directory of this distribution and at https://creativecommons.org/publicdomain/zero/1.0/. No part of yosql,
4 * including this file, may be copied, modified, propagated, or distributed except according to the terms contained
5 * in the LICENSE file.
6 */
8 package wtf.metio.yosql.codegen.files;
10 import ch.qos.cal10n.IMessageConveyor;
11 import org.slf4j.cal10n.LocLogger;
12 import wtf.metio.yosql.codegen.lifecycle.ValidationErrors;
13 import wtf.metio.yosql.codegen.orchestration.ExecutionErrors;
14 import wtf.metio.yosql.models.configuration.SqlParameter;
15 import wtf.metio.yosql.models.immutables.SqlConfiguration;
17 import java.nio.file.Path;
18 import java.util.ArrayList;
19 import java.util.List;
20 import java.util.Map;
21 import java.util.Optional;
22 import java.util.function.Predicate;
23 import java.util.stream.Collectors;
25 public final class DefaultMethodParameterConfigurer implements MethodParameterConfigurer {
27 private final LocLogger logger;
28 private final ExecutionErrors errors;
29 private final IMessageConveyor messages;
31 public DefaultMethodParameterConfigurer(
32 final LocLogger logger,
33 final ExecutionErrors errors,
34 final IMessageConveyor messages) {
35 this.logger = logger;
36 this.errors = errors;
37 this.messages = messages;
40 @Override
41 public SqlConfiguration configureParameters(final SqlConfiguration configuration, final Path source, final Map<String, List<Integer>> parameterIndices) {
42 final var currentParameters = configuration.parameters();
43 if (parametersAreValid(source, parameterIndices, configuration)) {
44 final var updatedParameters = updateIndices(currentParameters, parameterIndices);
45 final var allParameters = addMissingParameters(updatedParameters, parameterIndices);
46 return SqlConfiguration.copyOf(configuration).withParameters(allParameters);
48 return configuration;
51 private boolean parametersAreValid(
52 final Path source,
53 final Map<String, List<Integer>> parameterIndices,
54 final SqlConfiguration configuration) {
55 final var parameterErrors = configuration.parameters()
56 .stream()
57 .map(SqlParameter::name)
58 .flatMap(Optional::stream)
59 .filter(name -> !parameterIndices.containsKey(name))
60 .map(name -> messages.getMessage(ValidationErrors.UNKNOWN_PARAMETER, source, name))
61 .peek(errors::illegalArgument)
62 .peek(logger::error)
63 .toList();
64 return parameterErrors.isEmpty();
67 private static List<SqlParameter> updateIndices(final List<SqlParameter> parameters, final Map<String, List<Integer>> indices) {
68 return parameters.stream()
69 .map(parameter -> SqlParameter.copyOf(parameter)
70 .withIndices(parameter.name()
71 .map(indices::get)
72 .map(DefaultMethodParameterConfigurer::asIntArray)))
73 .collect(Collectors.toList());
76 private static int[] asIntArray(final List<Integer> numbers) {
77 return numbers.stream()
78 .mapToInt(Integer::intValue)
79 .toArray();
82 private static List<SqlParameter> addMissingParameters(final List<SqlParameter> parameters, final Map<String, List<Integer>> indices) {
83 final var all = new ArrayList<>(parameters);
84 for (final var entry : indices.entrySet()) {
85 final var parameterName = entry.getKey();
86 if (isMissingParameter(all, parameterName)) {
87 all.add(SqlParameter.builder()
88 .setName(parameterName)
89 .setType("java.lang.Object")
90 .setIndices(asIntArray(entry.getValue()))
91 .build());
94 return all;
97 private static boolean isMissingParameter(final List<SqlParameter> parameters, final String parameterName) {
98 return parameters.stream().noneMatch(nameMatches(parameterName));
101 private static Predicate<? super SqlParameter> nameMatches(final String parameterName) {
102 return parameter -> parameter.name()
103 .map(parameterName::equals)
104 .orElse(Boolean.FALSE);