diff --git a/src/main/java/org/cyclonedx/maven/BaseCycloneDxMojo.java b/src/main/java/org/cyclonedx/maven/BaseCycloneDxMojo.java
index 4ce1eafe..21599b84 100644
--- a/src/main/java/org/cyclonedx/maven/BaseCycloneDxMojo.java
+++ b/src/main/java/org/cyclonedx/maven/BaseCycloneDxMojo.java
@@ -215,21 +215,11 @@ public abstract class BaseCycloneDxMojo extends AbstractMojo {
private String outputTimestamp;
/**
- * External references to be added.
- *
- * They will be injected in two locations:
- *
- *
- * $.metadata.component.externalReferences[]
- * $.components[].externalReferences[]
(only for $.components[]
provided by the project)
- *
+ * External references to be added to $.metadata.component.externalReferences[]
.
*/
@Parameter
private ExternalReference[] externalReferences;
- @Parameter(defaultValue = "${mojoExecution}", readonly = true, required = true)
- private MojoExecution execution;
-
@org.apache.maven.plugins.annotations.Component
private MavenProjectHelper mavenProjectHelper;
@@ -270,7 +260,7 @@ protected String generatePackageUrl(final Artifact artifact) {
}
protected Component convert(Artifact artifact) {
- return modelConverter.convert(execution, artifact, schemaVersion(), includeLicenseText);
+ return modelConverter.convert(artifact, schemaVersion(), includeLicenseText, externalReferences);
}
/**
@@ -314,7 +304,7 @@ public void execute() throws MojoExecutionException {
String analysis = extractComponentsAndDependencies(topLevelComponents, componentMap, dependencyMap);
if (analysis != null) {
- final Metadata metadata = modelConverter.convert(project, projectType, execution, schemaVersion(), includeLicenseText);
+ final Metadata metadata = modelConverter.convert(project, projectType, schemaVersion(), includeLicenseText, externalReferences);
if (schemaVersion().getVersion() >= 1.3) {
metadata.addProperty(newProperty("maven.goal", analysis));
diff --git a/src/main/java/org/cyclonedx/maven/DefaultModelConverter.java b/src/main/java/org/cyclonedx/maven/DefaultModelConverter.java
index 62b9dc12..fce6d4b6 100644
--- a/src/main/java/org/cyclonedx/maven/DefaultModelConverter.java
+++ b/src/main/java/org/cyclonedx/maven/DefaultModelConverter.java
@@ -18,42 +18,20 @@
*/
package org.cyclonedx.maven;
-import java.io.File;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Properties;
-import java.util.TreeMap;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import javax.annotation.Nullable;
-import javax.inject.Inject;
-import javax.inject.Named;
-import javax.inject.Singleton;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.MapperFeature;
-import com.fasterxml.jackson.dataformat.xml.XmlMapper;
+import com.github.packageurl.MalformedPackageURLException;
+import com.github.packageurl.PackageURL;
import org.apache.commons.lang3.StringUtils;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.DefaultArtifact;
import org.apache.maven.artifact.handler.DefaultArtifactHandler;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.MailingList;
-import org.apache.maven.model.Plugin;
import org.apache.maven.model.building.ModelBuildingRequest;
-import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuilder;
import org.apache.maven.project.ProjectBuildingException;
import org.apache.maven.project.ProjectBuildingResult;
import org.apache.maven.repository.RepositorySystem;
-import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.cyclonedx.CycloneDxSchema;
import org.cyclonedx.model.Component;
import org.cyclonedx.model.ExternalReference;
@@ -67,8 +45,18 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.github.packageurl.MalformedPackageURLException;
-import com.github.packageurl.PackageURL;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
+import java.util.TreeMap;
+import java.util.stream.Collectors;
@Singleton
@Named
@@ -165,9 +153,7 @@ private String generatePackageUrl(String groupId, String artifactId, String vers
}
@Override
- public Component convert(MojoExecution execution, Artifact artifact, CycloneDxSchema.Version schemaVersion, boolean includeLicenseText) {
-
- // Populate basic fields from the `Artifact` instance
+ public Component convert(Artifact artifact, CycloneDxSchema.Version schemaVersion, boolean includeLicenseText, ExternalReference[] externalReferences) {
final Component component = new Component();
component.setGroup(artifact.getGroupId());
component.setName(artifact.getArtifactId());
@@ -202,8 +188,7 @@ public Component convert(MojoExecution execution, Artifact artifact, CycloneDxSc
if (project != null) {
// Populate external references
- List externalReferences = extractExternalReferences(project, execution);
- component.setExternalReferences(externalReferences);
+ setExternalReferences(component, externalReferences);
// Extract the rest of the metadata for JARs, i.e., *described* artifacts
if (isDescribedArtifact(artifact)) {
@@ -217,68 +202,13 @@ public Component convert(MojoExecution execution, Artifact artifact, CycloneDxSc
}
- private List extractExternalReferences(MavenProject project, MojoExecution activeExecution) {
- Plugin activePlugin = activeExecution.getPlugin();
- return project
- .getBuild()
- .getPlugins()
- .stream()
- .filter(plugin -> activePlugin.getGroupId().equals(plugin.getGroupId()) && activePlugin.getArtifactId().equals(plugin.getArtifactId()))
- .findFirst()
- .map(plugin -> extractExternalReferences(plugin, activeExecution))
- .orElseGet(ArrayList::new);
- }
-
- private static List extractExternalReferences(Plugin plugin, MojoExecution activeExecution) {
-
- // Collect external references from the execution configuration
- List executionExternalReferences = plugin
- .getExecutions()
- .stream()
- .filter(execution -> activeExecution.getExecutionId().equals(execution.getId()))
- .flatMap(execution -> {
- Xpp3Dom executionConfig = (Xpp3Dom) execution.getConfiguration();
- return ExternalReferenceConfigDto.parseDom(executionConfig).stream();
- })
- .collect(Collectors.toList());
-
- // Collect external references from the plugin configuration
- Xpp3Dom pluginConfig = (Xpp3Dom) plugin.getConfiguration();
- List pluginExternalReferences = ExternalReferenceConfigDto.parseDom(pluginConfig);
-
- // Combine collected external references
- return Stream
- .concat(executionExternalReferences.stream(), pluginExternalReferences.stream())
- .distinct()
- .collect(Collectors.toList());
-
- }
-
- private static final class ExternalReferenceConfigDto {
-
- private static final XmlMapper MAPPER = XmlMapper
- .builder()
- .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
- .enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS)
- .build();
-
- private static List parseDom(@Nullable Xpp3Dom dom) {
- if (dom == null) {
- return new ArrayList<>();
- }
- String xml = dom.toString();
- try {
- ExternalReferenceConfigDto dto = MAPPER.readValue(xml, ExternalReferenceConfigDto.class);
- @Nullable List externalReferences = dto.externalReferences;
- return externalReferences != null ? externalReferences : new ArrayList<>();
- } catch (JsonProcessingException error) {
- throw new RuntimeException(error);
- }
+ private static void setExternalReferences(Component component, ExternalReference[] externalReferences) {
+ if (externalReferences == null || externalReferences.length == 0) {
+ return;
}
-
- @JsonProperty
- private List externalReferences;
-
+ // We need a mutable `List`, hence `Arrays.asList()` won't work!
+ List externalReferences_ = Arrays.stream(externalReferences).collect(Collectors.toList());
+ component.setExternalReferences(externalReferences_);
}
private boolean isModified(Artifact artifact) {
@@ -433,7 +363,7 @@ else if (licenseChoiceToResolve.getExpression() != null && CycloneDxSchema.Versi
}
@Override
- public Metadata convert(final MavenProject project, String projectType, MojoExecution execution, CycloneDxSchema.Version schemaVersion, boolean includeLicenseText) {
+ public Metadata convert(final MavenProject project, String projectType, CycloneDxSchema.Version schemaVersion, boolean includeLicenseText, ExternalReference[] externalReferences) {
final Tool tool = new Tool();
final Properties properties = readPluginProperties();
tool.setVendor(properties.getProperty("vendor"));
@@ -459,9 +389,7 @@ public Metadata convert(final MavenProject project, String projectType, MojoExec
component.setType(resolveProjectType(projectType));
component.setPurl(generatePackageUrl(project.getArtifact()));
component.setBomRef(component.getPurl());
-
- List externalReferences = extractExternalReferences(project, execution);
- component.setExternalReferences(externalReferences);
+ setExternalReferences(component, externalReferences);
extractComponentMetadata(project, component, schemaVersion, includeLicenseText);
final Metadata metadata = new Metadata();
diff --git a/src/main/java/org/cyclonedx/maven/ModelConverter.java b/src/main/java/org/cyclonedx/maven/ModelConverter.java
index d3ae77f8..43115c8a 100644
--- a/src/main/java/org/cyclonedx/maven/ModelConverter.java
+++ b/src/main/java/org/cyclonedx/maven/ModelConverter.java
@@ -19,10 +19,10 @@
package org.cyclonedx.maven;
import org.apache.maven.artifact.Artifact;
-import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.project.MavenProject;
import org.cyclonedx.CycloneDxSchema;
import org.cyclonedx.model.Component;
+import org.cyclonedx.model.ExternalReference;
import org.cyclonedx.model.Metadata;
/**
@@ -44,24 +44,23 @@ public interface ModelConverter {
* Converts a Maven artifact (dependency or transitive dependency) into a
* CycloneDX component.
*
- * @param execution the associated execution
* @param artifact the artifact to convert
* @param schemaVersion the target CycloneDX schema version
* @param includeLicenseText should license text be included in bom?
+ * @param externalReferences the external references
* @return a CycloneDX component
*/
- Component convert(MojoExecution execution, Artifact artifact, CycloneDxSchema.Version schemaVersion, boolean includeLicenseText);
+ Component convert(Artifact artifact, CycloneDxSchema.Version schemaVersion, boolean includeLicenseText, ExternalReference[] externalReferences);
/**
* Converts a MavenProject into a Metadata object.
*
* @param project the MavenProject to convert
* @param projectType the target CycloneDX component type
- * @param execution the associated execution
* @param schemaVersion the target CycloneDX schema version
* @param includeLicenseText should license text be included in bom?
+ * @param externalReferences the external references
* @return a CycloneDX Metadata object
*/
- Metadata convert(MavenProject project, String projectType, MojoExecution execution, CycloneDxSchema.Version schemaVersion, boolean includeLicenseText);
-
+ Metadata convert(MavenProject project, String projectType, CycloneDxSchema.Version schemaVersion, boolean includeLicenseText, ExternalReference[] externalReferences);
}
diff --git a/src/test/java/org/cyclonedx/maven/ExternalReferenceTest.java b/src/test/java/org/cyclonedx/maven/ExternalReferenceTest.java
index 2d082b72..db8b80ee 100644
--- a/src/test/java/org/cyclonedx/maven/ExternalReferenceTest.java
+++ b/src/test/java/org/cyclonedx/maven/ExternalReferenceTest.java
@@ -34,7 +34,6 @@ public void testAddedExternalReferences() throws Exception {
verifier
.forProject(projDir)
.withCliOption("-Dcyclonedx-maven-plugin.version=" + getCurrentVersion())
- .withCliOption("-X")
.withCliOption("-B")
.execute("clean", "verify")
.assertErrorFreeLog();
@@ -45,12 +44,6 @@ public void testAddedExternalReferences() throws Exception {
"$.metadata.component.externalReferences[?(@.type=='chat')].url",
Collections.singleton("https://acme.com/parent"));
- // Verify parent components
- assertExternalReferences(
- new File(projDir, "target/bom.json"),
- "$.components[?(@.name=='child')].externalReferences[?(@.type=='chat')].url",
- Arrays.asList("https://acme.com/parent", "https://acme.com/child"));
-
// Verify child metadata
assertExternalReferences(
new File(projDir, "child/target/bom.json"),