diff --git a/license-maven-plugin/pom.xml b/license-maven-plugin/pom.xml index a97d2ef04..f5f4124ad 100755 --- a/license-maven-plugin/pom.xml +++ b/license-maven-plugin/pom.xml @@ -47,10 +47,15 @@ license com.mycila.maven.plugin.license + + true default-descriptor + + descriptor + process-classes @@ -59,6 +64,7 @@ helpmojo + process-classes @@ -70,13 +76,14 @@ src/test/** src/it/** src/main/resources/** + **/PropertyPlaceholderResolver.java maven-javadoc-plugin - -Xdoclint:none + **/*Mojo.java @@ -132,11 +139,6 @@ 3.3.3 - - org.springframework - spring-core - - com.mycila mycila-xmltool diff --git a/license-maven-plugin/src/main/java/com/mycila/maven/plugin/license/document/Document.java b/license-maven-plugin/src/main/java/com/mycila/maven/plugin/license/document/Document.java index e39f7e662..f3585f210 100755 --- a/license-maven-plugin/src/main/java/com/mycila/maven/plugin/license/document/Document.java +++ b/license-maven-plugin/src/main/java/com/mycila/maven/plugin/license/document/Document.java @@ -21,7 +21,6 @@ import com.mycila.maven.plugin.license.header.HeaderType; import com.mycila.maven.plugin.license.util.FileContent; import com.mycila.maven.plugin.license.util.FileUtils; -import org.springframework.util.PropertyPlaceholderHelper; import java.io.File; import java.io.IOException; @@ -38,7 +37,7 @@ public final class Document { private final String encoding; private final String[] keywords; private final DocumentPropertiesLoader documentPropertiesLoader; - private final PropertyPlaceholderHelper placeholderHelper = new PropertyPlaceholderHelper("${", "}", ":", true); + private final PropertyPlaceholderResolver placeholderResolver = new PropertyPlaceholderResolver(); private HeaderParser parser; @@ -94,7 +93,7 @@ public void updateHeader(Header header) { } public String mergeProperties(String str) { - return placeholderHelper.replacePlaceholders(str, documentPropertiesLoader.load(this)); + return placeholderResolver.replacePlaceholders(str, documentPropertiesLoader.load(this)); } public void save() { diff --git a/license-maven-plugin/src/main/java/com/mycila/maven/plugin/license/document/PropertyPlaceholderResolver.java b/license-maven-plugin/src/main/java/com/mycila/maven/plugin/license/document/PropertyPlaceholderResolver.java new file mode 100644 index 000000000..d06c55bed --- /dev/null +++ b/license-maven-plugin/src/main/java/com/mycila/maven/plugin/license/document/PropertyPlaceholderResolver.java @@ -0,0 +1,128 @@ +/* + * Copyright 2002-2019 the original author or 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 + * + * https://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 com.mycila.maven.plugin.license.document; + +import java.util.HashSet; +import java.util.Properties; +import java.util.Set; +import java.util.function.Function; + +/** + * Copy and simplification of Spring's PropertyPlaceholderHelper at + * https://github.com/spring-projects/spring-framework/blob/master/spring-core/src/main/java/org/springframework/util/PropertyPlaceholderHelper.java + *

+ * Utility class for working with Strings that have placeholder values in them. A placeholder takes the form + * {@code ${name}}. Using {@code PropertyPlaceholderHelper} these placeholders can be substituted for + * user-supplied values.

Values for substitution can be supplied using a {@link Properties} instance or + * using a {@link Function}. + * + * @author Juergen Hoeller + * @author Rob Harrop + * @since 3.0 + */ +class PropertyPlaceholderResolver { + + private final String placeholderPrefix = "${"; + private final String placeholderSuffix = "}"; + + public String replacePlaceholders(String value, final Properties properties) { + return replacePlaceholders(value, properties::getProperty); + } + + private String replacePlaceholders(String value, Function placeholderResolver) { + return parseStringValue(value, placeholderResolver, new HashSet<>()); + } + + private String parseStringValue(String value, Function placeholderResolver, Set visitedPlaceholders) { + StringBuilder result = new StringBuilder(value); + int startIndex = value.indexOf(this.placeholderPrefix); + while (startIndex != -1) { + int endIndex = findPlaceholderEndIndex(result, startIndex); + if (endIndex != -1) { + String placeholder = result.substring(startIndex + this.placeholderPrefix.length(), endIndex); + String originalPlaceholder = placeholder; + if (!visitedPlaceholders.add(originalPlaceholder)) { + throw new IllegalArgumentException("Circular placeholder reference '" + originalPlaceholder + "' in property definitions"); + } + // Recursive invocation, parsing placeholders contained in the placeholder key. + placeholder = parseStringValue(placeholder, placeholderResolver, visitedPlaceholders); + // Now obtain the value for the fully resolved key... + String propVal = placeholderResolver.apply(placeholder); + String valueSeparator = ":"; + if (propVal == null) { + int separatorIndex = placeholder.indexOf(valueSeparator); + if (separatorIndex != -1) { + String actualPlaceholder = placeholder.substring(0, separatorIndex); + String defaultValue = placeholder.substring(separatorIndex + valueSeparator.length()); + propVal = placeholderResolver.apply(actualPlaceholder); + if (propVal == null) { + propVal = defaultValue; + } + } + } + if (propVal != null) { + // Recursive invocation, parsing placeholders contained in the + // previously resolved placeholder value. + propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders); + result.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal); + startIndex = result.indexOf(this.placeholderPrefix, startIndex + propVal.length()); + } else { + // Proceed with unprocessed value. + startIndex = result.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length()); + } + visitedPlaceholders.remove(originalPlaceholder); + } else { + startIndex = -1; + } + } + + return result.toString(); + } + + private int findPlaceholderEndIndex(CharSequence buf, int startIndex) { + int index = startIndex + this.placeholderPrefix.length(); + int withinNestedPlaceholder = 0; + while (index < buf.length()) { + String simplePrefix = "{"; + if (substringMatch(buf, index, this.placeholderSuffix)) { + if (withinNestedPlaceholder > 0) { + withinNestedPlaceholder--; + index = index + this.placeholderSuffix.length(); + } else { + return index; + } + } else if (substringMatch(buf, index, simplePrefix)) { + withinNestedPlaceholder++; + index = index + simplePrefix.length(); + } else { + index++; + } + } + return -1; + } + + private static boolean substringMatch(CharSequence str, int index, CharSequence substring) { + if (index + substring.length() > str.length()) { + return false; + } + for (int i = 0; i < substring.length(); i++) { + if (str.charAt(index + i) != substring.charAt(i)) { + return false; + } + } + return true; + } +} diff --git a/pom.xml b/pom.xml index 3e7a52c76..610edbcfe 100644 --- a/pom.xml +++ b/pom.xml @@ -22,8 +22,7 @@ com.mycila mycila-pom - 3 - + 9 license-maven-plugin-parent @@ -72,11 +71,6 @@ maven-plugin-annotations 3.6.0 - - org.springframework - spring-core - 4.3.19.RELEASE - com.mycila mycila-xmltool @@ -99,7 +93,6 @@ junit ${junit.version} - @@ -108,7 +101,7 @@ org.apache.maven.plugins maven-plugin-plugin - 3.2 + 3.6.0 org.apache.maven.plugins @@ -141,13 +134,18 @@ maven-gpg-plugin - 1.4 + 1.6 false ${gpg.keyname} ${gpg.passphrase} + + org.apache.maven.plugins + maven-plugin-plugin + 3.6.0 +