You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwebbeans.apache.org by rm...@apache.org on 2020/12/05 20:12:33 UTC
[openwebbeans] 01/01: basic scan mojo
This is an automated email from the ASF dual-hosted git repository.
rmannibucau pushed a commit to branch rmannibucau/scan-mojo
in repository https://gitbox.apache.org/repos/asf/openwebbeans.git
commit 6863edf69a3743b42b381a8e288d5141ab437f94
Author: Romain Manni-Bucau <rm...@gmail.com>
AuthorDate: Sat Dec 5 21:12:25 2020 +0100
basic scan mojo
---
pom.xml | 2 +
.../webbeans/config/OpenWebBeansConfiguration.java | 7 +
.../corespi/scanner/AbstractMetaDataDiscovery.java | 3 +-
.../webbeans/corespi/scanner/xbean/CdiArchive.java | 49 ++-
.../InterceptorAnnotatedDiscoveryTest.java | 4 +-
webbeans-maven-plugin/pom.xml | 118 ++++++
.../org/apache/openwebbeans/maven/ScanMojo.java | 457 +++++++++++++++++++++
.../src/main/resources/META-INF/MANIFEST.MF | 1 +
.../apache/webbeans/web/tests/WebBeansTest.java | 4 +-
9 files changed, 640 insertions(+), 5 deletions(-)
diff --git a/pom.xml b/pom.xml
index 3d672d1..c37574a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -504,6 +504,7 @@
</execution>
</executions>
<configuration>
+ <excludes>**/HelpMojo.java</excludes>
<configLocation>openwebbeans/owb-checks-default.xml</configLocation>
<headerLocation>openwebbeans/owb-header.txt</headerLocation>
<consoleOutput>true</consoleOutput>
@@ -649,6 +650,7 @@
<module>webbeans-se</module>
<module>webbeans-junit5</module>
<module>webbeans-slf4j</module>
+ <module>webbeans-maven-plugin</module>
</modules>
<dependencyManagement>
diff --git a/webbeans-impl/src/main/java/org/apache/webbeans/config/OpenWebBeansConfiguration.java b/webbeans-impl/src/main/java/org/apache/webbeans/config/OpenWebBeansConfiguration.java
index 7eab234..82486a5 100644
--- a/webbeans-impl/src/main/java/org/apache/webbeans/config/OpenWebBeansConfiguration.java
+++ b/webbeans-impl/src/main/java/org/apache/webbeans/config/OpenWebBeansConfiguration.java
@@ -556,4 +556,11 @@ public class OpenWebBeansConfiguration
return generatorJavaVersion;
}
+
+ public void cleanBuiltTimeScanning()
+ {
+ configProperties.stringPropertyNames().stream()
+ .filter(it -> it.startsWith("openwebbeans.buildtime.scanning."))
+ .forEach(configProperties::remove);
+ }
}
diff --git a/webbeans-impl/src/main/java/org/apache/webbeans/corespi/scanner/AbstractMetaDataDiscovery.java b/webbeans-impl/src/main/java/org/apache/webbeans/corespi/scanner/AbstractMetaDataDiscovery.java
index 210556e..797f093 100644
--- a/webbeans-impl/src/main/java/org/apache/webbeans/corespi/scanner/AbstractMetaDataDiscovery.java
+++ b/webbeans-impl/src/main/java/org/apache/webbeans/corespi/scanner/AbstractMetaDataDiscovery.java
@@ -129,7 +129,8 @@ public abstract class AbstractMetaDataDiscovery implements BdaScannerService
}
archive = new CdiArchive(
beanArchiveService, WebBeansUtil.getCurrentClassLoader(),
- beanDeploymentUrls, userFilter, getAdditionalArchive());
+ beanDeploymentUrls, userFilter, getAdditionalArchive(),
+ webBeansContext.getOpenWebBeansConfiguration());
finder = new OwbAnnotationFinder(archive);
return finder;
diff --git a/webbeans-impl/src/main/java/org/apache/webbeans/corespi/scanner/xbean/CdiArchive.java b/webbeans-impl/src/main/java/org/apache/webbeans/corespi/scanner/xbean/CdiArchive.java
index b77aaf0..1b7c199 100644
--- a/webbeans-impl/src/main/java/org/apache/webbeans/corespi/scanner/xbean/CdiArchive.java
+++ b/webbeans-impl/src/main/java/org/apache/webbeans/corespi/scanner/xbean/CdiArchive.java
@@ -18,14 +18,18 @@
*/
package org.apache.webbeans.corespi.scanner.xbean;
+import org.apache.webbeans.config.OpenWebBeansConfiguration;
import org.apache.webbeans.spi.BeanArchiveService;
import org.apache.webbeans.spi.BeanArchiveService.BeanArchiveInformation;
import org.apache.xbean.finder.archive.Archive;
+import org.apache.xbean.finder.archive.ClassesArchive;
import org.apache.xbean.finder.archive.ClasspathArchive;
import org.apache.xbean.finder.archive.CompositeArchive;
import org.apache.xbean.finder.archive.FilteredArchive;
import org.apache.xbean.finder.filter.Filter;
+import org.apache.xbean.finder.util.Files;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
@@ -35,6 +39,10 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Stream;
+
+import static java.util.stream.Collectors.toList;
/**
* this delegate pattern is interesting
@@ -53,7 +61,7 @@ public class CdiArchive implements Archive
private final Archive delegate;
public CdiArchive(BeanArchiveService beanArchiveService, ClassLoader loader, Map<String, URL> urls,
- Filter userFilter, Archive customArchive)
+ Filter userFilter, Archive customArchive, OpenWebBeansConfiguration config)
{
Collection<Archive> archives = new ArrayList<>();
boolean customAdded = false;
@@ -64,7 +72,9 @@ public class CdiArchive implements Archive
BeanArchiveInformation beanArchiveInfo = beanArchiveService.getBeanArchiveInformation(url);
final boolean custom = "openwebbeans".equals(url.getProtocol());
Archive archive = new FilteredArchive(
- custom ? customArchive : ClasspathArchive.archive(loader, url),
+ custom ?
+ customArchive :
+ createArchive(loader, url, config),
new BeanArchiveFilter(beanArchiveInfo, urlClasses, userFilter));
if (!customAdded && custom)
{
@@ -78,9 +88,44 @@ public class CdiArchive implements Archive
{
archives.add(userFilter != null ? new FilteredArchive(customArchive, userFilter) : customArchive);
}
+ if (config != null)
+ {
+ config.cleanBuiltTimeScanning();
+ }
delegate = new CompositeArchive(archives);
}
+ private Archive createArchive(final ClassLoader loader, final URL url, final OpenWebBeansConfiguration config)
+ {
+ if (config != null)
+ {
+ final File file = Files.toFile(url);
+ if (!file.isDirectory()) // see ScanMojo
+ {
+ final String classes = config.getProperty(
+ "openwebbeans.buildtime.scanning." + file.getName() + ".classes");
+ if (classes != null)
+ {
+ return new ClassesArchive(Stream.of(classes.split(","))
+ .map(it ->
+ {
+ try
+ {
+ return loader.loadClass(it);
+ }
+ catch (final ClassNotFoundException e)
+ {
+ return null;
+ }
+ })
+ .filter(Objects::nonNull)
+ .collect(toList()));
+ }
+ }
+ }
+ return ClasspathArchive.archive(loader, url);
+ }
+
public Map<String, FoundClasses> classesByUrl()
{
return classesByUrl;
diff --git a/webbeans-impl/src/test/java/org/apache/webbeans/test/discovery/InterceptorAnnotatedDiscoveryTest.java b/webbeans-impl/src/test/java/org/apache/webbeans/test/discovery/InterceptorAnnotatedDiscoveryTest.java
index e3f9602..a8f79cc 100644
--- a/webbeans-impl/src/test/java/org/apache/webbeans/test/discovery/InterceptorAnnotatedDiscoveryTest.java
+++ b/webbeans-impl/src/test/java/org/apache/webbeans/test/discovery/InterceptorAnnotatedDiscoveryTest.java
@@ -75,7 +75,9 @@ public class InterceptorAnnotatedDiscoveryTest extends AbstractUnitTest
}
super.initFinder();
- archive = new CdiArchive(webBeansContext().getBeanArchiveService(), WebBeansUtil.getCurrentClassLoader(), emptyMap(), null, null)
+ archive = new CdiArchive(
+ webBeansContext().getBeanArchiveService(), WebBeansUtil.getCurrentClassLoader(), emptyMap(),
+ null, null, null)
{
@Override
public Map<String, FoundClasses> classesByUrl()
diff --git a/webbeans-maven-plugin/pom.xml b/webbeans-maven-plugin/pom.xml
new file mode 100644
index 0000000..f0e7104
--- /dev/null
+++ b/webbeans-maven-plugin/pom.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>openwebbeans</artifactId>
+ <groupId>org.apache.openwebbeans</groupId>
+ <version>2.0.21-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>openwebbeans-maven-plugin</artifactId>
+ <name>Maven Plugin</name>
+ <packaging>maven-plugin</packaging>
+ <description>Apache OpenWebBeans Maven Plugin</description>
+
+ <properties>
+ <mvn.version>3.6.3</mvn.version>
+ <meecrowave.build.name>${project.groupId}.maven</meecrowave.build.name>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>${mvn.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>javax.enterprise</groupId>
+ <artifactId>cdi-api</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-core</artifactId>
+ <version>${mvn.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>javax.inject</groupId>
+ <artifactId>javax.inject</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.plugin-tools</groupId>
+ <artifactId>maven-plugin-annotations</artifactId>
+ <version>3.3</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.shared</groupId>
+ <artifactId>maven-dependency-tree</artifactId>
+ <version>3.0.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.shared</groupId>
+ <artifactId>maven-artifact-resolver</artifactId>
+ <version>1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.xbean</groupId>
+ <artifactId>xbean-finder-shaded</artifactId>
+ <version>${xbean.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>3.6.0</version>
+ <executions>
+ <execution>
+ <id>mojo-descriptor</id>
+ <goals>
+ <goal>descriptor</goal>
+ <goal>helpmojo</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <goalPrefix>openwebbeans</goalPrefix>
+ <skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>3.6.0</version>
+ </plugin>
+ </plugins>
+ </reporting>
+
+</project>
\ No newline at end of file
diff --git a/webbeans-maven-plugin/src/main/java/org/apache/openwebbeans/maven/ScanMojo.java b/webbeans-maven-plugin/src/main/java/org/apache/openwebbeans/maven/ScanMojo.java
new file mode 100644
index 0000000..e62d10a
--- /dev/null
+++ b/webbeans-maven-plugin/src/main/java/org/apache/openwebbeans/maven/ScanMojo.java
@@ -0,0 +1,457 @@
+/*
+ * 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.openwebbeans.maven;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.DefaultArtifact;
+import org.apache.maven.artifact.handler.DefaultArtifactHandler;
+import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
+import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugins.annotations.Component;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.project.DefaultDependencyResolutionRequest;
+import org.apache.maven.project.DependencyResolutionException;
+import org.apache.maven.project.DependencyResolutionRequest;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.MavenProjectHelper;
+import org.apache.maven.project.ProjectDependenciesResolver;
+import org.apache.maven.repository.RepositorySystem;
+import org.apache.maven.shared.dependency.graph.DependencyGraphBuilder;
+import org.apache.xbean.finder.AnnotationFinder;
+import org.apache.xbean.finder.archive.Archive;
+import org.apache.xbean.finder.archive.ClasspathArchive;
+import org.apache.xbean.finder.util.Files;
+import org.eclipse.aether.graph.DependencyVisitor;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.IOException;
+import java.io.Writer;
+import java.lang.reflect.Modifier;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+import static java.util.Arrays.asList;
+import static java.util.Comparator.comparing;
+import static java.util.stream.Collectors.toList;
+import static java.util.stream.Collectors.toSet;
+import static org.apache.maven.plugins.annotations.ResolutionScope.RUNTIME_PLUS_SYSTEM;
+
+/**
+ * Scan at build time the beans and generate an OWB configuration to use it.
+ */
+@Mojo(name = "scan", requiresDependencyResolution = RUNTIME_PLUS_SYSTEM)
+public class ScanMojo extends AbstractMojo
+{
+ private static final String DEFAULT_DEP_EXCLUDES = "org.apache.johnzon:johnzon-," +
+ "org.apache.xbean:," +
+ "org.apache.openwebbeans:," +
+ "org.apache.tomcat:tomcat-," +
+ "org.apache.openjpa:openjpa," +
+ "org.apache.geronimo.specs:," +
+ "org.apache.commons:commons-," +
+ "commons-.+:commons-.+," +
+ "javax\\..+:.+," +
+ "org.postgresql:," +
+ "com.h2database:h2," +
+ "org.checkerframework:," +
+ "serp," +
+ "slf4j-";
+
+ @Parameter(property = "openwebbeans.skip", defaultValue = "false")
+ private boolean skip;
+
+ @Parameter(property = "openwebbeans.scanFolders", defaultValue = "false") // can move more than jars
+ private boolean scanFolders;
+
+ @Parameter(property = "openwebbeans.scopes", defaultValue = "compile,runtime")
+ private Collection<String> scopes;
+
+ @Parameter(property = "openwebbeans.libs")
+ private Collection<String> libs;
+
+ @Parameter(property = "openwebbeans.dependencies.includes")
+ private Collection<String> dependenciesIncludes;
+
+ @Parameter(property = "openwebbeans.dependencies.excludes", defaultValue = DEFAULT_DEP_EXCLUDES)
+ private Collection<String> dependenciesExcludes;
+
+ @Parameter(property = "openwebbeans.classes.excludes")
+ private Collection<String> classesExcludes;
+
+ @Parameter(defaultValue = "${project.build.outputDirectory}")
+ private File outputDirectory;
+
+ @Component
+ private MavenProjectHelper projectHelper;
+
+ @Component
+ private RepositorySystem repositorySystem;
+
+ @Component
+ private ProjectDependenciesResolver dependenciesResolver;
+
+ @Component
+ private DependencyGraphBuilder graphBuilder;
+
+ @Parameter(defaultValue = "${project}", readonly = true)
+ private MavenProject project;
+
+ /**
+ * Used to extend properties set by default.
+ */
+ @Parameter
+ private Map<String, String> openwebbeansProperties;
+
+ @Parameter(defaultValue = "CLASSES")
+ private ScanMode mode;
+
+ private Map<String, Pattern> patterns = new HashMap<>();
+
+ @Override
+ public void execute() throws MojoExecutionException
+ {
+ if (skip)
+ {
+ getLog().warn(getClass().getSimpleName() + " skipped");
+ return;
+ }
+
+ final Collection<Path> files = new ArrayList<>();
+ if (dependenciesExcludes.contains("{defaults}"))
+ {
+ dependenciesExcludes.remove("{defaults}");
+ dependenciesExcludes.addAll(asList(DEFAULT_DEP_EXCLUDES.split(",")));
+ }
+
+ collectClasspath(files);
+ if (!scanFolders)
+ {
+ files.removeIf(it -> java.nio.file.Files.isDirectory(it));
+ }
+
+ final List<URL> urls = files.stream().map(it ->
+ {
+ try
+ {
+ return it.toUri().toURL();
+ }
+ catch (final MalformedURLException e)
+ {
+ throw new IllegalStateException(e);
+ }
+ }).collect(toList());
+
+ final Thread thread = Thread.currentThread();
+ final ClassLoader oldLoader = thread.getContextClassLoader();
+ final List<Scanned> scanned;
+ try (final URLClassLoader loader = new URLClassLoader(urls.toArray(new URL[0])))
+ {
+ thread.setContextClassLoader(loader);
+ scanned = urls.stream()
+ .map(url -> doScan(url, loader))
+ .collect(toList());
+ }
+ catch (final Exception e)
+ {
+ throw new MojoExecutionException(e.getMessage(), e);
+ }
+ finally
+ {
+ thread.setContextClassLoader(oldLoader);
+ }
+
+ final Properties properties = new Properties()
+ {
+ @Override // deterministic write, not elegant but simple, avoids to recode java.util.Properties.saveConvert
+ public synchronized Enumeration<Object> keys()
+ {
+ final List<String> keys = new ArrayList<String>(List.class.cast(Collections.list(super.keys())));
+ Collections.sort(keys);
+ return Collections.enumeration(new ArrayList<>(keys));
+ }
+
+ @Override // same for java 11 and not 8
+ public Set<Map.Entry<Object, Object>> entrySet()
+ {
+ return new LinkedHashSet<>(super.entrySet().stream()
+ .sorted(comparing(it -> String.valueOf(it.getKey())))
+ .collect(toList()));
+ }
+ };
+ // meecrowave uses 1000 so let's override it
+ // for now we don't override scanner since built-in ones are able to read these meta but later we could
+ properties.setProperty("configuration.ordinal", "2000");
+ switch (mode == null ? ScanMode.CLASSES : mode)
+ {
+ case CLASSES:
+ if (!scanned.isEmpty())
+ {
+ scanned.forEach(meta -> properties.setProperty(
+ "openwebbeans.buildtime.scanning." + meta.name + ".classes",
+ String.join(",", meta.classes)));
+ }
+ break;
+ default:
+ getLog().error("Unsupported scan mode: " + mode);
+ }
+
+ if (openwebbeansProperties != null) // easy way to customize a docker image or so let's support it
+ {
+ openwebbeansProperties.forEach(properties::setProperty);
+ }
+
+ final Path output = outputDirectory.toPath().resolve("META-INF/openwebbeans/openwebbeans.properties");
+ try
+ {
+ java.nio.file.Files.createDirectories(output.getParent());
+ try (final Writer writer = new BufferedWriter(java.nio.file.Files.newBufferedWriter(output))
+ {
+ @Override
+ public void write(final String str) throws IOException
+ {
+ if (!str.startsWith("#")) // skip date comment (and we don't care of other comments btw)
+ {
+ super.write(str);
+ }
+ }
+ })
+ {
+ // don't use store() to ensure it is reproducible (no date)
+ properties.store(writer, "");
+ }
+ }
+ catch (final IOException ioe)
+ {
+ throw new IllegalStateException(ioe);
+ }
+ }
+
+ private Scanned doScan(final URL url, final ClassLoader loader)
+ {
+ final File file = Files.toFile(url);
+ final Archive archive = ClasspathArchive.archive(loader, url);
+ final Collection<String> classes = new AnnotationFinder(archive, false)
+ .getAnnotatedClassNames().stream()
+ .filter(it ->
+ {
+ try
+ {
+ final Class<?> aClass = loader.loadClass(it);
+ return !aClass.isAnonymousClass() &&
+ !Modifier.isPrivate(aClass.getModifiers());
+ }
+ catch (final ClassNotFoundException | NoClassDefFoundError err)
+ {
+ return false;
+ }
+ })
+ .filter(it -> classesExcludes == null || classesExcludes.stream().noneMatch(it::startsWith))
+ .sorted()
+ .collect(toList());
+ return new Scanned(file.getName(), classes);
+ }
+
+ protected void collectClasspath(final Collection<Path> files)
+ {
+ final Collection<String> includedArtifacts = project.getArtifacts().stream()
+ .filter(this::isIncluded)
+ .map(a ->
+ {
+ files.add(a.getFile().toPath());
+ return a.getArtifactId();
+ }).collect(toSet());
+ libs.forEach(l ->
+ {
+ final boolean transitive = l.endsWith("?transitive");
+ final String coords = transitive ? l.substring(0, l.length() - "?transitive".length()) : l;
+ final String[] c = coords.split(":");
+ if (c.length < 3 || c.length > 5)
+ {
+ throw new IllegalArgumentException("libs syntax is groupId:artifactId:version[:classifier][:type[?transitive]]");
+ }
+ if (!transitive)
+ {
+ files.add(resolve(c[0], c[1], c[2], c.length == 4 ? c[3] : ""));
+ }
+ else
+ {
+ addTransitiveDependencies(files, includedArtifacts, new Dependency()
+ {{
+ setGroupId(c[0]);
+ setArtifactId(c[1]);
+ setVersion(c[2]);
+ if (c.length == 4 && !"-".equals(c[3]))
+ {
+ setClassifier(c[3]);
+ }
+ if (c.length == 5)
+ {
+ setType(c[4]);
+ }
+ }});
+ }
+ });
+ }
+
+ private void addTransitiveDependencies(final Collection<Path> aggregator,
+ final Collection<String> includedArtifacts, final Dependency dependency)
+ {
+ final DependencyResolutionRequest request = new DefaultDependencyResolutionRequest();
+ request.setMavenProject(new MavenProject()
+ {{
+ getDependencies().add(dependency);
+ }});
+ try
+ {
+ dependenciesResolver
+ .resolve(request)
+ .getDependencyGraph()
+ .accept(new DependencyVisitor()
+ {
+ @Override
+ public boolean visitEnter(final org.eclipse.aether.graph.DependencyNode node)
+ {
+ return true;
+ }
+
+ @Override
+ public boolean visitLeave(final org.eclipse.aether.graph.DependencyNode node)
+ {
+ final org.eclipse.aether.artifact.Artifact artifact = node.getArtifact();
+ if (artifact != null && includedArtifacts.add(artifact.getArtifactId()))
+ {
+ aggregator.add(artifact.getFile().toPath());
+ }
+ return true;
+ }
+ });
+ }
+ catch (final DependencyResolutionException e)
+ {
+ throw new IllegalStateException(e.getMessage(), e);
+ }
+ }
+
+ private Path resolve(final String group, final String artifact, final String version, final String classifier)
+ {
+ final DefaultArtifact art = new DefaultArtifact(
+ group, artifact, version, "compile", "jar", classifier, new DefaultArtifactHandler());
+ final ArtifactResolutionRequest artifactRequest = new ArtifactResolutionRequest()
+ .setArtifact(art);
+ final ArtifactResolutionResult result = repositorySystem.resolve(artifactRequest);
+ if (!result.isSuccess())
+ {
+ throw new IllegalStateException("Can't find " + art + ", please add it to the pom.");
+ }
+ return result.getArtifacts().iterator().next().getFile().toPath();
+ }
+
+
+ private boolean isIncluded(final Artifact a)
+ {
+ return (!((scopes == null &&
+ !(Artifact.SCOPE_COMPILE.equals(a.getScope()) || Artifact.SCOPE_RUNTIME.equals(a.getScope())))
+ || (scopes != null && !scopes.contains(a.getScope())))) &&
+ isExplicitlyIncluded(a);
+ }
+
+ private boolean isExplicitlyIncluded(final Artifact art)
+ {
+ if (dependenciesExcludes.isEmpty() && dependenciesIncludes.isEmpty())
+ {
+ return true;
+ }
+ final String coord = art.getGroupId() + ':' + art.getArtifactId();
+ final String artOnly = art.getArtifactId();
+ if (!dependenciesIncludes.isEmpty() && dependenciesExcludes.isEmpty())
+ {
+ return dependenciesIncludes.stream()
+ .anyMatch(it -> compare(coord, artOnly, it));
+ }
+ if (dependenciesIncludes.isEmpty() && !dependenciesExcludes.isEmpty())
+ {
+ return dependenciesExcludes.stream()
+ .noneMatch(it -> compare(coord, artOnly, it));
+ }
+ final boolean forced = dependenciesIncludes.stream()
+ .anyMatch(it -> compare(coord, artOnly, it));
+ if (forced)
+ {
+ return true;
+ }
+ final boolean notExcluded = dependenciesExcludes.stream()
+ .noneMatch(it -> compare(coord, artOnly, it));
+ return notExcluded;
+ }
+
+ private boolean compare(final String coord, final String artOnly, final String conf)
+ {
+ return coord.startsWith(conf) || artOnly.startsWith(conf) || patterns.computeIfAbsent(conf, k ->
+ {
+ try
+ {
+ return Pattern.compile(k);
+ }
+ catch (final Exception e)
+ {
+ // whatever, ignore pattern
+ return Pattern.compile("/\\\\");
+ }
+ }).matcher(coord).matches();
+ }
+
+ private static class Scanned
+ {
+ private final String name;
+ private final Collection<String> classes;
+
+ private Scanned(final String name, final Collection<String> classes)
+ {
+ this.name = name;
+ this.classes = classes;
+ }
+ }
+
+ // this will be used to add new mode like "FULLY_PRE_SCANNED"
+ // where we wouldn't use the classloader but only the meta to scan
+ public enum ScanMode
+ {
+ // means we map the list of classes per jar,
+ // it enables to speed up scanning and keep extensibility of CDI
+ CLASSES
+ }
+}
diff --git a/webbeans-maven-plugin/src/main/resources/META-INF/MANIFEST.MF b/webbeans-maven-plugin/src/main/resources/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..9d885be
--- /dev/null
+++ b/webbeans-maven-plugin/src/main/resources/META-INF/MANIFEST.MF
@@ -0,0 +1 @@
+Manifest-Version: 1.0
diff --git a/webbeans-web/src/test/java/org/apache/webbeans/web/tests/WebBeansTest.java b/webbeans-web/src/test/java/org/apache/webbeans/web/tests/WebBeansTest.java
index 82d1828..cbbb1f0 100644
--- a/webbeans-web/src/test/java/org/apache/webbeans/web/tests/WebBeansTest.java
+++ b/webbeans-web/src/test/java/org/apache/webbeans/web/tests/WebBeansTest.java
@@ -79,7 +79,9 @@ public class WebBeansTest {
@Override
public void scan()
{
- archive = new CdiArchive(new DefaultBeanArchiveService(), Thread.currentThread().getContextClassLoader(), new HashMap<String, URL>(), null, null);
+ archive = new CdiArchive(
+ new DefaultBeanArchiveService(), Thread.currentThread().getContextClassLoader(),
+ new HashMap<String, URL>(), null, null, null);
finder = new OwbAnnotationFinder(new ClassesArchive());
}
}