This is an automated email from the ASF dual-hosted git repository. sjaranowski pushed a commit to branch MNG-5222 in repository https://gitbox.apache.org/repos/asf/maven.git
commit cef451673081be469e789055f75ec08cb1dd06cb Author: Slawomir Jaranowski <[email protected]> AuthorDate: Fri Apr 15 20:52:02 2022 +0200 [MNG-5222] Improvement in deprecated params detection --- .../plugin/internal/DefaultMavenPluginManager.java | 9 +- .../plugin/internal/DeprecatedPluginValidator.java | 133 +++++++++++++++++++++ .../MavenPluginConfigurationValidator.java | 39 ++++++ .../internal/ValidatingConfigurationListener.java | 117 +----------------- 4 files changed, 180 insertions(+), 118 deletions(-) diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java index 66a49cb3d..51c49c84f 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java @@ -143,6 +143,7 @@ public class DefaultMavenPluginManager private PluginVersionResolver pluginVersionResolver; private PluginArtifactsCache pluginArtifactsCache; private MavenPluginValidator pluginValidator; + private MavenPluginConfigurationValidator configurationValidator; private final ExtensionDescriptorBuilder extensionDescriptorBuilder = new ExtensionDescriptorBuilder(); private final PluginDescriptorBuilder builder = new PluginDescriptorBuilder(); @@ -158,7 +159,8 @@ public class DefaultMavenPluginManager ExtensionRealmCache extensionRealmCache, PluginVersionResolver pluginVersionResolver, PluginArtifactsCache pluginArtifactsCache, - MavenPluginValidator pluginValidator ) + MavenPluginValidator pluginValidator, + MavenPluginConfigurationValidator configurationValidator ) { this.container = container; this.classRealmManager = classRealmManager; @@ -170,6 +172,7 @@ public class DefaultMavenPluginManager this.pluginVersionResolver = pluginVersionResolver; this.pluginArtifactsCache = pluginArtifactsCache; this.pluginValidator = pluginValidator; + this.configurationValidator = configurationValidator; } public synchronized PluginDescriptor getPluginDescriptor( Plugin plugin, List<RemoteRepository> repositories, @@ -603,6 +606,8 @@ public class DefaultMavenPluginManager ExpressionEvaluator expressionEvaluator = new PluginParameterExpressionEvaluator( session, mojoExecution ); + configurationValidator.validate( mojoDescriptor, pomConfiguration, expressionEvaluator ); + populateMojoExecutionFields( mojo, mojoExecution.getExecutionId(), mojoDescriptor, pluginRealm, pomConfiguration, expressionEvaluator ); @@ -638,7 +643,7 @@ public class DefaultMavenPluginManager ConfigurationListener listener = new DebugConfigurationListener( logger ); ValidatingConfigurationListener validator = - new ValidatingConfigurationListener( mojo, mojoDescriptor, listener, expressionEvaluator ); + new ValidatingConfigurationListener( mojo, mojoDescriptor, listener ); logger.debug( "Configuring mojo execution '" + mojoDescriptor.getId() + ':' + executionId + "' with " + configuratorId + " configurator -->" ); diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/DeprecatedPluginValidator.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/DeprecatedPluginValidator.java new file mode 100644 index 000000000..03beb16e5 --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/DeprecatedPluginValidator.java @@ -0,0 +1,133 @@ +package org.apache.maven.plugin.internal; + +/* + * 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. + */ + +import javax.inject.Named; +import javax.inject.Singleton; + +import org.apache.maven.plugin.descriptor.MojoDescriptor; +import org.apache.maven.plugin.descriptor.Parameter; +import org.apache.maven.shared.utils.logging.MessageUtils; +import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException; +import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator; +import org.codehaus.plexus.configuration.PlexusConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Print warnings if deprecated params of plugin are used in configuration. + * + * @author Slawomir Jaranowski + */ +@Named +@Singleton +class DeprecatedPluginValidator implements MavenPluginConfigurationValidator +{ + private static final Logger LOGGER = LoggerFactory.getLogger( DeprecatedPluginValidator.class ); + + @Override + public void validate( MojoDescriptor mojoDescriptor, + PlexusConfiguration pomConfiguration, + ExpressionEvaluator expressionEvaluator ) + { + if ( !LOGGER.isWarnEnabled() ) + { + return; + } + + if ( mojoDescriptor.getParameters() == null ) + { + return; + } + + mojoDescriptor.getParameters().stream() + .filter( parameter -> parameter.getDeprecated() != null ) + .filter( Parameter::isEditable ) + .forEach( parameter -> checkParameter( parameter, pomConfiguration, expressionEvaluator ) ); + } + + private static void checkParameter( Parameter parameter, + PlexusConfiguration pomConfiguration, + ExpressionEvaluator expressionEvaluator ) + { + PlexusConfiguration config = pomConfiguration.getChild( parameter.getName(), false ); + + if ( isValueSet( config, expressionEvaluator ) ) + { + logDeprecateWarn( parameter ); + } + } + + private static boolean isValueSet( PlexusConfiguration config, + ExpressionEvaluator expressionEvaluator ) + { + if ( config == null ) + { + return false; + } + + // there are sub items ... so configuration is declared + if (config.getChildCount() > 0 ) + { + return true; + } + + String strValue = config.getValue(); + + if ( strValue == null || strValue.isEmpty() ) + { + return false; + } + + // for declaration like @Parameter( property = "config.property" ) + // the value will contains ${config.property} + try + { + return expressionEvaluator.evaluate( strValue ) != null; + } + catch ( ExpressionEvaluationException e ) + { + // not important + // will be reported during Mojo fields populate + } + + // fallback - in case of error in expressionEvaluator + return false; + } + + private static void logDeprecateWarn( Parameter parameter ) + { + StringBuilder sb = new StringBuilder(); + sb.append( "Parameter '" ); + sb.append( parameter.getName() ); + sb.append( '\'' ); + if ( parameter.getExpression() != null ) + { + String userProperty = parameter.getExpression().replace( "${", "'" ).replace( '}', '\'' ); + sb.append( " (user property " ); + sb.append( userProperty ); + sb.append( ")" ); + } + sb.append( " is deprecated: " ); + sb.append( parameter.getDeprecated() ); + + LOGGER.warn( MessageUtils.buffer().warning( sb.toString() ).toString() ); + } +} diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/MavenPluginConfigurationValidator.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/MavenPluginConfigurationValidator.java new file mode 100644 index 000000000..8252782d3 --- /dev/null +++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/MavenPluginConfigurationValidator.java @@ -0,0 +1,39 @@ +package org.apache.maven.plugin.internal; + +/* + * 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. + */ + +import org.apache.maven.plugin.descriptor.MojoDescriptor; +import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator; +import org.codehaus.plexus.configuration.PlexusConfiguration; + +/** + * Service responsible for validating plugin configuration. + * + * @author Slawomir Jaranowski + */ +interface MavenPluginConfigurationValidator +{ + /** + * Check mojo configuration. + */ + void validate( MojoDescriptor mojoDescriptor, + PlexusConfiguration pomConfiguration, + ExpressionEvaluator expressionEvaluator ); +} diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/ValidatingConfigurationListener.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/ValidatingConfigurationListener.java index 75b5cb4f7..c04f44821 100644 --- a/maven-core/src/main/java/org/apache/maven/plugin/internal/ValidatingConfigurationListener.java +++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/ValidatingConfigurationListener.java @@ -19,22 +19,13 @@ package org.apache.maven.plugin.internal; * under the License. */ -import java.lang.reflect.Array; import java.util.Collection; import java.util.HashMap; -import java.util.Iterator; import java.util.Map; -import java.util.Objects; -import java.util.StringJoiner; import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.plugin.descriptor.Parameter; -import org.apache.maven.shared.utils.logging.MessageUtils; import org.codehaus.plexus.component.configurator.ConfigurationListener; -import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException; -import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * A configuration listener to help validate the plugin configuration. For instance, check for required but missing @@ -45,25 +36,16 @@ import org.slf4j.LoggerFactory; class ValidatingConfigurationListener implements ConfigurationListener { - private static final Logger LOGGER = LoggerFactory.getLogger( ValidatingConfigurationListener.class ); - private final Object mojo; private final ConfigurationListener delegate; - private final MojoDescriptor mojoDescriptor; - private final ExpressionEvaluator expressionEvaluator; - - private final Map<String, Parameter> missingParameters; - ValidatingConfigurationListener( Object mojo, MojoDescriptor mojoDescriptor, ConfigurationListener delegate, - ExpressionEvaluator expressionEvaluator ) + ValidatingConfigurationListener( Object mojo, MojoDescriptor mojoDescriptor, ConfigurationListener delegate ) { this.mojo = mojo; this.delegate = delegate; - this.mojoDescriptor = mojoDescriptor; - this.expressionEvaluator = expressionEvaluator; this.missingParameters = new HashMap<>(); if ( mojoDescriptor.getParameters() != null ) @@ -109,102 +91,5 @@ class ValidatingConfigurationListener { missingParameters.remove( fieldName ); } - - if ( LOGGER.isWarnEnabled() ) - { - warnDeprecated( fieldName, value ); - } - } - - private void warnDeprecated( String fieldName, Object value ) - { - Parameter parameter = mojoDescriptor.getParameterMap().get( fieldName ); - String deprecated = parameter.getDeprecated(); - if ( deprecated != null ) - { - Object defaultValue = evaluateValue( parameter.getDefaultValue() ); - if ( !Objects.equals( toString( value ), defaultValue ) ) - { - StringBuilder sb = new StringBuilder(); - sb.append( " Parameter '" ); - sb.append( fieldName ); - sb.append( '\'' ); - if ( parameter.getExpression() != null ) - { - String userProperty = parameter.getExpression().replace( "${", "'" ).replace( '}', '\'' ); - sb.append( " (user property " ); - sb.append( userProperty ); - sb.append( ")" ); - } - sb.append( " is deprecated: " ); - sb.append( deprecated ); - - LOGGER.warn( MessageUtils.buffer().warning( sb.toString() ).toString() ); - } - } - } - - private Object evaluateValue( String value ) - { - try - { - return expressionEvaluator.evaluate( value ); - } - catch ( ExpressionEvaluationException e ) - { - // should not happen here - } - return value; - } - - /** - * Creates a string representation of the specified object for comparing with default values. - * - * @param obj The object to create a string representation for, may be <code>null</code>. - * @return The string representation, null for empty arrays / collections. - */ - private static String toString( Object obj ) - { - String str; - if ( obj != null && obj.getClass().isArray() ) - { - int n = Array.getLength( obj ); - if ( n == 0 ) - { - str = null; - } - else - { - StringJoiner sj = new StringJoiner( "," ); - for ( int i = 0; i < n; i++ ) - { - sj.add( String.valueOf( Array.get( obj, i ) ) ); - } - str = sj.toString(); - } - } - else if ( obj instanceof Collection ) - { - Collection<?> collection = (Collection<?>) obj; - if ( collection.isEmpty() ) - { - str = null; - } - else - { - Iterator<?> it = collection.iterator(); - StringJoiner sj = new StringJoiner( "," ); - while ( it.hasNext() ) - { - sj.add( String.valueOf( it.next() ) ); - } - str = sj.toString(); - } - } - else - { - str = String.valueOf( obj ); - } - return str; } }
