Skip to content

Commit

Permalink
introduce MojoUtils to encapsulate Mojo parameter retrieval
Browse files Browse the repository at this point in the history
  • Loading branch information
kwin committed Nov 7, 2022
1 parent 83df9fa commit 36e1c4a
Show file tree
Hide file tree
Showing 5 changed files with 196 additions and 135 deletions.
2 changes: 1 addition & 1 deletion org.eclipse.m2e.core/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %Bundle-Name
Bundle-SymbolicName: org.eclipse.m2e.core;singleton:=true
Bundle-Version: 2.1.0.qualifier
Bundle-Version: 2.0.5.qualifier
Bundle-Activator: org.eclipse.m2e.core.internal.MavenPluginActivator
Bundle-Vendor: %Bundle-Vendor
Bundle-Localization: plugin
Expand Down
22 changes: 0 additions & 22 deletions org.eclipse.m2e.core/src/org/eclipse/m2e/core/embedder/IMaven.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@
import java.util.List;
import java.util.Map;

import org.osgi.annotation.versioning.ProviderType;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;

Expand Down Expand Up @@ -59,7 +57,6 @@
* @author igor
* @noimplement This interface is not intended to be implemented by clients.
*/
@ProviderType
public interface IMaven extends IComponentLookup {

// POM Model read/write operations
Expand Down Expand Up @@ -178,25 +175,6 @@ MojoExecution setupMojoExecution(MavenProject project, MojoExecution execution,
<T> T getMojoParameterValue(MavenProject project, MojoExecution mojoExecution, String parameter,
Class<T> asType, IProgressMonitor monitor) throws CoreException;

/**
* Resolves a nested configuration parameter from the given {@code mojoExecution}. It coerces from String to the given
* type and considers expressions and default values.
*
* @param <T>
* @param project the Maven project
* @param mojoExecution the mojo execution from which to retrieve the configuration value
* @param parameterPath the path of the parameter to look up, the first item is the name of the element directly below
* {@code <configuration>} and the last one is the element containing the actual value
* @param asType the type to coerce to
* @param monitor the progress monitor
* @return the parameter value or {@code null} if the parameter with the given name was not found
* @throws CoreException
* @since 2.1.0
* @see IMaven#getMojoParameterValue(MavenProject, MojoExecution, String, Class, IProgressMonitor)
*/
<T> T getMojoParameterValue(MavenProject project, MojoExecution mojoExecution, List<String> parameterPath,
Class<T> asType, IProgressMonitor monitor) throws CoreException;

/**
* @since 1.4
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,7 @@
import org.eclipse.osgi.util.NLS;

import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.classworlds.realm.ClassRealm;
import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
import org.codehaus.plexus.component.configurator.converters.ConfigurationConverter;
import org.codehaus.plexus.component.configurator.converters.lookup.ConverterLookup;
import org.codehaus.plexus.component.configurator.converters.lookup.DefaultConverterLookup;
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.configuration.PlexusConfiguration;
import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
import org.codehaus.plexus.util.dag.CycleDetectedException;
import org.codehaus.plexus.util.xml.Xpp3Dom;

Expand Down Expand Up @@ -94,16 +86,11 @@
import org.apache.maven.model.building.ModelBuildingRequest;
import org.apache.maven.model.interpolation.ModelInterpolator;
import org.apache.maven.plugin.BuildPluginManager;
import org.apache.maven.plugin.InvalidPluginDescriptorException;
import org.apache.maven.plugin.MavenPluginManager;
import org.apache.maven.plugin.Mojo;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.MojoNotFoundException;
import org.apache.maven.plugin.PluginConfigurationException;
import org.apache.maven.plugin.PluginDescriptorParsingException;
import org.apache.maven.plugin.PluginManagerException;
import org.apache.maven.plugin.PluginNotFoundException;
import org.apache.maven.plugin.PluginParameterExpressionEvaluator;
import org.apache.maven.plugin.PluginResolutionException;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.version.DefaultPluginVersionRequest;
Expand Down Expand Up @@ -158,8 +145,6 @@ public class MavenImpl implements IMaven, IMavenConfigurationChangeListener {
@Reference
private IMavenConfiguration mavenConfiguration;

private final ConverterLookup converterLookup = new DefaultConverterLookup();

@Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
private final List<ISettingsChangeListener> settingsListeners = new CopyOnWriteArrayList<>();

Expand Down Expand Up @@ -709,110 +694,19 @@ private String formatAsDirectory(String directory) {
return directory.replace(GROUP_SEPARATOR, PATH_SEPARATOR);
}

private <T> T getMojoParameterValue(MavenSession session, MojoExecution mojoExecution, List<String> parameterPath,
Class<T> asType) throws CoreException {
Xpp3Dom dom = mojoExecution.getConfiguration();
if(dom == null) {
return null;
}
PlexusConfiguration configuration = new XmlPlexusConfiguration(dom);
for(String parameter : parameterPath) {
configuration = configuration.getChild(parameter);
if(configuration == null) {
return null;
}
}
return getMojoParameterValue(session, mojoExecution, configuration, asType, String.join("/", parameterPath));
}

private <T> T getMojoParameterValue(MavenSession session, MojoExecution mojoExecution,
PlexusConfiguration configuration, Class<T> asType, String parameterLabel) throws CoreException {
try {
MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();

ClassRealm pluginRealm = lookup(BuildPluginManager.class).getPluginRealm(session,
mojoDescriptor.getPluginDescriptor());

ExpressionEvaluator expressionEvaluator = new PluginParameterExpressionEvaluator(session, mojoExecution);
ConfigurationConverter typeConverter = converterLookup.lookupConverterForType(asType);

Object value = typeConverter.fromConfiguration(converterLookup, configuration, asType,
mojoDescriptor.getImplementationClass(), pluginRealm, expressionEvaluator, null);
return asType.cast(value);
} catch(Exception e) {
throw new CoreException(Status
.error(NLS.bind(Messages.MavenImpl_error_param_for_execution, parameterLabel, mojoExecution.getExecutionId()),
e));
}
}

@Override
public <T> T getMojoParameterValue(MavenProject project, MojoExecution mojoExecution, String parameter,
Class<T> asType, IProgressMonitor monitor) throws CoreException {
return getExecutionContext().execute(project,
(context, pm) -> getMojoParameterValue(context.getSession(), mojoExecution,
List.of(parameter), asType),
monitor);
}

@Override
public <T> T getMojoParameterValue(MavenProject project, MojoExecution mojoExecution, List<String> parameterPath,
Class<T> asType, IProgressMonitor monitor) throws CoreException {
return getExecutionContext().execute(project,
(context, pm) -> getMojoParameterValue(context.getSession(), mojoExecution, parameterPath, asType), monitor);
}

private <T> T getMojoParameterValue(String parameter, Class<T> type, MavenSession session, Plugin plugin,
ConfigurationContainer configuration, String goal) throws CoreException {
Xpp3Dom config = (Xpp3Dom) configuration.getConfiguration();
config = (config != null) ? config.getChild(parameter) : null;

PlexusConfiguration paramConfig = null;

if(config == null) {
MojoDescriptor mojoDescriptor;

try {
mojoDescriptor = lookup(BuildPluginManager.class).getMojoDescriptor(plugin, goal,
session.getCurrentProject().getRemotePluginRepositories(), session.getRepositorySession());
} catch(PluginNotFoundException | PluginResolutionException | PluginDescriptorParsingException
| MojoNotFoundException | InvalidPluginDescriptorException ex) {
throw new CoreException(Status.error(Messages.MavenImpl_error_param, ex));
}

PlexusConfiguration defaultConfig = mojoDescriptor.getMojoConfiguration();
if(defaultConfig != null) {
paramConfig = defaultConfig.getChild(parameter, false);
}
} else {
paramConfig = new XmlPlexusConfiguration(config);
}

if(paramConfig == null) {
return null;
}

try {
MojoExecution mojoExecution = new MojoExecution(plugin, goal, "default"); //$NON-NLS-1$

ExpressionEvaluator expressionEvaluator = new PluginParameterExpressionEvaluator(session, mojoExecution);

ConfigurationConverter typeConverter = converterLookup.lookupConverterForType(type);

Object value = typeConverter.fromConfiguration(converterLookup, paramConfig, type, Object.class,
getPlexusContainer().getContainerRealm(), expressionEvaluator, null);
return type.cast(value);
} catch(ComponentConfigurationException | ClassCastException ex) {
throw new CoreException(Status.error(Messages.MavenImpl_error_param, ex));
}
return new MojoUtils(this, getPlexusContainer().getContainerRealm(), getExecutionContext())
.getParameterValue(project, mojoExecution, parameter, asType, monitor);

}

@Override
public <T> T getMojoParameterValue(MavenProject project, String parameter, Class<T> type, Plugin plugin,
ConfigurationContainer configuration, String goal, IProgressMonitor monitor) throws CoreException {
return getExecutionContext().execute(project,
(context, pm) -> getMojoParameterValue(parameter, type, context.getSession(), plugin, configuration, goal),
monitor);
return new MojoUtils(this, getPlexusContainer().getContainerRealm(), getExecutionContext())
.getParameterValue(project, parameter, type, plugin, configuration, goal, monitor);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
/*******************************************************************************
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Konrad Windszus - initial implementation
*******************************************************************************/
package org.eclipse.m2e.core.internal.embedder;

import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.osgi.util.NLS;

import org.codehaus.plexus.classworlds.realm.ClassRealm;
import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
import org.codehaus.plexus.component.configurator.converters.ConfigurationConverter;
import org.codehaus.plexus.component.configurator.converters.lookup.ConverterLookup;
import org.codehaus.plexus.component.configurator.converters.lookup.DefaultConverterLookup;
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
import org.codehaus.plexus.configuration.PlexusConfiguration;
import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
import org.codehaus.plexus.util.xml.Xpp3Dom;

import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.ConfigurationContainer;
import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.BuildPluginManager;
import org.apache.maven.plugin.InvalidPluginDescriptorException;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.MojoNotFoundException;
import org.apache.maven.plugin.PluginDescriptorParsingException;
import org.apache.maven.plugin.PluginNotFoundException;
import org.apache.maven.plugin.PluginParameterExpressionEvaluator;
import org.apache.maven.plugin.PluginResolutionException;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.project.MavenProject;

import org.eclipse.m2e.core.embedder.IComponentLookup;
import org.eclipse.m2e.core.embedder.IMaven;
import org.eclipse.m2e.core.embedder.IMavenExecutionContext;
import org.eclipse.m2e.core.internal.Messages;


/**
* Utility methods to resolve Mojo parameters Still restricted to internal use only until a proper API has been
* established.
*/
public final class MojoUtils {

private final ConverterLookup converterLookup;
private final IComponentLookup componentManager;
private final ClassLoader classLoader;
private final IMavenExecutionContext executionContext;

public MojoUtils(IComponentLookup componentManager, ClassLoader classLoader,
IMavenExecutionContext executionContext) {
super();
this.converterLookup = new DefaultConverterLookup();
this.componentManager = componentManager;
this.classLoader = classLoader;
this.executionContext = executionContext;
}

public <T> T getParameterValue(MavenProject project, String parameter, Class<T> type, Plugin plugin,
ConfigurationContainer configuration, String goal, IProgressMonitor monitor) throws CoreException {
return executionContext.execute(project,
(context, pm) -> getParameterValue(parameter, type, context.getSession(), plugin, configuration, goal),
monitor);
}

public <T> T getParameterValue(MavenProject project, MojoExecution mojoExecution, String parameter,
Class<T> asType, IProgressMonitor monitor) throws CoreException {
return executionContext.execute(project,
(context, pm) -> getParameterValue(context.getSession(), mojoExecution, List.of(parameter), asType),
monitor);
}

/**
* Resolves a nested configuration parameter from the given {@code mojoExecution}. It coerces from String to the given
* type and considers expressions and default values.
*
* @param <T>
* @param project the Maven project
* @param mojoExecution the mojo execution from which to retrieve the configuration value
* @param parameterPath the path of the parameter to look up, the first item is the name of the element directly below
* {@code <configuration>} and the last one is the element containing the actual value
* @param asType the type to coerce to
* @param monitor the progress monitor
* @return the parameter value or {@code null} if the parameter with the given name was not found
* @throws CoreException
* @see IMaven#getMojoParameterValue(MavenProject, MojoExecution, String, Class, IProgressMonitor)
*/
public <T> T getParameterValue(MavenProject project, MojoExecution mojoExecution, List<String> parameterPath,
Class<T> asType, IProgressMonitor monitor) throws CoreException {
return executionContext.execute(project,
(context, pm) -> getParameterValue(context.getSession(), mojoExecution, parameterPath, asType), monitor);
}

private <T> T getParameterValue(MavenSession session, MojoExecution mojoExecution, List<String> parameterPath,
Class<T> asType) throws CoreException {
Xpp3Dom dom = mojoExecution.getConfiguration();
if(dom == null) {
return null;
}
PlexusConfiguration configuration = new XmlPlexusConfiguration(dom);
for(String parameter : parameterPath) {
configuration = configuration.getChild(parameter);
if(configuration == null) {
return null;
}
}
return getParameterValue(session, mojoExecution, configuration, asType, String.join("/", parameterPath));
}

private <T> T getParameterValue(MavenSession session, MojoExecution mojoExecution,
PlexusConfiguration configuration, Class<T> asType, String parameterLabel) throws CoreException {
try {
MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();

ClassRealm pluginRealm = componentManager.lookup(BuildPluginManager.class).getPluginRealm(session,
mojoDescriptor.getPluginDescriptor());

ExpressionEvaluator expressionEvaluator = new PluginParameterExpressionEvaluator(session, mojoExecution);
ConfigurationConverter typeConverter = converterLookup.lookupConverterForType(asType);

Object value = typeConverter.fromConfiguration(converterLookup, configuration, asType,
mojoDescriptor.getImplementationClass(), pluginRealm, expressionEvaluator, null);
return asType.cast(value);
} catch(Exception e) {
throw new CoreException(Status.error(
NLS.bind(Messages.MavenImpl_error_param_for_execution, parameterLabel, mojoExecution.getExecutionId()), e));
}
}

private <T> T getParameterValue(String parameter, Class<T> type, MavenSession session, Plugin plugin,
ConfigurationContainer configuration, String goal) throws CoreException {
Xpp3Dom config = (Xpp3Dom) configuration.getConfiguration();
config = (config != null) ? config.getChild(parameter) : null;

PlexusConfiguration paramConfig = null;

if(config == null) {
MojoDescriptor mojoDescriptor;

try {
mojoDescriptor = componentManager.lookup(BuildPluginManager.class).getMojoDescriptor(plugin, goal,
session.getCurrentProject().getRemotePluginRepositories(), session.getRepositorySession());
} catch(PluginNotFoundException | PluginResolutionException | PluginDescriptorParsingException
| MojoNotFoundException | InvalidPluginDescriptorException ex) {
throw new CoreException(Status.error(Messages.MavenImpl_error_param, ex));
}

PlexusConfiguration defaultConfig = mojoDescriptor.getMojoConfiguration();
if(defaultConfig != null) {
paramConfig = defaultConfig.getChild(parameter, false);
}
} else {
paramConfig = new XmlPlexusConfiguration(config);
}

if(paramConfig == null) {
return null;
}

try {
MojoExecution mojoExecution = new MojoExecution(plugin, goal, "default"); //$NON-NLS-1$

ExpressionEvaluator expressionEvaluator = new PluginParameterExpressionEvaluator(session, mojoExecution);

ConfigurationConverter typeConverter = converterLookup.lookupConverterForType(type);

Object value = typeConverter.fromConfiguration(converterLookup, paramConfig, type, Object.class,
classLoader, expressionEvaluator, null);
return type.cast(value);
} catch(ComponentConfigurationException | ClassCastException ex) {
throw new CoreException(Status.error(Messages.MavenImpl_error_param, ex));
}
}

}
Loading

0 comments on commit 36e1c4a

Please sign in to comment.