io.freefair.gradle.plugins.maven.war.WarOverlayPlugin Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of maven-plugin Show documentation
Show all versions of maven-plugin Show documentation
Collection of Maven related Gradle plugins
package io.freefair.gradle.plugins.maven.war;
import groovy.lang.Closure;
import lombok.RequiredArgsConstructor;
import org.codehaus.groovy.runtime.StringGroovyMethods;
import org.gradle.api.*;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.Dependency;
import org.gradle.api.artifacts.ExternalDependency;
import org.gradle.api.artifacts.ProjectDependency;
import org.gradle.api.file.ConfigurableFileCollection;
import org.gradle.api.file.CopySpec;
import org.gradle.api.file.FileTree;
import org.gradle.api.internal.file.copy.CopySpecInternal;
import org.gradle.api.plugins.WarPlugin;
import org.gradle.api.tasks.Sync;
import org.gradle.api.tasks.bundling.AbstractArchiveTask;
import org.gradle.api.tasks.bundling.War;
import java.io.File;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
import static org.gradle.api.plugins.BasePlugin.CLEAN_TASK_NAME;
import static org.gradle.api.plugins.JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME;
import static org.gradle.api.plugins.JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME;
import static org.gradle.api.plugins.WarPlugin.WAR_TASK_NAME;
/**
* @author Lars Grefer
*/
@NonNullApi
public class WarOverlayPlugin implements Plugin {
private Project project;
@Override
public void apply(Project project) {
this.project = project;
project.getPluginManager().apply(WarPlugin.class);
project.getTasks().withType(War.class, warTask -> {
NamedDomainObjectContainer warOverlays = project.container(WarOverlay.class, name -> new WarOverlay(name, warTask));
warTask.getExtensions().add("overlays", warOverlays);
Configuration warOverlayClasspath = project.getConfigurations().create(warTask.getName() + "OverlayClasspath");
warTask.getExtensions().add("overlayClasspath", warOverlayClasspath);
if (warTask.getName().equals(WarPlugin.WAR_TASK_NAME)) {
project.getConfigurations().getByName(COMPILE_CLASSPATH_CONFIGURATION_NAME).extendsFrom(warOverlayClasspath);
project.getConfigurations().getByName(TEST_IMPLEMENTATION_CONFIGURATION_NAME).extendsFrom(warOverlayClasspath);
}
project.afterEvaluate(p -> warOverlays.all(overlay -> {
if (overlay.isEnabled()) {
configureOverlay(overlay);
} else {
Collection children = (Collection) overlay.getWarTask().getRootSpec().getChildren();
children.remove(overlay.getWarCopySpec());
}
}));
});
}
private void configureOverlay(WarOverlay overlay) {
if (overlay.isDeferProvidedConfiguration()) {
//Delay this to trick IntelliJ
overlay.getWarTask().doFirst(new ExcludeProvidedAction(overlay));
} else {
overlay.getWarCopySpec().exclude(element -> overlay.isProvided());
}
Object source = overlay.getSource();
if (source instanceof AbstractArchiveTask) {
configureOverlay(overlay, (AbstractArchiveTask) source);
} else if (source instanceof Project && overlay.getConfigureClosure() == null) {
configureOverlay(overlay, (Project) source);
} else if (source instanceof File) {
configureOverlay(overlay, (File) source);
} else {
Closure configClosure = overlay.getConfigureClosure();
Dependency dependency;
if (configClosure == null) {
dependency = project.getDependencies().create(source);
} else {
dependency = project.getDependencies().create(source, configClosure);
}
if (dependency instanceof ProjectDependency) {
configureOverlay(overlay, ((ProjectDependency) dependency).getDependencyProject());
} else if (dependency instanceof ExternalDependency) {
configureOverlay(overlay, (ExternalDependency) dependency);
} else {
throw new GradleException("Unsupported dependency type: " + dependency.getClass().getName());
}
}
}
private void configureOverlay(WarOverlay overlay, File file) {
configureOverlay(overlay, () -> project.zipTree(file));
}
private void configureOverlay(WarOverlay overlay, ExternalDependency dependency) {
War warTask = overlay.getWarTask();
dependency.setTransitive(false);
Configuration configuration = project.getConfigurations().create(overlay.getConfigurationName());
configuration.setDescription(String.format("Contents of the overlay '%s' for the task '%s'.", overlay.getName(), warTask.getName()));
configuration.getDependencies().add(dependency);
configureOverlay(overlay, () -> project.zipTree(configuration.getSingleFile()));
}
private void configureOverlay(WarOverlay overlay, Callable warTree) {
War warTask = overlay.getWarTask();
String capitalizedWarTaskName = StringGroovyMethods.capitalize((CharSequence) warTask.getName());
String capitalizedOverlayName = StringGroovyMethods.capitalize((CharSequence) overlay.getName());
File destinationDir = new File(project.getBuildDir(), String.format("overlays/%s/%s", warTask.getName(), overlay.getName()));
Action extractOverlay = copySpec -> {
copySpec.into(destinationDir);
copySpec.from(warTree);
};
Sync extractOverlayTask = project.getTasks().create(String.format("extract%s%sOverlay", capitalizedOverlayName, capitalizedWarTaskName), Sync.class, extractOverlay);
overlay.getWarCopySpec().from(extractOverlayTask);
if (overlay.isEnableCompilation()) {
if (!destinationDir.exists() || isEmpty(destinationDir)) {
project.sync(extractOverlay);
}
project.getTasks().getByName(CLEAN_TASK_NAME).finalizedBy(extractOverlayTask);
ConfigurableFileCollection classes = project.files(new File(destinationDir, "WEB-INF/classes"))
.builtBy(extractOverlayTask);
project.getDependencies().add(getClasspathConfigurationName(overlay), classes);
FileTree libs = project.files(extractOverlayTask).builtBy(extractOverlayTask).getAsFileTree()
.matching(patternFilterable -> patternFilterable.include("WEB-INF/lib/**"));
project.getDependencies().add(getClasspathConfigurationName(overlay), libs);
}
}
private boolean isEmpty(File destinationDir) {
String[] list = destinationDir.list();
return list == null || list.length == 0;
}
private void configureOverlay(WarOverlay overlay, Project otherProject) {
project.evaluationDependsOn(otherProject.getPath());
War otherWar = (War) otherProject.getTasks().getByName(WAR_TASK_NAME);
configureOverlay(overlay, otherWar);
if (overlay.isEnableCompilation()) {
project.getDependencies().add(getClasspathConfigurationName(overlay), otherProject);
otherProject.getPlugins().withType(WarOverlayPlugin.class, otherWarOverlayPlugin -> {
Map map = new HashMap<>();
map.put("path", otherProject.getPath());
map.put("configuration", otherWarOverlayPlugin.getClasspathConfigurationName(otherWar));
project.getDependencies().add(
getClasspathConfigurationName(overlay),
project.getDependencies().project(map)
);
});
}
}
private void configureOverlay(WarOverlay overlay, AbstractArchiveTask from) {
overlay.getWarCopySpec().with(from.getRootSpec());
}
private String getClasspathConfigurationName(WarOverlay warOverlay) {
return getClasspathConfigurationName(warOverlay.getWarTask());
}
private String getClasspathConfigurationName(War warTask) {
return warTask.getName() + "OverlayClasspath";
}
@RequiredArgsConstructor
private static class ExcludeProvidedAction implements Action {
private final CopySpec warCopySpec;
private final boolean provided;
public ExcludeProvidedAction(WarOverlay overlay) {
warCopySpec = overlay.getWarCopySpec();
provided = overlay.isProvided();
}
@Override
public void execute(Task w) {
warCopySpec.exclude(element -> provided);
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy