WarUtil.java
package com.github.jonasrutishauser.cdi.maven.plugin.war;
/*
* Copyright (C) 2017 Jonas Rutishauser
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program.
* If not, see <http://www.gnu.org/licenses/lgpl-3.0.txt>.
*/
import java.io.File;
import java.lang.annotation.Annotation;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import javax.enterprise.inject.spi.Extension;
import org.apache.maven.plugin.MojoExecutionException;
import org.codehaus.plexus.archiver.UnArchiver;
import org.codehaus.plexus.archiver.manager.ArchiverManager;
import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
import org.jboss.weld.bootstrap.api.CDI11Bootstrap;
import org.jboss.weld.bootstrap.api.TypeDiscoveryConfiguration;
import org.jboss.weld.bootstrap.spi.Deployment;
import org.jboss.weld.bootstrap.spi.EEModuleDescriptor;
import org.jboss.weld.bootstrap.spi.EEModuleDescriptor.ModuleType;
import org.jboss.weld.bootstrap.spi.Metadata;
import org.jboss.weld.bootstrap.spi.helpers.EEModuleDescriptorImpl;
import org.jboss.weld.environment.deployment.WeldBeanDeploymentArchive;
import org.jboss.weld.environment.deployment.discovery.DiscoveryStrategy;
import org.jboss.weld.environment.deployment.discovery.DiscoveryStrategyFactory;
import org.jboss.weld.resources.ClassLoaderResourceLoader;
import org.jboss.weld.resources.spi.ResourceLoader;
import com.github.jonasrutishauser.cdi.maven.plugin.ArchiveUtil;
import com.github.jonasrutishauser.cdi.maven.plugin.ear.EjbUtil;
import com.github.jonasrutishauser.cdi.maven.plugin.weld.WarBeanArchiveScanner;
import com.github.jonasrutishauser.cdi.maven.plugin.weld.WarDeployment;
public class WarUtil extends ArchiveUtil {
private final ArchiverManager archiverManager;
private final EjbUtil ejbUtil = new EjbUtil();
private File war;
private URLClassLoader warClassloader;
public WarUtil(ArchiverManager archiverManager) {
this.archiverManager = archiverManager;
}
public static WarUtil create(ArchiverManager archiverManager, File workDirectory, File warFile,
ClassLoader earClassloader) throws MalformedURLException {
WarUtil util = new WarUtil(archiverManager);
util.init(workDirectory, warFile, earClassloader);
return util;
}
@Override
public void init(File workDirectory, File warFile, ClassLoader parentClassloader) throws MalformedURLException {
UnArchiver unArchiver;
try {
unArchiver = archiverManager.getUnArchiver(warFile);
} catch (NoSuchArchiverException e) {
throw new IllegalStateException(e);
}
File extractedDir = new File(workDirectory, warFile.getName());
this.war = extractedDir;
extractedDir.mkdirs();
unArchiver.setDestDirectory(extractedDir);
unArchiver.setSourceFile(warFile);
unArchiver.extract();
File libDir = new File(extractedDir, "WEB-INF/lib");
File[] jars = libDir.listFiles(file -> file.getName().endsWith(".jar"));
List<URL> urls = new ArrayList<>();
urls.add(new File(extractedDir, WarBeanArchiveScanner.CLASSES).toURI().toURL());
if (jars != null) {
for (File jar : jars) {
urls.add(jar.toURI().toURL());
}
}
warClassloader = new URLClassLoader(urls.toArray(new URL[urls.size()]), parentClassloader);
}
@Override
public Deployment createDeployment(CDI11Bootstrap bootstrap) throws MojoExecutionException {
Set<Metadata<Extension>> extensions = StreamSupport
.stream(bootstrap.loadExtensions(warClassloader).spliterator(), false).collect(Collectors.toSet());
addDefaultExtensions(extensions);
TypeDiscoveryConfiguration typeDiscoveryConfiguration = bootstrap.startExtensions(extensions);
Set<WeldBeanDeploymentArchive> archives = createArchives(bootstrap,
typeDiscoveryConfiguration.getKnownBeanDefiningAnnotations());
ResourceLoader resourceLoader = archives.iterator().next().getServices().get(ResourceLoader.class);
return new WarDeployment(resourceLoader, bootstrap, archives, extensions);
}
@Override
public ClassLoader getClassLoader() {
return warClassloader;
}
public Set<WeldBeanDeploymentArchive> createArchives(CDI11Bootstrap bootstrap,
Set<Class<? extends Annotation>> beanDefiningAnnotations) {
Set<Class<? extends Annotation>> annotations = new HashSet<>(beanDefiningAnnotations);
ejbUtil.addBeanDefiningAnnotations(annotations);
DiscoveryStrategy strategy = DiscoveryStrategyFactory.create(new ClassLoaderResourceLoader(warClassloader),
bootstrap, annotations, false);
strategy.setScanner(new WarBeanArchiveScanner(bootstrap, war, warClassloader.getURLs()));
Set<WeldBeanDeploymentArchive> archives = strategy.performDiscovery().stream().map(ejbUtil::addEjbDescriptors)
.collect(Collectors.toSet());
archives.forEach(this::addServices);
return archives;
}
private void addServices(WeldBeanDeploymentArchive archive) {
archive.getServices().add(EEModuleDescriptor.class,
new EEModuleDescriptorImpl(archive.getId(), ModuleType.WEB));
}
}