ExternalInterpolator.java
package io.github.giulong.spectrum.internals.jackson.deserializers.interpolation.interpolators;
import static java.util.stream.Collectors.joining;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import com.fasterxml.jackson.annotation.JsonPropertyDescription;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonStreamContext;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Getter
public abstract class ExternalInterpolator extends Interpolator {
@SuppressWarnings("unused")
@JsonPropertyDescription("Variable prefix")
private String prefix;
@SuppressWarnings("unused")
@JsonPropertyDescription("Variable tokens' delimiter")
private String delimiter;
@SuppressWarnings("unused")
@JsonPropertyDescription("Function to specify how to transform the original camelCase of the key to match the external variable to search")
private TransformCase transformCase;
public abstract Function<String, String> getConsumer();
@Override
public Optional<String> findVariableFor(final String value, final JsonParser jsonParser) {
final String className = getClass().getSimpleName();
final List<String> keyPathTokens = new ArrayList<>();
keyPathTokens.add(prefix);
getKeyPathTokens(keyPathTokens, jsonParser.getParsingContext());
final String keyPath = keyPathTokens
.stream()
.filter(Objects::nonNull)
.collect(joining(delimiter));
final String transformedKeyPath = transformCase.getFunction().apply(keyPath);
log.trace("{} is looking for {}", className, transformedKeyPath);
final String key = getConsumer().apply(transformedKeyPath);
if (key != null) {
log.debug("{} found {} = {}", className, transformedKeyPath, key);
return Optional.of(key);
}
return Optional.empty();
}
void getKeyPathTokens(final List<String> accumulator, final JsonStreamContext context) {
final JsonStreamContext parentContext = context.getParent();
if (parentContext != null) {
getKeyPathTokens(accumulator, parentContext);
accumulator.add(context.getCurrentName());
}
}
@Getter
@AllArgsConstructor
enum TransformCase {
NONE(s -> s),
LOWER(String::toLowerCase),
UPPER(String::toUpperCase);
private final Function<String, String> function;
}
}