blob: ff52d0b0c0fe4d16939acebae173a91dd042246b [file] [log] [blame]
/*
* 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.model.plugin;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.maven.api.model.Build;
import org.apache.maven.api.model.Model;
import org.apache.maven.api.model.Plugin;
import org.apache.maven.api.model.PluginContainer;
import org.apache.maven.api.model.PluginExecution;
import org.apache.maven.api.model.PluginManagement;
import org.apache.maven.lifecycle.LifeCyclePluginAnalyzer;
import org.apache.maven.model.building.ModelBuildingRequest;
import org.apache.maven.model.building.ModelProblem.Severity;
import org.apache.maven.model.building.ModelProblem.Version;
import org.apache.maven.model.building.ModelProblemCollector;
import org.apache.maven.model.building.ModelProblemCollectorRequest;
import org.apache.maven.model.merge.MavenModelMerger;
/**
* Handles injection of plugin executions induced by the lifecycle bindings for a packaging.
*
*/
@Named
@Singleton
public class DefaultLifecycleBindingsInjector implements LifecycleBindingsInjector {
private final LifecycleBindingsMerger merger = new LifecycleBindingsMerger();
private final LifeCyclePluginAnalyzer lifecycle;
@Inject
public DefaultLifecycleBindingsInjector(LifeCyclePluginAnalyzer lifecycle) {
this.lifecycle = lifecycle;
}
public void injectLifecycleBindings(
org.apache.maven.model.Model model, ModelBuildingRequest request, ModelProblemCollector problems) {
String packaging = model.getPackaging();
Collection<org.apache.maven.model.Plugin> defaultPlugins =
lifecycle.getPluginsBoundByDefaultToAllLifecycles(packaging);
if (defaultPlugins == null) {
problems.add(new ModelProblemCollectorRequest(Severity.ERROR, Version.BASE)
.setMessage("Unknown packaging: " + packaging)
.setLocation(model.getLocation("packaging")));
} else if (!defaultPlugins.isEmpty()) {
List<Plugin> plugins = defaultPlugins.stream()
.map(org.apache.maven.model.Plugin::getDelegate)
.collect(Collectors.toList());
Model lifecycleModel = Model.newBuilder()
.build(Build.newBuilder().plugins(plugins).build())
.build();
model.update(merger.merge(model.getDelegate(), lifecycleModel));
}
}
/**
* The domain-specific model merger for lifecycle bindings
*/
protected static class LifecycleBindingsMerger extends MavenModelMerger {
private static final String PLUGIN_MANAGEMENT = "plugin-management";
public Model merge(Model target, Model source) {
Build targetBuild = target.getBuild();
if (targetBuild == null) {
targetBuild = Build.newInstance();
}
Map<Object, Object> context =
Collections.singletonMap(PLUGIN_MANAGEMENT, targetBuild.getPluginManagement());
Build.Builder builder = Build.newBuilder(targetBuild);
mergePluginContainer_Plugins(builder, targetBuild, source.getBuild(), false, context);
return target.withBuild(builder.build());
}
@SuppressWarnings({"checkstyle:methodname"})
@Override
protected void mergePluginContainer_Plugins(
PluginContainer.Builder builder,
PluginContainer target,
PluginContainer source,
boolean sourceDominant,
Map<Object, Object> context) {
List<Plugin> src = source.getPlugins();
if (!src.isEmpty()) {
List<Plugin> tgt = target.getPlugins();
Map<Object, Plugin> merged = new LinkedHashMap<>((src.size() + tgt.size()) * 2);
for (Plugin element : tgt) {
Object key = getPluginKey().apply(element);
merged.put(key, element);
}
Map<Object, Plugin> added = new LinkedHashMap<>();
for (Plugin element : src) {
Object key = getPluginKey().apply(element);
Plugin existing = merged.get(key);
if (existing != null) {
element = mergePlugin(existing, element, sourceDominant, context);
} else {
added.put(key, element);
}
merged.put(key, element);
}
if (!added.isEmpty()) {
PluginManagement pluginMgmt = (PluginManagement) context.get(PLUGIN_MANAGEMENT);
if (pluginMgmt != null) {
for (Plugin managedPlugin : pluginMgmt.getPlugins()) {
Object key = getPluginKey().apply(managedPlugin);
Plugin addedPlugin = added.get(key);
if (addedPlugin != null) {
Plugin plugin =
mergePlugin(managedPlugin, addedPlugin, sourceDominant, Collections.emptyMap());
merged.put(key, plugin);
}
}
}
}
List<Plugin> result = new ArrayList<>(merged.values());
builder.plugins(result);
}
}
@Override
protected void mergePluginExecution_Priority(
PluginExecution.Builder builder,
PluginExecution target,
PluginExecution source,
boolean sourceDominant,
Map<Object, Object> context) {
if (target.getPriority() > source.getPriority()) {
builder.priority(source.getPriority());
builder.location("priority", source.getLocation("priority"));
}
}
// mergePluginExecution_Priority( builder, target, source, sourceDominant, context );
}
}