Skip to content

Commit

Permalink
Generate externalRefs with PURL
Browse files Browse the repository at this point in the history
  • Loading branch information
rogelio-o committed Jan 17, 2024
1 parent fad39c1 commit c65a9f1
Show file tree
Hide file tree
Showing 11 changed files with 244 additions and 22 deletions.
15 changes: 11 additions & 4 deletions src/main/java/org/spdx/maven/CreateSpdxMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -478,9 +478,16 @@ public class CreateSpdxMojo extends AbstractMojo
* If true, use ${project.groupId}:${artifactId} as the SPDX package name.
* Otherwise, ${project.name} will be used
*/
@Parameter
@Parameter( property = "spdx.useArtifactID" )
private boolean useArtifactID;

/**
* If true, adds an external reference to every package with category "PACKAGE-MANAGER", type "purl"
* and locator "pkg:maven/${project.groupId}/${project.artifactId}@${project.version}".
*/
@Parameter( property = "spdx.generatePurls" )
private boolean generatePurls;

public void execute() throws MojoExecutionException
{
if ( skip )
Expand Down Expand Up @@ -608,7 +615,7 @@ private SpdxDocumentBuilder initSpdxDocumentBuilder( OutputFormat outputFormatEn
spdxDocumentNamespace = spdxDocumentNamespace.replace( " ", "%20" );
}
URI namespaceUri = new URI( spdxDocumentNamespace );
builder = new SpdxDocumentBuilder( spdxFile, namespaceUri,
builder = new SpdxDocumentBuilder( mavenProject, generatePurls, spdxFile, namespaceUri,
this.matchLicensesOnCrossReferenceUrls, outputFormatEnum );
}
catch ( SpdxBuilderException e )
Expand Down Expand Up @@ -652,7 +659,7 @@ private SpdxDependencyInformation getSpdxDependencyInformation( Set<Artifact> de
SpdxDocumentBuilder builder,
boolean useArtifactID ) throws LicenseMapperException, InvalidSPDXAnalysisException
{
SpdxDependencyInformation retval = new SpdxDependencyInformation( builder.getLicenseManager(), builder.getSpdxDoc(), createExternalRefs );
SpdxDependencyInformation retval = new SpdxDependencyInformation( builder.getLicenseManager(), builder.getSpdxDoc(), createExternalRefs, generatePurls );
if ( dependencies != null )
{
for ( Artifact dependency : dependencies )
Expand Down Expand Up @@ -798,7 +805,7 @@ private void logIncludedDirectories( List<FileSet> includedDirectories )
}

/**
* @param container SPDX Document containing any extracted license infos
* @param spdxDoc SPDX Document containing any extracted license infos
* @return default file information from the plugin parameters
* @throws MojoExecutionException
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,17 @@
import org.spdx.library.SpdxInvalidIdException;
import org.spdx.library.model.Checksum;
import org.spdx.library.model.ExternalDocumentRef;
import org.spdx.library.model.ExternalRef;
import org.spdx.library.model.ExternalSpdxElement;
import org.spdx.library.model.ReferenceType;
import org.spdx.library.model.Relationship;
import org.spdx.library.model.SpdxDocument;
import org.spdx.library.model.SpdxElement;
import org.spdx.library.model.SpdxPackage;
import org.spdx.library.model.enumerations.AnnotationType;
import org.spdx.library.model.enumerations.ChecksumAlgorithm;
import org.spdx.library.model.enumerations.Purpose;
import org.spdx.library.model.enumerations.ReferenceCategory;
import org.spdx.library.model.enumerations.RelationshipType;
import org.spdx.library.model.license.AnyLicenseInfo;
import org.spdx.library.model.license.SpdxNoAssertionLicense;
Expand Down Expand Up @@ -153,16 +156,18 @@ public RelationshipType getRelationshipType()
private LicenseManager licenseManager;
private SpdxDocument spdxDoc;
private boolean createExternalRefs = false;
private boolean generatePurls = false;
DateFormat format = new SimpleDateFormat( SpdxConstants.SPDX_DATE_FORMAT );

/**
*/
public SpdxDependencyInformation( LicenseManager licenseManager,
SpdxDocument spdxDoc, boolean createExternalRefs )
SpdxDocument spdxDoc, boolean createExternalRefs, boolean generatePurls )
{
this.licenseManager = licenseManager;
this.spdxDoc = spdxDoc;
this.createExternalRefs = createExternalRefs;
this.generatePurls = generatePurls;
}

/**
Expand Down Expand Up @@ -360,6 +365,11 @@ private SpdxElement createSpdxPackage( Artifact artifact,
.setComment( "This package was created for a Maven dependency. No SPDX or license information could be found in the Maven POM file." )
.setVersionInfo( artifact.getBaseVersion() )
.setFilesAnalyzed( false )
<<<<<<< Updated upstream
=======
.setDownloadLocation( "NOASSERTION" )
.setExternalRefs( SpdxExternalRefBuilder.getDefaultExternalRefs( spdxDoc, generatePurls, mavenProject ) )
>>>>>>> Stashed changes
.build();
return pkg;
}
Expand Down Expand Up @@ -668,6 +678,7 @@ private SpdxPackage createSpdxPackage( MavenProject project, boolean useArtifact
packageName, new SpdxNoAssertionLicense(), copyright, declaredLicense )
.setDownloadLocation( downloadLocation )
.setFilesAnalyzed( false )
.setExternalRefs( SpdxExternalRefBuilder.getDefaultExternalRefs( spdxDoc, generatePurls, project ) )
.build();
if ( project.getVersion() != null )
{
Expand Down
8 changes: 7 additions & 1 deletion src/main/java/org/spdx/maven/utils/SpdxDocumentBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import java.util.Set;

import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.shared.model.fileset.FileSet;

import org.spdx.jacksonstore.MultiFormatStore;
Expand Down Expand Up @@ -80,6 +81,8 @@ public class SpdxDocumentBuilder
//TODO: Map the SPDX document to the Maven build artifacts
DateFormat format = new SimpleDateFormat( SpdxConstants.SPDX_DATE_FORMAT );

private MavenProject project;
private boolean generatePurls;
private SpdxDocument spdxDoc;
private SpdxPackage projectPackage;
private LicenseManager licenseManager;
Expand All @@ -98,9 +101,11 @@ public class SpdxDocumentBuilder
* @throws SpdxBuilderException
* @throws LicenseMapperException
*/
public SpdxDocumentBuilder( File spdxFile, URI spdxDocumentNamespace,
public SpdxDocumentBuilder( MavenProject project, boolean generatePurls, File spdxFile, URI spdxDocumentNamespace,
boolean useStdLicenseSourceUrls, OutputFormat outputFormat ) throws SpdxBuilderException, LicenseMapperException
{
this.project = project;
this.generatePurls = generatePurls;
this.spdxFile = spdxFile;

if ( spdxDocumentNamespace == null )
Expand Down Expand Up @@ -336,6 +341,7 @@ private SpdxPackage createSpdxPackage( SpdxProjectInformation projectInformation
.setDownloadLocation( downloadUrl )
.setPackageVerificationCode( nullPackageVerificationCode )
.setPrimaryPurpose( projectInformation.getPrimaryPurpose() )
.setExternalRefs( SpdxExternalRefBuilder.getDefaultExternalRefs( spdxDoc, generatePurls, project ) )
.build();
}
catch ( InvalidSPDXAnalysisException e )
Expand Down
40 changes: 40 additions & 0 deletions src/main/java/org/spdx/maven/utils/SpdxExternalRefBuilder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package org.spdx.maven.utils;

import java.util.Collection;
import java.util.List;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.project.MavenProject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.spdx.library.InvalidSPDXAnalysisException;
import org.spdx.library.model.ExternalRef;
import org.spdx.library.model.ReferenceType;
import org.spdx.library.model.SpdxDocument;
import org.spdx.library.model.enumerations.ReferenceCategory;

public class SpdxExternalRefBuilder
{

private static final Logger LOG = LoggerFactory.getLogger( SpdxExternalRefBuilder.class );

public static Collection<ExternalRef> getDefaultExternalRefs( SpdxDocument spdxDoc, boolean generatePurls, MavenProject project ) {
ExternalRef generatedPurlExternalRef = generatePurls ? generatePurlExternalRef( spdxDoc, project ) : null;
return generatedPurlExternalRef == null ? List.of() : List.of(generatedPurlExternalRef);
}

private static ExternalRef generatePurlExternalRef( SpdxDocument spdxDoc, MavenProject project )
{
try
{
String purl = "pkg:maven/" + project.getGroupId() + "/" + project.getArtifactId() + "@" + project.getVersion();
return spdxDoc.createExternalRef( ReferenceCategory.PACKAGE_MANAGER, new ReferenceType("http://spdx.org/rdf/references/purl"),
purl, null );
}
catch (InvalidSPDXAnalysisException e)
{
LOG.warn( "Invalid reference type \"purl\" for generated purl external ref");
return null;
}
}

}
61 changes: 55 additions & 6 deletions src/test/java/org/spdx/maven/TestSpdxMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.spdx.jacksonstore.MultiFormatStore;
import org.spdx.jacksonstore.MultiFormatStore.Format;
import org.spdx.library.ModelCopyManager;
import org.spdx.library.model.ExternalRef;
import org.spdx.library.model.ReferenceType;
import org.spdx.library.model.SpdxDocument;
import org.spdx.library.model.SpdxElement;
import org.spdx.library.model.SpdxFile;
Expand Down Expand Up @@ -77,7 +79,7 @@ public void testExecute() throws Exception
assertTrue( spdxFile.exists() );
// Test output artifact file is created
File artifactFile = getTestFile(
"target/test-classes/unit/spdx-maven-plugin-test/spdx maven plugin test.spdx.rdf.xml" );
"target/test-classes/unit/spdx-maven-plugin-test/spdx-maven-plugin-test.spdx.rdf.xml" );
assertTrue( artifactFile.exists() );
ISerializableModelStore modelStore = new RdfStore();
ModelCopyManager copyManager = new ModelCopyManager();
Expand Down Expand Up @@ -321,7 +323,7 @@ public void testExecuteUseArtfactId() throws Exception
assertTrue( spdxFile.exists() );
// Test output artifact file is created
File artifactFile = getTestFile(
"target/test-classes/unit/spdx-maven-plugin-test/spdx maven plugin test.spdx.json" );
"target/test-classes/unit/spdx-maven-plugin-test/spdx-maven-plugin-test.spdx.json" );
assertTrue( artifactFile.exists() );
ISerializableModelStore modelStore = new MultiFormatStore( new InMemSpdxStore(), Format.JSON );
ModelCopyManager copyManager = new ModelCopyManager();
Expand Down Expand Up @@ -431,7 +433,7 @@ else if ( creator.equals( "Person: Creator2" ) )
assertTrue( described instanceof SpdxPackage );
SpdxPackage pkg = (SpdxPackage) described;
// name
assertEquals( "org.spdx:spdx maven plugin test", pkg.getName().get() );
assertEquals( "org.spdx:spdx-maven-plugin-test", pkg.getName().get() );
// packageAnnotations
assertEquals( 1, pkg.getAnnotations().size() );
org.spdx.library.model.Annotation annotation = pkg.getAnnotations().toArray( new org.spdx.library.model.Annotation [pkg.getAnnotations().size()] )[0];
Expand Down Expand Up @@ -567,7 +569,7 @@ public void testExecuteJson() throws Exception
assertTrue( spdxFile.exists() );
// Test output artifact file is created
File artifactFile = getTestFile(
"target/test-classes/unit/spdx-maven-plugin-test/spdx maven plugin test.spdx.json" );
"target/test-classes/unit/spdx-maven-plugin-test/spdx-maven-plugin-test.spdx.json" );
assertTrue( artifactFile.exists() );
ISerializableModelStore modelStore = new MultiFormatStore( new InMemSpdxStore(), Format.JSON );
ModelCopyManager copyManager = new ModelCopyManager();
Expand Down Expand Up @@ -850,7 +852,7 @@ public void testExecuteUriNotUrl() throws Exception
assertTrue( spdxFile.exists() );
// Test output artifact file is created
File artifactFile = getTestFile(
"target/test-classes/unit/spdx-maven-plugin-test/spdx maven plugin test.spdx.rdf.xml" );
"target/test-classes/unit/spdx-maven-plugin-test/spdx-maven-plugin-test.spdx.rdf.xml" );
assertTrue( artifactFile.exists() );
ISerializableModelStore modelStore = new RdfStore();
ModelCopyManager copyManager = new ModelCopyManager();
Expand Down Expand Up @@ -883,7 +885,7 @@ public void testExecuteNoContributors() throws Exception
assertTrue( spdxFile.exists() );
// Test output artifact file is created
File artifactFile = getTestFile(
"target/test-classes/unit/spdx-maven-plugin-test/spdx maven plugin test.spdx.rdf.xml" );
"target/test-classes/unit/spdx-maven-plugin-test/spdx-maven-plugin-test.spdx.rdf.xml" );
assertTrue( artifactFile.exists() );
ISerializableModelStore modelStore = new RdfStore();
ModelCopyManager copyManager = new ModelCopyManager();
Expand Down Expand Up @@ -1110,4 +1112,51 @@ else if ( externalRefs[0].getReferenceCategory().equals(
assertEquals( fileWithSnippet, snippets.get( 1 ).getSnippetFromFile().getId() );
//TODO Test dependencies
}

@Test
public void testExecuteUseGeneratePurls() throws Exception
{
File testPom = new File( getBasedir(), UNIT_TEST_RESOURCE_DIR + "/json-pom-generate-purl.xml" );
// CreateSpdxMojo mojo = (CreateSpdxMojo) configureMojo( myMojo, "spdx-maven-plugin", testPom );
// if the below does not work due to a lookup error, run mvn test goal
CreateSpdxMojo mojo = (CreateSpdxMojo) lookupMojo( "createSPDX", testPom );
assertNotNull( mojo );
mojo.execute();
// Test SPDX filename parameter
File spdxFile = new File( getBasedir(), SPDX_JSON_FILE_NAME );
assertTrue( spdxFile.exists() );
// Test output artifact file is created
File artifactFile = getTestFile(
"target/test-classes/unit/spdx-maven-plugin-test/spdx-maven-plugin-test.spdx.json" );
assertTrue( artifactFile.exists() );
ISerializableModelStore modelStore = new MultiFormatStore( new InMemSpdxStore(), Format.JSON );
ModelCopyManager copyManager = new ModelCopyManager();
SpdxDocument result;
String documentUri;
try ( InputStream is = new FileInputStream( artifactFile.getAbsolutePath() ) )
{
documentUri = modelStore.deSerialize( is, false );
result = new SpdxDocument( modelStore, documentUri, copyManager, false );
}
List<String> warnings = result.verify();
assertEquals( 0, warnings.size() );
// Test configuration parameters found in the test resources pom.xml file
// Document namespace
assertEquals( "http://spdx.org/documents/spdx%20toolsv2.0%20rc1", result.getDocumentUri() );
// purls
List<SpdxPackage> packages = new ArrayList<>();
SpdxModelFactory.getElements( modelStore, documentUri, copyManager, SpdxPackage.class ).forEach( (pkg) -> {
packages.add( (SpdxPackage)pkg );
});
for ( SpdxPackage pkg : packages ) {
Collection<ExternalRef> externalRefs = pkg.getExternalRefs();
assertNotNull( externalRefs );
assertFalse( externalRefs.isEmpty() );
ExternalRef externalRef = pkg.getExternalRefs().stream().findFirst().get();
assertEquals( externalRef.getReferenceCategory(), ReferenceCategory.PACKAGE_MANAGER );
assertEquals( externalRef.getReferenceType().getIndividualURI(), "http://spdx.org/rdf/references/purl");
assertEquals( externalRef.getReferenceLocator(),
"pkg:maven/" + pkg.getName().get().replace(":", "/") + "@" + pkg.getVersionInfo().get() );
}
}
}
Loading

0 comments on commit c65a9f1

Please sign in to comment.