org.spdx.rdfparser.model.SpdxDocument Maven / Gradle / Ivy
/**
* Copyright (c) 2015 Source Auditor Inc.
*
* 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 org.spdx.rdfparser.model;
import java.util.Calendar;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.spdx.rdfparser.IModelContainer;
import org.spdx.rdfparser.InvalidSPDXAnalysisException;
import org.spdx.rdfparser.RdfModelHelper;
import org.spdx.rdfparser.SPDXCreatorInformation;
import org.spdx.rdfparser.SPDXReview;
import org.spdx.rdfparser.SpdxDocumentContainer;
import org.spdx.rdfparser.SpdxRdfConstants;
import org.spdx.rdfparser.license.AnyLicenseInfo;
import org.spdx.rdfparser.license.ExtractedLicenseInfo;
import org.spdx.rdfparser.license.ListedLicenses;
import org.spdx.rdfparser.license.SpdxListedLicense;
import com.google.common.base.Objects;
import org.apache.jena.graph.Node;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.Resource;
/**
* An SpdxDocument is a summary of the contents, provenance, ownership and licensing
* analysis of a specific software package.
* This is, effectively, the top level of SPDX information.
*
* Documents always have a model
*
* @author Gary O'Neall
*
*/
public class SpdxDocument extends SpdxElement {
private SpdxDocumentContainer documentContainer;
SPDXCreatorInformation creationInfo; //TODO Refactor to RdfModelObject
AnyLicenseInfo dataLicense;
String specVersion;
@Deprecated // Replaced by annotations
SPDXReview[] reviewers;
/**
* @param documentContainer
* @param node
* @throws InvalidSPDXAnalysisException
*/
public SpdxDocument(SpdxDocumentContainer documentContainer, Node node)
throws InvalidSPDXAnalysisException {
super(documentContainer, node);
this.documentContainer = documentContainer;
getMyPropertiesFromModel();
if (this.getCreationInfo() == null){
String licenseListVersion = ListedLicenses.getListedLicenses().getLicenseListVersion();
String creationDate = DateFormatUtils.format(Calendar.getInstance(), SpdxRdfConstants.SPDX_DATE_FORMAT);
SPDXCreatorInformation creationInfo = new SPDXCreatorInformation(new String[] { }, creationDate, null, licenseListVersion);
setCreationInfo(creationInfo);
}
else if (StringUtils.isBlank(this.getCreationInfo().getLicenseListVersion())){
this.getCreationInfo().setLicenseListVersion(ListedLicenses.getListedLicenses().getLicenseListVersion());
}
}
/* (non-Javadoc)
* @see org.spdx.rdfparser.model.RdfModelObject#getPropertiesFromModel()
*/
@Override
public void getPropertiesFromModel() throws InvalidSPDXAnalysisException {
super.getPropertiesFromModel();
getMyPropertiesFromModel();
}
void getMyPropertiesFromModel() throws InvalidSPDXAnalysisException {
dataLicense = findAnyLicenseInfoPropertyValue(SpdxRdfConstants.SPDX_NAMESPACE,
SpdxRdfConstants.PROP_SPDX_DATA_LICENSE);
creationInfo = findCreationInfoPropertyValue(SpdxRdfConstants.SPDX_NAMESPACE,
SpdxRdfConstants.PROP_SPDX_CREATION_INFO);
specVersion = findSinglePropertyValue(SpdxRdfConstants.SPDX_NAMESPACE,
SpdxRdfConstants.PROP_SPDX_VERSION);
reviewers = findReviewPropertyValues(SpdxRdfConstants.SPDX_NAMESPACE,
SpdxRdfConstants.PROP_SPDX_REVIEWED_BY);
}
/**
* @return all SPDX items connected directly to this document. Does not include
* children SPDX items (e.g. files within packages).
* @throws InvalidSPDXAnalysisException
*/
public SpdxItem[] getDocumentDescribes() throws InvalidSPDXAnalysisException {
Relationship[] allRelationships = this.getRelationships();
int count = 0;
for (int i = 0; i < allRelationships.length; i++) {
if (allRelationships[i].getRelationshipType() == Relationship.RelationshipType.DESCRIBES &&
allRelationships[i].getRelatedSpdxElement() instanceof SpdxItem) {
count++;
}
}
SpdxItem[] refresh = new SpdxItem[count];
int refreshIndex = 0;
for (int i = 0; i < allRelationships.length; i++) {
if (allRelationships[i].getRelationshipType() == Relationship.RelationshipType.DESCRIBES &&
allRelationships[i].getRelatedSpdxElement() instanceof SpdxItem) {
refresh[refreshIndex++] = (SpdxItem)allRelationships[i].getRelatedSpdxElement();
}
}
return refresh;
}
SpdxItem[] getPackagesFromItems(SpdxItem[] items) {
int count = 0;
for (int i = 0; i < items.length; i++) {
if (items[i] instanceof SpdxPackage) {
count++;
}
}
SpdxItem[] retval = new SpdxItem[count];
count = 0;
for (int i = 0; i < items.length; i++) {
if (items[i] instanceof SpdxPackage) {
retval[count++] = items[i];
}
}
return retval;
}
SpdxItem[] getFilesFromItems(SpdxItem[] items) {
int count = 0;
for (int i = 0; i < items.length; i++) {
if (items[i] instanceof SpdxFile) {
count++;
}
}
SpdxItem[] retval = new SpdxItem[count];
count = 0;
for (int i = 0; i < items.length; i++) {
if (items[i] instanceof SpdxFile) {
retval[count++] = items[i];
}
}
return retval;
}
/* (non-Javadoc)
* @see org.spdx.rdfparser.model.RdfModelObject#getUri(org.spdx.rdfparser.IModelContainer)
*/
@Override
public String getUri(IModelContainer modelContainer) throws InvalidSPDXAnalysisException {
if (this.node != null && this.node.isURI()) {
return this.node.getURI();
} else {
// for the document, the URI is the same as the namespace
return modelContainer.getDocumentNamespace();
}
}
/**
* @return The unique Document Namespace
* @throws InvalidSPDXAnalysisException
*/
public String getDocumentUri() throws InvalidSPDXAnalysisException {
return this.getUri(documentContainer);
}
public String getDocumentNamespace() throws InvalidSPDXAnalysisException {
String[] parts = this.getDocumentUri().split("#");
return parts[0];
}
/* (non-Javadoc)
* @see org.spdx.rdfparser.model.RdfModelObject#getType(org.apache.jena.rdf.model.Model)
*/
@Override
public Resource getType(Model model) {
return model.createResource(SpdxRdfConstants.SPDX_NAMESPACE + SpdxRdfConstants.CLASS_SPDX_DOCUMENT);
}
@Override
public void populateModel() throws InvalidSPDXAnalysisException {
super.populateModel();
setPropertyValue(SpdxRdfConstants.SPDX_NAMESPACE,
SpdxRdfConstants.PROP_SPDX_DATA_LICENSE, this.dataLicense);
setPropertyValue(SpdxRdfConstants.SPDX_NAMESPACE,
SpdxRdfConstants.PROP_SPDX_CREATION_INFO, this.creationInfo);
setPropertyValues(SpdxRdfConstants.SPDX_NAMESPACE,
SpdxRdfConstants.PROP_SPDX_EXTRACTED_LICENSES, this.documentContainer.getExtractedLicenseInfos());
setPropertyValue(SpdxRdfConstants.SPDX_NAMESPACE,
SpdxRdfConstants.PROP_SPDX_VERSION, specVersion);
setPropertyValues(SpdxRdfConstants.SPDX_NAMESPACE,
SpdxRdfConstants.PROP_SPDX_REVIEWED_BY, reviewers);
}
/**
* @return the documentContainer
*/
public SpdxDocumentContainer getDocumentContainer() {
return documentContainer;
}
/**
* @return the creationInfo
* @throws InvalidSPDXAnalysisException
*/
public SPDXCreatorInformation getCreationInfo() throws InvalidSPDXAnalysisException {
if (this.resource != null && this.refreshOnGet) {
try {
//TODO Once CreationInfo has been refactored to an RdfModelObjet, check for equivalent
creationInfo = findCreationInfoPropertyValue(SpdxRdfConstants.SPDX_NAMESPACE,
SpdxRdfConstants.PROP_SPDX_CREATION_INFO);
} catch (InvalidSPDXAnalysisException e) {
logger.error("Error getting creationInfo from model");
throw(e);
}
}
return creationInfo;
}
/**
* @param creationInfo the creationInfo to set
*/
public void setCreationInfo(SPDXCreatorInformation creationInfo) {
this.creationInfo = creationInfo;
setPropertyValue(SpdxRdfConstants.SPDX_NAMESPACE,
SpdxRdfConstants.PROP_SPDX_CREATION_INFO, this.creationInfo);
}
/**
* @return the dataLicense
* @throws InvalidSPDXAnalysisException
*/
public AnyLicenseInfo getDataLicense() throws InvalidSPDXAnalysisException {
if (this.resource != null && this.refreshOnGet) {
try {
AnyLicenseInfo refresh = findAnyLicenseInfoPropertyValue(SpdxRdfConstants.SPDX_NAMESPACE,
SpdxRdfConstants.PROP_SPDX_DATA_LICENSE);
if (refresh == null || !refresh.equals(this.dataLicense)) {
this.dataLicense = refresh;
}
} catch (InvalidSPDXAnalysisException e) {
logger.error("Error getting data license from model");
throw(e);
}
}
return this.dataLicense;
}
/**
* @param dataLicense the dataLicense to set
* @throws InvalidSPDXAnalysisException
*/
public void setDataLicense(AnyLicenseInfo dataLicense) throws InvalidSPDXAnalysisException {
this.dataLicense = dataLicense;
setPropertyValue(SpdxRdfConstants.SPDX_NAMESPACE,
SpdxRdfConstants.PROP_SPDX_DATA_LICENSE, this.dataLicense);
}
/**
* @return the externalDocumentRefs
* @throws InvalidSPDXAnalysisException
*/
public ExternalDocumentRef[] getExternalDocumentRefs() throws InvalidSPDXAnalysisException {
return this.documentContainer.getExternalDocumentRefs();
}
/**
* @param externalDocumentRefs the externalDocumentRefs to set
* @throws InvalidSPDXAnalysisException
*/
public void setExternalDocumentRefs(ExternalDocumentRef[] externalDocumentRefs) throws InvalidSPDXAnalysisException {
this.documentContainer.setExternalDocumentRefs(externalDocumentRefs);
}
/**
* @return the extractedLicenseInfos
* @throws InvalidSPDXAnalysisException
*/
public ExtractedLicenseInfo[] getExtractedLicenseInfos() throws InvalidSPDXAnalysisException {
return this.documentContainer.getExtractedLicenseInfos();
}
/**
* @param extractedLicenseInfos the extractedLicenseInfos to set
* @throws InvalidSPDXAnalysisException
*/
public void setExtractedLicenseInfos(
ExtractedLicenseInfo[] extractedLicenseInfos) throws InvalidSPDXAnalysisException {
this.documentContainer.setExtractedLicenseInfos(extractedLicenseInfos);
}
/**
* @return the specVersion
*/
public String getSpecVersion() {
if (this.resource != null && this.refreshOnGet) {
specVersion = findSinglePropertyValue(SpdxRdfConstants.SPDX_NAMESPACE,
SpdxRdfConstants.PROP_SPDX_VERSION);
}
return specVersion;
}
/**
* @return the reviewers
* @throws InvalidSPDXAnalysisException
*/
@Deprecated
public SPDXReview[] getReviewers() throws InvalidSPDXAnalysisException {
if (this.resource != null && this.refreshOnGet) {
try {
// Note - this will always create new objects which may be considered a bug
// No intention to fix since the reviewers are deprecated as of 2.0
reviewers = findReviewPropertyValues(SpdxRdfConstants.SPDX_NAMESPACE,
SpdxRdfConstants.PROP_SPDX_REVIEWED_BY);
} catch (InvalidSPDXAnalysisException e) {
logger.error("Error getting reviews from model");
throw(e);
}
}
return reviewers;
}
/**
* @param reviewers the reviewers to set
*/
@Deprecated
public void setReviewers(SPDXReview[] reviewers) {
this.reviewers = reviewers;
setPropertyValues(SpdxRdfConstants.SPDX_NAMESPACE,
SpdxRdfConstants.PROP_SPDX_REVIEWED_BY, reviewers);
}
/**
* @param specVersion the specVersion to set
*/
public void setSpecVersion(String specVersion) {
this.specVersion = specVersion;
setPropertyValue(SpdxRdfConstants.SPDX_NAMESPACE,
SpdxRdfConstants.PROP_SPDX_VERSION, specVersion);
}
/* (non-Javadoc)
* @see org.spdx.rdfparser.model.IRdfModel#verify()
*/
@Override
public List verify() {
List retval = super.verify();
// specVersion
String docSpecVersion = ""; // note - this is used later in verify to verify version specific info
if (this.specVersion == null || this.specVersion.isEmpty()) {
retval.add("Missing required SPDX version");
docSpecVersion = "UNKNOWN";
} else {
docSpecVersion = this.specVersion;
String verify = this.documentContainer.verifySpdxVersion(docSpecVersion);
if (verify != null) {
retval.add(verify);
}
}
// creationInfo
try {
SPDXCreatorInformation creator = this.getCreationInfo();
if (creator == null) {
retval.add("Missing required Creator");
} else {
List creatorVerification = creator.verify();
retval.addAll(creatorVerification);
}
} catch (InvalidSPDXAnalysisException e) {
retval.add("Invalid creator information: "+e.getMessage());
}
// Reviewers
try {
SPDXReview[] reviews = this.getReviewers();
if (reviews != null) {
for (int i = 0; i < reviews.length; i++) {
List reviewerVerification = reviews[i].verify();
retval.addAll(reviewerVerification);
}
}
} catch (InvalidSPDXAnalysisException e) {
retval.add("Invalid reviewers: "+e.getMessage());
}
// Extracted licensine infos
try {
ExtractedLicenseInfo[] extractedLicInfos = this.getExtractedLicenseInfos();
if (extractedLicInfos != null) {
for (int i = 0; i < extractedLicInfos.length; i++) {
List extractedLicInfoVerification = extractedLicInfos[i].verify();
retval.addAll(extractedLicInfoVerification);
}
}
} catch (InvalidSPDXAnalysisException e) {
retval.add("Invalid extracted licensing info: "+e.getMessage());
}
// data license
if (!docSpecVersion.equals(SpdxDocumentContainer.POINT_EIGHT_SPDX_VERSION) &&
!docSpecVersion.equals(SpdxDocumentContainer.POINT_NINE_SPDX_VERSION)) { // added as a mandatory field in 1.0
try {
AnyLicenseInfo dataLicense = this.getDataLicense();
if (dataLicense == null) {
retval.add("Missing required data license");
} else {
if (!(dataLicense instanceof SpdxListedLicense)) {
retval.add("Invalid license type for data license - must be an SPDX Listed license");
} else {
if (docSpecVersion.equals(SpdxDocumentContainer.ONE_DOT_ZERO_SPDX_VERSION))
{
if (!((SpdxListedLicense)dataLicense).getLicenseId().equals(
SpdxDocumentContainer.SPDX_DATA_LICENSE_ID_VERSION_1_0)) {
retval.add("Incorrect data license for SPDX version 1.0 document - found "+
((SpdxListedLicense)dataLicense).getLicenseId()+", expected "+
SpdxDocumentContainer.SPDX_DATA_LICENSE_ID_VERSION_1_0);
}
} else {
if (!((SpdxListedLicense)dataLicense).getLicenseId().equals(
SpdxDocumentContainer.SPDX_DATA_LICENSE_ID)) {
retval.add("Incorrect data license for SPDX document - found "+
((SpdxListedLicense)dataLicense).getLicenseId()+
", expected "+SpdxDocumentContainer.SPDX_DATA_LICENSE_ID);
}
}
}
}
} catch (InvalidSPDXAnalysisException e) {
retval.add("Invalid data license: "+e.getMessage());
}
}
// External document references
try {
ExternalDocumentRef[] externalRefs = this.getExternalDocumentRefs();
for (int i = 0; i < externalRefs.length; i++) {
retval.addAll(externalRefs[i].verify());
}
} catch (InvalidSPDXAnalysisException e) {
retval.add("Invalid external document references: "+e.getMessage());
}
// documentDescribes relationships
try {
SpdxItem[] items = getDocumentDescribes();
if (items.length == 0) {
retval.add("Document must have at least one relationship of type DOCUMENT_DESCRIBES");
}
} catch (InvalidSPDXAnalysisException e) {
retval.add("Invalid document items: "+e.getMessage());
}
try {
List allElements = documentContainer.findAllElements();
for (SpdxElement element:allElements) {
if (!element.getId().equals(this.getId())) {
retval.addAll(element.verify());
}
}
} catch (InvalidSPDXAnalysisException e) {
retval.add("Invalid elements: "+e.getMessage());
}
return retval;
}
@Override
public boolean equivalent(IRdfModel o) {
return this.equivalent(o, true);
}
@Override
public boolean equivalent(IRdfModel o, boolean testRelationships) {
if (o == this) {
return true;
}
if (!(o instanceof SpdxDocument)) {
return false;
}
if (!(super.equivalent(o, testRelationships))) {
return false;
}
SpdxDocument comp = (SpdxDocument)o;
try {
return (Objects.equal(this.creationInfo, comp.getCreationInfo()) &&
Objects.equal(this.dataLicense, comp.getDataLicense()) &&
arraysEquivalent(this.getExternalDocumentRefs(), comp.getExternalDocumentRefs(), testRelationships) &&
RdfModelHelper.arraysEqual(this.getExtractedLicenseInfos(), comp.getExtractedLicenseInfos()) &&
RdfModelHelper.arraysEqual(this.reviewers, comp.getReviewers()) && Objects.equal(this.specVersion, comp.getSpecVersion()));
} catch (InvalidSPDXAnalysisException ex) {
logger.error("Error testing for equivalent",ex);
return false;
}
}
@Override
protected String getNamePropertyName() {
return SpdxRdfConstants.PROP_NAME;
}
//NOTE: We can not implement clone since there is only one SPDX document per model
/**
* This method has been replaced by getSpecVersion to match the specification property name
* @return
*/
@Deprecated
public String getSpdxVersion() {
return this.getSpecVersion();
}
/**
* This method has been replaced by getCreationInfo to match the specification property name
* @return
* @throws InvalidSPDXAnalysisException
*/
@Deprecated
public SPDXCreatorInformation getCreatorInfo() throws InvalidSPDXAnalysisException {
return this.getCreationInfo();
}
/**
* This method has been replaced by getComment to match the specification property name
* @return
*/
@Deprecated
public String getDocumentComment() {
return this.getComment();
}
/**
* This method has been replaced by getSpdxItems
* This method will fail unless there is one and only 1 SPDX document
* @return
* @throws InvalidSPDXAnalysisException
*/
@Deprecated
public SpdxPackage getSpdxPackage() throws InvalidSPDXAnalysisException {
SpdxItem[] retval = this.getDocumentDescribes();
if (retval.length != 1) {
throw(new InvalidSPDXAnalysisException("More than one SPDX package defined in the document. Must use getSpdxItems - Likely this application has not been upgraded for SPDX 2.0"));
}
return (SpdxPackage)retval[0];
}
/**
* @param license license to be added to the extracted licensing infos
* @throws InvalidSPDXAnalysisException
*/
public void addExtractedLicenseInfos(
ExtractedLicenseInfo license) throws InvalidSPDXAnalysisException {
this.documentContainer.addExtractedLicenseInfos( license );
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy