You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

PropertyResolver.java 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /*
  2. * SonarScanner CLI
  3. * Copyright (C) 2011-2022 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. package org.sonarsource.scanner.cli;
  21. import java.util.LinkedList;
  22. import java.util.List;
  23. import java.util.Map;
  24. import java.util.Properties;
  25. import java.util.regex.Matcher;
  26. import java.util.regex.Pattern;
  27. public class PropertyResolver {
  28. private static final Pattern placeholderPattern = Pattern.compile("\\$\\{([\\w\\.]+)\\}");
  29. private final Properties props;
  30. private final Properties resolved;
  31. private final List<String> queue;
  32. private Map<String, String> env;
  33. public PropertyResolver(Properties props, Map<String, String> env) {
  34. this.props = props;
  35. this.env = env;
  36. this.resolved = new Properties();
  37. this.queue = new LinkedList<>();
  38. }
  39. public Properties resolve() {
  40. for (Map.Entry<Object, Object> e : props.entrySet()) {
  41. if (resolved.containsKey(e.getKey())) {
  42. continue;
  43. }
  44. resolveProperty((String) e.getKey());
  45. }
  46. return resolved;
  47. }
  48. private String getValue(String key) {
  49. String propValue;
  50. if (key.startsWith("env.")) {
  51. String envKey = key.substring(4);
  52. propValue = env.get(envKey);
  53. } else {
  54. propValue = props.getProperty(key);
  55. }
  56. return propValue != null ? propValue : "";
  57. }
  58. private String resolveProperty(String propKey) {
  59. String propValue = getValue(propKey);
  60. if (propValue.isEmpty()) {
  61. resolved.setProperty(propKey, propValue);
  62. return propValue;
  63. }
  64. Matcher m = placeholderPattern.matcher(propValue);
  65. StringBuffer sb = new StringBuffer();
  66. while (m.find()) {
  67. String varName = (null == m.group(1)) ? m.group(2) : m.group(1);
  68. if (queue.contains(varName)) {
  69. throw new IllegalArgumentException("Found a loop resolving place holders in properties, for variable: " + varName);
  70. }
  71. String placeholderValue = resolveVar(varName);
  72. m.appendReplacement(sb, Matcher.quoteReplacement(placeholderValue));
  73. }
  74. m.appendTail(sb);
  75. String resolvedPropValue = sb.toString();
  76. resolved.setProperty(propKey, resolvedPropValue);
  77. return resolvedPropValue;
  78. }
  79. private String resolveVar(String varName) {
  80. String placeholderValue;
  81. if (resolved.containsKey(varName)) {
  82. placeholderValue = resolved.getProperty(varName);
  83. } else {
  84. queue.add(varName);
  85. placeholderValue = resolveProperty(varName);
  86. queue.remove(varName);
  87. }
  88. return placeholderValue;
  89. }
  90. }