[ https://issues.apache.org/jira/browse/MNG-7914?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17863176#comment-17863176 ]
ASF GitHub Bot commented on MNG-7914: ------------------------------------- gnodet commented on code in PR #1595: URL: https://github.com/apache/maven/pull/1595#discussion_r1666555646 ########## maven-embedder/src/main/java/org/apache/maven/cli/props/InterpolationHelper.java: ########## @@ -0,0 +1,364 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 org.apache.maven.cli.props; + +import java.util.HashMap; +import java.util.Map; + +public class InterpolationHelper { + + private InterpolationHelper() {} + + private static final char ESCAPE_CHAR = '\\'; + private static final String DELIM_START = "${"; + private static final String DELIM_STOP = "}"; + private static final String MARKER = "$__"; + private static final String ENV_PREFIX = "env:"; + + /** + * Callback for substitution + */ + public interface SubstitutionCallback { + + String getValue(String key); + } + + /** + * Perform substitution on a property set + * + * @param properties the property set to perform substitution on + * @param callback Callback for substituion + */ + public static void performSubstitution(Map<String, String> properties, SubstitutionCallback callback) { + performSubstitution(properties, callback, true, true, true); + } + + /** + * Perform substitution on a property set + * + * @param properties the property set to perform substitution on + * @param callback the callback to obtain substitution values + * @param substituteFromConfig If substitute from configuration + * @param substituteFromSystemProperties If substitute from system properties + * @param defaultsToEmptyString sets an empty string if a replacement value is not found, leaves intact otherwise + */ + public static void performSubstitution( + Map<String, String> properties, + SubstitutionCallback callback, + boolean substituteFromConfig, + boolean substituteFromSystemProperties, + boolean defaultsToEmptyString) { + Map<String, String> org = new HashMap<>(properties); + for (String name : properties.keySet()) { + properties.compute( + name, + (k, value) -> substVars( + value, + name, + null, + org, + callback, + substituteFromConfig, + substituteFromSystemProperties, + defaultsToEmptyString)); + } + } + + /** + * <p> + * This method performs property variable substitution on the + * specified value. If the specified value contains the syntax + * {@code ${<prop-name>}}, where {@code <prop-name>} + * refers to either a configuration property or a system property, + * then the corresponding property value is substituted for the variable + * placeholder. Multiple variable placeholders may exist in the + * specified value as well as nested variable placeholders, which + * are substituted from inner most to outer most. Configuration + * properties override system properties. + * </p> + * + * @param val The string on which to perform property substitution. + * @param currentKey The key of the property being evaluated used to + * detect cycles. + * @param cycleMap Map of variable references used to detect nested cycles. + * @param configProps Set of configuration properties. + * @return The value of the specified string after system property substitution. + * @throws IllegalArgumentException If there was a syntax error in the + * property placeholder syntax or a recursive variable reference. + **/ + public static String substVars( + String val, String currentKey, Map<String, String> cycleMap, Map<String, String> configProps) + throws IllegalArgumentException { + return substVars(val, currentKey, cycleMap, configProps, (SubstitutionCallback) null); + } + + /** + * <p> + * This method performs property variable substitution on the + * specified value. If the specified value contains the syntax + * {@code ${<prop-name>}}, where {@code <prop-name>} + * refers to either a configuration property or a system property, + * then the corresponding property value is substituted for the variable + * placeholder. Multiple variable placeholders may exist in the + * specified value as well as nested variable placeholders, which + * are substituted from inner most to outer most. Configuration + * properties override system properties. + * </p> + * + * @param val The string on which to perform property substitution. + * @param currentKey The key of the property being evaluated used to + * detect cycles. + * @param cycleMap Map of variable references used to detect nested cycles. + * @param configProps Set of configuration properties. + * @param callback the callback to obtain substitution values + * @return The value of the specified string after system property substitution. + * @throws IllegalArgumentException If there was a syntax error in the + * property placeholder syntax or a recursive variable reference. + **/ + public static String substVars( + String val, + String currentKey, + Map<String, String> cycleMap, + Map<String, String> configProps, + SubstitutionCallback callback) + throws IllegalArgumentException { Review Comment: I'll fix that. Fwiw, those three classes come from Karaf/Felix. They even provide a bit more, as they can even be used to programmatically modify properties file while keeping layout and comments (though I don't think we'll need that in the short term), or even typed properties (not included here). > Provide a single entry point for configuration > ---------------------------------------------- > > Key: MNG-7914 > URL: https://issues.apache.org/jira/browse/MNG-7914 > Project: Maven > Issue Type: New Feature > Reporter: Guillaume Nodet > Priority: Major > Fix For: 4.0.x-candidate > > > Looking at MNG-7772, this should not require any code change, but it's all > about configuration. > I propose to load / interpolate the following files: > * {{${maven.home}/conf/maven.user.properties}} > * {{${maven.home}/conf/maven.system.properties}} > Those files would be used to load additional user properties and system > properties for Maven. In addition to the simple interpolation mechanism, we > should provide two enhancements using special keys {{{}$\{includes{}}}} and > {{{}$\{optionals{}}}} which would be used to load additional referenced > configuration files such as: > {{ ${optionals} = ${user.home}/.m2/maven.user.properties, > ${session.rootDirectory}/.mvn/maven.user.properties}} > Being loaded early when Maven is loaded, those files could reference > directories to load extensions from: > {{{}maven.core.extensions.directories = > ${session.rootDirectory}/.mvn/extensions.xml,{}}}{{{}${user.home}/.m2/extensions.xml,${maven.home}/extensions.xml{}}} > > In various places, the maven code could be simplified and offer more > configuration points at the same time. -- This message was sent by Atlassian Jira (v8.20.10#820010)