
io.micronaut.context.env.DefaultPropertyPlaceholderResolver Maven / Gradle / Ivy
/*
* Copyright 2017-2018 original authors
*
* 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 io.micronaut.context.env;
import io.micronaut.context.exceptions.ConfigurationException;
import io.micronaut.core.util.StringUtils;
import io.micronaut.core.value.PropertyResolver;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* The default {@link PropertyPlaceholderResolver}.
*
* @author graemerocher
* @since 1.0
*/
public class DefaultPropertyPlaceholderResolver implements PropertyPlaceholderResolver {
/**
* Prefix for placeholder in properties.
*/
public static final String PREFIX = "${";
/**
* Suffix for placeholder in properties.
*/
public static final String SUFFIX = "}";
private static final Pattern ESCAPE_SEQUENCE = Pattern.compile("(.+)?:`([^`]+?)`");
private static final Pattern ENVIRONMENT_VAR_SEQUENCE = Pattern.compile("^[\\p{Lu}_{0-9}]+");
private static final char COLON = ':';
private final PropertyResolver environment;
private final String prefix;
/**
* @param environment The property resolver for the environment
*/
public DefaultPropertyPlaceholderResolver(PropertyResolver environment) {
this.environment = environment;
this.prefix = PREFIX;
}
@Override
public String getPrefix() {
return this.prefix;
}
@Override
public Optional resolvePlaceholders(String str) {
try {
int i = str.indexOf(prefix);
if (i > -1) {
return Optional.of(resolvePlaceholders(str, i));
}
return Optional.of(str);
} catch (ConfigurationException e) {
return Optional.empty();
}
}
@Override
public String resolveRequiredPlaceholders(String str) throws ConfigurationException {
int i = str.indexOf(prefix);
if (i > -1) {
return resolvePlaceholders(str, i);
}
return str;
}
/**
* Resolves a replacement for the given expression. Returning true if the replacement was resolved.
*
* @param builder The builder
* @param str The full string
* @param expr The current expression
* @return True if a placeholder was resolved
*/
protected boolean resolveReplacement(StringBuilder builder, String str, String expr) {
if (environment.containsProperty(expr)) {
builder.append(environment.getProperty(expr, String.class).orElseThrow(() -> new ConfigurationException("Could not resolve placeholder ${" + expr + "} in value: " + str)));
return true;
}
return false;
}
private String resolvePlaceholders(String str, int startIndex) {
StringBuilder builder = new StringBuilder(str.substring(0, startIndex));
String restOfString = str.substring(startIndex + 2);
int i = restOfString.indexOf('}');
if (i > -1) {
String expr = restOfString.substring(0, i).trim();
if (restOfString.length() > i) {
restOfString = restOfString.substring(i + 1);
}
resolveExpression(builder, str, expr);
i = restOfString.indexOf(prefix);
if (i > -1) {
builder.append(resolvePlaceholders(restOfString, i));
} else {
builder.append(restOfString);
}
} else {
throw new ConfigurationException("Incomplete placeholder definitions detected: " + str);
}
return builder.toString();
}
private void resolveExpression(StringBuilder builder, String str, String expr) {
String defaultValue = null;
Matcher matcher = ESCAPE_SEQUENCE.matcher(expr);
boolean escaped = false;
if (matcher.find()) {
defaultValue = matcher.group(2);
expr = matcher.group(1);
escaped = true;
} else {
int j = expr.indexOf(COLON);
if (j > -1) {
defaultValue = expr.substring(j + 1);
expr = expr.substring(0, j);
}
}
if (resolveReplacement(builder, str, expr)) {
return;
}
if (ENVIRONMENT_VAR_SEQUENCE.matcher(expr).matches()) {
String v = System.getenv(expr);
if (StringUtils.isNotEmpty(v)) {
builder.append(v);
return;
}
}
if (defaultValue != null) {
if (!escaped && (ESCAPE_SEQUENCE.matcher(defaultValue).find() || defaultValue.indexOf(COLON) > -1)) {
StringBuilder resolved = new StringBuilder();
resolveExpression(resolved, expr, defaultValue);
builder.append(resolved);
} else {
builder.append(defaultValue);
}
return;
}
throw new ConfigurationException("Could not resolve placeholder ${" + expr + "} in value: " + str);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy