org.wildfly.swarm.plugin.process.ModuleGenerator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of wildfly-swarm-fraction-plugin Show documentation
Show all versions of wildfly-swarm-fraction-plugin Show documentation
Plugin to create fraction packages for Wildfly Swarm proper.
package org.wildfly.swarm.plugin.process;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.project.MavenProject;
import org.jboss.shrinkwrap.descriptor.api.Descriptors;
import org.jboss.shrinkwrap.descriptor.api.jbossmodule15.ArtifactType;
import org.jboss.shrinkwrap.descriptor.api.jbossmodule15.DependenciesType;
import org.jboss.shrinkwrap.descriptor.api.jbossmodule15.FilterType;
import org.jboss.shrinkwrap.descriptor.api.jbossmodule15.ModuleDependencyType;
import org.jboss.shrinkwrap.descriptor.api.jbossmodule15.ModuleDescriptor;
import org.jboss.shrinkwrap.descriptor.api.jbossmodule15.PathSetType;
import org.jboss.shrinkwrap.descriptor.api.jbossmodule15.ResourcesType;
import org.jboss.shrinkwrap.descriptor.api.jbossmodule15.SystemDependencyType;
import org.wildfly.swarm.plugin.FractionMetadata;
/**
* @author Bob McWhirter
*/
public class ModuleGenerator implements Function {
private static final String RUNTIME = "runtime";
private static final String MAIN = "main";
private static final String DEPLOYMENT = "deployment";
private static final String DETECT = "detect";
private static final String MODULE_XML = "module.xml";
private final Log log;
private final MavenProject project;
public ModuleGenerator(Log log,
MavenProject project) {
this.log = log;
this.project = project;
}
@Override
public FractionMetadata apply(FractionMetadata meta) {
if (meta.hasModuleConf()) {
Path moduleConf = meta.getModuleConf();
List dependencies;
try (BufferedReader reader = new BufferedReader(new FileReader(moduleConf.toFile()))) {
dependencies = reader.lines()
.map(String::trim)
.filter(line -> !line.startsWith("#"))
.collect(Collectors.toList());
generate(meta.getBaseModulePath(), dependencies);
} catch (IOException e) {
this.log.error(e.getMessage(), e);
}
}
return meta;
}
private void generate(Path root, List dependencies) throws IOException {
String moduleName = root.toString().replace(File.separatorChar, '.');
Path outputDir = Paths.get(this.project.getBuild().getOutputDirectory(), "modules");
Path runtimeModuleXml = outputDir.resolve(root).resolve(Paths.get(RUNTIME, MODULE_XML));
Path apiModuleXml = outputDir.resolve(root).resolve(Paths.get("api", MODULE_XML));
Path mainModuleXml = outputDir.resolve(root).resolve(Paths.get(MAIN, MODULE_XML));
Path deploymentModuleXml = outputDir.resolve(root).resolve(Paths.get(DEPLOYMENT, MODULE_XML));
Set apiPaths = determineApiPaths();
Set runtimePaths = determineRuntimePaths();
Set deploymentPaths = determineDeploymentPaths();
// -- runtime
ModuleDescriptor runtimeModule = Descriptors.create(ModuleDescriptor.class);
runtimeModule
.name(moduleName)
.slot(RUNTIME);
markModulePrivate(runtimeModule);
ArtifactType> runtimeArtifact = runtimeModule.getOrCreateResources().createArtifact();
runtimeArtifact.name(this.project.getGroupId() + ":" + this.project.getArtifactId() + ":" + this.project.getVersion());
PathSetType>>> runtimeExcludeSet = runtimeArtifact.getOrCreateFilter()
.createExcludeSet();
for (String path : apiPaths) {
runtimeExcludeSet.createPath().name(path);
}
for (String path : deploymentPaths) {
runtimeExcludeSet.createPath().name(path);
}
runtimeModule.getOrCreateDependencies()
.createModule().name(moduleName).slot(MAIN).export(true);
runtimeModule.getOrCreateDependencies()
.createModule().name("org.wildfly.swarm.bootstrap").optional(true).up()
.createModule().name("org.wildfly.swarm.container").slot(RUNTIME).up()
.createModule().name("org.wildfly.swarm.spi").slot(RUNTIME).up();
runtimeModule.getOrCreateDependencies()
.createModule()
.name("javax.enterprise.api");
runtimeModule.getOrCreateDependencies()
.createModule()
.name("org.jboss.weld.se");
addDependencies(runtimeModule, dependencies);
// -- api
ModuleDescriptor apiModule = Descriptors.create(ModuleDescriptor.class);
apiModule.name(moduleName).slot("api");
ArtifactType> apiArtifact = apiModule.getOrCreateResources().createArtifact();
apiArtifact.name(this.project.getGroupId() + ":" + this.project.getArtifactId() + ":" + this.project.getVersion());
PathSetType>>> apiIncludeSet = apiArtifact.getOrCreateFilter()
.createIncludeSet();
for (String path : apiPaths) {
apiIncludeSet.createPath().name(path);
}
apiIncludeSet.createPath().name("META-INF");
PathSetType>>> apiExcludeSet = apiArtifact.getOrCreateFilter()
.createExcludeSet();
for (String path : runtimePaths) {
apiExcludeSet.createPath().name(path);
}
for (String path : deploymentPaths) {
apiExcludeSet.createPath().name(path);
}
apiModule.getOrCreateDependencies()
.createModule()
.name("org.wildfly.swarm.container");
apiModule.getOrCreateDependencies()
.createModule()
.name("javax.enterprise.api");
apiModule.getOrCreateDependencies()
.createModule()
.name("org.jboss.weld.se");
addDependencies(apiModule, dependencies);
// -- main
ModuleDescriptor mainModule = Descriptors.create(ModuleDescriptor.class);
mainModule.name(moduleName).slot(MAIN);
SystemDependencyType> system = mainModule.getOrCreateDependencies().createSystem();
system.export(true);
PathSetType>> systemPaths = system.getOrCreatePaths();
for (String path : apiPaths) {
systemPaths.createPath().name(path);
}
ModuleDependencyType> depModule = mainModule.getOrCreateDependencies()
.createModule();
depModule.name(moduleName)
.slot(apiModule.getSlot())
.export(true)
.services("export");
FilterType>> imports = depModule.getOrCreateImports();
for (String path : apiPaths) {
imports.createInclude().path(path);
}
imports.getOrCreateInclude().path("**");
FilterType>> exports = depModule.getOrCreateExports();
exports.createInclude().path("**");
// -- deployment
ModuleDescriptor deploymentModule = null;
if (!deploymentPaths.isEmpty()) {
deploymentModule = Descriptors.create(ModuleDescriptor.class);
deploymentModule
.name(moduleName)
.slot(DEPLOYMENT);
ModuleDependencyType> deploymentMainDep = deploymentModule.getOrCreateDependencies()
.createModule();
deploymentMainDep.name(moduleName)
.slot(mainModule.getSlot());
FilterType>> depMainImports = deploymentMainDep.getOrCreateImports();
PathSetType>>> depMainExcludes = depMainImports.createExcludeSet();
ArtifactType> deploymentArtifact = deploymentModule.getOrCreateResources().createArtifact();
deploymentArtifact.name(this.project.getGroupId() + ":" + this.project.getArtifactId() + ":" + this.project.getVersion());
PathSetType>>> deploymentExcludeSet = deploymentArtifact.getOrCreateFilter()
.createExcludeSet();
for (String path : apiPaths) {
deploymentExcludeSet.createPath().name(path);
}
for (String path : runtimePaths) {
deploymentExcludeSet.createPath().name(path);
depMainExcludes.createPath().name(path);
}
deploymentExcludeSet.createPath().name("META-INF");
deploymentExcludeSet.createPath().name("META-INF/**");
depMainExcludes.createPath().name("META-INF");
depMainExcludes.createPath().name("META-INF/**");
addDependencies(deploymentModule, dependencies);
}
export(mainModule, mainModuleXml);
export(apiModule, apiModuleXml);
export(runtimeModule, runtimeModuleXml);
export(deploymentModule, deploymentModuleXml);
}
private void markModulePrivate(ModuleDescriptor module) {
module.getOrCreateProperties().createProperty().name("jboss.api").value("private");
}
private void addDependencies(ModuleDescriptor module, List dependencies) {
for (String dependency : dependencies) {
dependency = dependency.trim();
if (!dependency.isEmpty()) {
boolean optional = false;
if (dependency.startsWith("*")) {
optional = true;
dependency = dependency.substring(1);
}
String services = null;
if (dependency.contains("services=export")) {
services = "export";
dependency = dependency.replace("services=export", "");
} else if (dependency.contains("services=import")) {
services = "import";
dependency = dependency.replace("services=import", "");
}
boolean isexport = false;
if (dependency.contains("export=true")) {
isexport = true;
dependency = dependency.replace("export=true", "");
}
dependency = dependency.trim();
int colonLoc = dependency.indexOf(':');
String depName;
String depSlot;
if (colonLoc < 0) {
depName = dependency;
depSlot = MAIN;
} else {
depName = dependency.substring(0, colonLoc);
depSlot = dependency.substring(colonLoc + 1);
}
ModuleDependencyType> moduleDep = module.getOrCreateDependencies()
.createModule()
.name(depName)
.slot(depSlot);
if (services != null) {
moduleDep.services(services);
}
if (isexport) {
moduleDep.export(isexport);
}
if (optional) {
moduleDep.optional(true);
}
}
}
}
private void export(ModuleDescriptor module, Path path) throws IOException {
if (module == null) {
log.info("Not exporting empty module: " + path);
return;
}
Files.createDirectories(path.getParent());
try (FileOutputStream out = new FileOutputStream(path.toFile())) {
module.exportTo(out);
}
}
private Set determineApiPaths() throws IOException {
return determinePaths((file) -> (!(file.contains(RUNTIME) || file.contains(DEPLOYMENT) || file.contains(DETECT))));
}
private Set determineRuntimePaths() throws IOException {
return determinePaths((file) -> file.contains(RUNTIME));
}
private Set determineDeploymentPaths() throws IOException {
return determinePaths((file) -> file.contains(DEPLOYMENT));
}
private Set determinePaths(Predicate pred) throws IOException {
Path dir = Paths.get(this.project.getBuild().getOutputDirectory());
Set paths = new HashSet<>();
if (Files.exists(dir)) {
FileVisitor visitor = new SimpleFileVisitor() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
if (file.getFileName().toString().endsWith(".class")) {
if (pred.test(file.toString())) {
paths.add(javaSlashize(dir.relativize(file.getParent())));
}
}
return super.visitFile(file, attrs);
}
};
Files.walkFileTree(dir, visitor);
}
return paths;
}
private String javaSlashize(Path path) {
List parts = new ArrayList<>();
int numParts = path.getNameCount();
for (int i = 0; i < numParts; ++i) {
parts.add(path.getName(i).toString());
}
return String.join("/", parts);
}
}