com.metaeffekt.artifact.analysis.bom.spdx.facade.SpdxApiFacade Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2021-2024 the original author or authors.
*
* Licensed 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 com.metaeffekt.artifact.analysis.bom.spdx.facade;
import lombok.extern.slf4j.Slf4j;
import org.metaeffekt.core.inventory.processor.model.Artifact;
import org.spdx.jacksonstore.MultiFormatStore;
import org.spdx.library.InvalidSPDXAnalysisException;
import org.spdx.library.ModelCopyManager;
import org.spdx.library.Read;
import org.spdx.library.SpdxConstants;
import org.spdx.library.model.Relationship;
import org.spdx.library.model.SpdxDocument;
import org.spdx.library.model.SpdxPackage;
import org.spdx.library.model.enumerations.RelationshipType;
import org.spdx.library.model.license.AnyLicenseInfo;
import org.spdx.library.model.license.ExtractedLicenseInfo;
import org.spdx.library.model.license.InvalidLicenseStringException;
import org.spdx.library.model.license.LicenseInfoFactory;
import org.spdx.storage.IModelStore;
import org.spdx.storage.simple.InMemSpdxStore;
import java.io.File;
import java.io.FileInputStream;
import java.util.List;
import java.util.stream.Collectors;
@Slf4j
public class SpdxApiFacade {
public static void addRelationshipsToDocument(SpdxDocument spdxDocument, String fromNode,
List toNodes, RelationshipType relationshipType) {
for (String toNode : toNodes) {
try {
if (fromNode.equals("DOCUMENT")) {
spdxDocument.getDocumentDescribes().add(getPackageByName(toNode, spdxDocument));
continue;
}
Relationship relationship = spdxDocument.createRelationship(getPackageByName(toNode, spdxDocument),
relationshipType, null);
SpdxPackage spdxPackage = getPackageByName(fromNode, spdxDocument);
if (spdxPackage != null) {
spdxPackage.addRelationship(relationship);
}
} catch (InvalidSPDXAnalysisException e) {
throw new RuntimeException("Failed to add Relationship: " + fromNode + " to the document.",e);
}
}
}
public static SpdxPackage getPackageByName(String name, SpdxDocument spdxDocument) {
List spdxPackages;
try {
spdxPackages = Read.getAllPackages(spdxDocument.getModelStore(),
spdxDocument.getDocumentUri()).collect(Collectors.toList());
} catch (InvalidSPDXAnalysisException e) {
throw new RuntimeException("Failed to get all packages from SpdxDocument.", e);
}
for (SpdxPackage spdxPackage : spdxPackages) {
try {
if (spdxPackage.getName().orElse("").equals(name)) {
return spdxPackage;
}
} catch (InvalidSPDXAnalysisException e) {
throw new RuntimeException("SpdxPackage: "+ spdxPackage.getId() +" does not have a name.", e);
}
}
return null;
}
/**
* Parses an object "correctly" by also passing the full context.
* Note that as of 1.1.7/1.1.8, parsing a license string may affect the state of your ModelStore.
*
* @param licenseString the licenseString to be parsed
* @param spdxDocument context required to get a good parse
*
* @return Returns the parsed object.
*
* @throws InvalidLicenseStringException throws whenever the spdx library decides to (undocumented as of year 2023).
*/
public static AnyLicenseInfo parseLicenseString(String licenseString, SpdxDocument spdxDocument)
throws InvalidLicenseStringException {
return LicenseInfoFactory.parseSPDXLicenseString(
licenseString,
spdxDocument.getModelStore(),
spdxDocument.getDocumentUri(),
spdxDocument.getCopyManager()
);
}
/**
* Creates an {@link ExtractedLicenseInfo} using the context's document.
*
* Once implemented: @see SpdxDocument#createExtractedLicense(String, String)
*
* @param licenseId is an id (name) of a licenseRef
* @param text is license text to set in the returned object
* @param comment the comment to insert
* @param spdxDocument needed for correctly creating the object
*
* @throws InvalidSPDXAnalysisException throws whenever the spdx library decides to (undocumented as of year 2023).
*/
public static void createExtractedLicenseInfo(String licenseId, String text, String comment, SpdxDocument spdxDocument)
throws InvalidSPDXAnalysisException {
ExtractedLicenseInfo extractedLicenseInfo = new ExtractedLicenseInfo(
spdxDocument.getModelStore(),
spdxDocument.getDocumentUri(),
licenseId,
spdxDocument.getCopyManager(),
true);
if (text != null) {
extractedLicenseInfo.setExtractedText(text);
} else {
extractedLicenseInfo.setExtractedText(SpdxConstants.NOASSERTION_VALUE);
extractedLicenseInfo.setComment(comment);
}
spdxDocument.addExtractedLicenseInfos(extractedLicenseInfo);
}
public static SpdxDocument generateFromFile(File spdxDocumentFile) {
try (IModelStore iModelStore = new InMemSpdxStore()) {
try (MultiFormatStore multiFormatStore = new MultiFormatStore(iModelStore, MultiFormatStore.Format.JSON_PRETTY)) {
try (FileInputStream inputStream = new FileInputStream(spdxDocumentFile)) {
multiFormatStore.deSerialize(inputStream, true);
return new SpdxDocument(multiFormatStore, multiFormatStore
.getDocumentUris().stream()
.findFirst()
.orElseThrow(RuntimeException::new),
new ModelCopyManager(), false);
}
}
} catch (Exception e) {
return null;
}
}
public static String getFilePathFromProjectLocations(String locations) {
String rootMarker = "[root]";
int startIndex = locations.indexOf(rootMarker) + rootMarker.length();
// FIXME: Improve location handling to include all possible path representations
if (!locations.contains(rootMarker)) {
return locations;
}
int endIndex = locations.indexOf(Artifact.PROJECT_DELIMITER_REGEXP, startIndex);
if (endIndex == -1) {
endIndex = locations.length();
return locations.substring(startIndex,endIndex).trim();
}
return "/";
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy