Skip to content

Commit

Permalink
Add an option to not copy license details in CopyManager (#140)
Browse files Browse the repository at this point in the history
* Add an option to copy to not copy listed license details

Signed-off-by: Gary O'Neall <gary@sourceauditor.com>

* Move CrossRef from simple license info to ListedLicense

Signed-off-by: Gary O'Neall <gary@sourceauditor.com>

* Change all LicenseException references to ListedLicenseException

Signed-off-by: Gary O'Neall <gary@sourceauditor.com>

* Fix unit test failures

Signed-off-by: Gary O'Neall <gary@sourceauditor.com>

Signed-off-by: Gary O'Neall <gary@sourceauditor.com>
  • Loading branch information
goneall committed Nov 28, 2022
1 parent 3f81382 commit cd1b91d
Show file tree
Hide file tree
Showing 12 changed files with 103 additions and 44 deletions.
67 changes: 54 additions & 13 deletions src/main/java/org/spdx/library/ModelCopyManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ public String putCopiedId(IModelStore fromStore, String fromDocumentUri, String
}
return idMap.put(fromId, toId);
}

/**
* Copy an item from one Model Object Store to another
* @param toStore Model Store to copy to
Expand All @@ -136,6 +136,24 @@ public String putCopiedId(IModelStore fromStore, String fromDocumentUri, String
* @throws InvalidSPDXAnalysisException
*/
public void copy(IModelStore toStore, String toDocumentUri, String toId, IModelStore fromStore, String fromDocumentUri, String fromId, String type) throws InvalidSPDXAnalysisException {
copy(toStore, toDocumentUri, toId, fromStore, fromDocumentUri, fromId, type, false);
}

/**
* Copy an item from one Model Object Store to another
* @param toStore Model Store to copy to
* @param toId Id to use in the copy
* @param toDocumentUri Target document URI
* @param fromStore Model Store containing the source item
* @param fromDocumentUri Document URI for the source item
* @param fromId ID source ID
* @param type Type to copy
* @param excludeLicenseDetails If true, don't copy over properties of the listed licenses
* @throws InvalidSPDXAnalysisException
*/
public void copy(IModelStore toStore, String toDocumentUri, String toId,
IModelStore fromStore, String fromDocumentUri, String fromId,
String type, boolean excludeLicenseDetails) throws InvalidSPDXAnalysisException {
Objects.requireNonNull(toStore, "ToStore can not be null");
Objects.requireNonNull(toDocumentUri, "To Document URI can not be null");
Objects.requireNonNull(fromStore, "FromStore can not be null");
Expand All @@ -150,12 +168,16 @@ public void copy(IModelStore toStore, String toDocumentUri, String toId, IModelS
toStore.create(toDocumentUri, toId, type);
}
putCopiedId(fromStore, fromDocumentUri, fromId, toStore, toDocumentUri, toId);
List<String> propertyNames = fromStore.getPropertyValueNames(fromDocumentUri, fromId);
for (String propName:propertyNames) {
if (fromStore.isCollectionProperty(fromDocumentUri, fromId, propName)) {
copyCollectionProperty(toStore, toDocumentUri, toId, fromStore, fromDocumentUri, fromId, propName);
} else {
copyIndividualProperty(toStore, toDocumentUri, toId, fromStore, fromDocumentUri, fromId, propName);
if (!(excludeLicenseDetails &&
(SpdxConstants.CLASS_SPDX_LISTED_LICENSE.equals(type) ||
SpdxConstants.CLASS_SPDX_LISTED_LICENSE_EXCEPTION.equals(type)))) {
List<String> propertyNames = fromStore.getPropertyValueNames(fromDocumentUri, fromId);
for (String propName:propertyNames) {
if (fromStore.isCollectionProperty(fromDocumentUri, fromId, propName)) {
copyCollectionProperty(toStore, toDocumentUri, toId, fromStore, fromDocumentUri, fromId, propName, excludeLicenseDetails);
} else {
copyIndividualProperty(toStore, toDocumentUri, toId, fromStore, fromDocumentUri, fromId, propName, excludeLicenseDetails);
}
}
}
}
Expand All @@ -169,10 +191,11 @@ public void copy(IModelStore toStore, String toDocumentUri, String toId, IModelS
* @param fromDocumentUri Document URI for the source item
* @param fromId ID source ID
* @param propName Name of the property
* @param excludeLicenseDetails If true, don't copy over properties of the listed licenses
* @throws InvalidSPDXAnalysisException
*/
private void copyIndividualProperty(IModelStore toStore, String toDocumentUri, String toId, IModelStore fromStore,
String fromDocumentUri, String fromId, String propName) throws InvalidSPDXAnalysisException {
String fromDocumentUri, String fromId, String propName, boolean excludeLicenseDetails) throws InvalidSPDXAnalysisException {
if (fromStore.isCollectionProperty(fromDocumentUri, fromId, propName)) {
throw new InvalidSPDXAnalysisException("Property "+propName+" is a collection type");
}
Expand All @@ -187,7 +210,7 @@ private void copyIndividualProperty(IModelStore toStore, String toDocumentUri, S
} else {
toStore.setValue(toDocumentUri, toId, propName,
copy(toStore, toDocumentUri, fromStore, fromDocumentUri,
tv.getId(), tv.getType()));
tv.getId(), tv.getType(), excludeLicenseDetails));
}
} else {
toStore.setValue(toDocumentUri, toId, propName, result.get());
Expand All @@ -204,10 +227,11 @@ private void copyIndividualProperty(IModelStore toStore, String toDocumentUri, S
* @param fromDocumentUri Document URI for the source item
* @param fromId ID source ID
* @param propName Name of the property
* @param excludeLicenseDetails If true, don't copy over properties of the listed licenses
* @throws InvalidSPDXAnalysisException
*/
private void copyCollectionProperty(IModelStore toStore, String toDocumentUri, String toId, IModelStore fromStore,
String fromDocumentUri, String fromId, String propName) throws InvalidSPDXAnalysisException {
String fromDocumentUri, String fromId, String propName, boolean excludeLicenseDetails) throws InvalidSPDXAnalysisException {
if (!fromStore.isCollectionProperty(fromDocumentUri, fromId, propName)) {
throw new InvalidSPDXAnalysisException("Property "+propName+" is not a collection type");
}
Expand All @@ -223,14 +247,30 @@ private void copyCollectionProperty(IModelStore toStore, String toDocumentUri, S
toStoreItem = listItemTv;
} else {
toStoreItem = copy(toStore, toDocumentUri, fromStore, fromDocumentUri,
listItemTv.getId(), listItemTv.getType());
listItemTv.getId(), listItemTv.getType(), excludeLicenseDetails);
}
} else {
toStoreItem = listItem;
}
toStore.addValueToCollection(toDocumentUri, toId, propName, toStoreItem);
}
}

/**
* Copy an item from one Model Object Store to another using the source ID for the target unless it is anonymous
* @param toStore Model Store to copy to
* @param toDocumentUri Target document URI
* @param fromStore Model Store containing the source item
* @param fromDocumentUri Document URI for the source item
* @param sourceId ID source ID
* @param type Type to copy
* @return ID for the copied object
* @throws InvalidSPDXAnalysisException
*/
public TypedValue copy(IModelStore toStore, String toDocumentUri, IModelStore fromStore,
String fromDocumentUri, String sourceId, String type) throws InvalidSPDXAnalysisException {
return copy(toStore, toDocumentUri, fromStore, fromDocumentUri, sourceId, type, false);
}

/**
* Copy an item from one Model Object Store to another using the source ID for the target unless it is anonymous
Expand All @@ -240,11 +280,12 @@ private void copyCollectionProperty(IModelStore toStore, String toDocumentUri, S
* @param fromDocumentUri Document URI for the source item
* @param sourceId ID source ID
* @param type Type to copy
* @param excludeLicenseDetails If true, don't copy over properties of the listed licenses
* @return ID for the copied object
* @throws InvalidSPDXAnalysisException
*/
public TypedValue copy(IModelStore toStore, String toDocumentUri, IModelStore fromStore,
String fromDocumentUri, String sourceId, String type) throws InvalidSPDXAnalysisException {
String fromDocumentUri, String sourceId, String type, boolean excludeLicenseDetails) throws InvalidSPDXAnalysisException {
Objects.requireNonNull(toStore, "To Store can not be null");
Objects.requireNonNull(toDocumentUri, "To Document URI can not be null");
Objects.requireNonNull(fromStore, "From Store can not be null");
Expand All @@ -271,7 +312,7 @@ public TypedValue copy(IModelStore toStore, String toDocumentUri, IModelStore fr
} else {
toId = sourceId;
}
copy(toStore, toDocumentUri, toId, fromStore, fromDocumentUri, sourceId, type);
copy(toStore, toDocumentUri, toId, fromStore, fromDocumentUri, sourceId, type, excludeLicenseDetails);
}
return new TypedValue(toId, type);
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/spdx/library/SpdxConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ public class SpdxConstants {
CLASS_POINTER_COMPOUNT_POINTER, CLASS_POINTER_LINE_CHAR_POINTER, CLASS_SINGLE_POINTER};

// classes that use the listed license URI for their namespace
public static final String[] LISTED_LICENSE_URI_CLASSES = {CLASS_SPDX_LISTED_LICENSE, CLASS_SPDX_LICENSE_EXCEPTION};
public static final String[] LISTED_LICENSE_URI_CLASSES = {CLASS_SPDX_LISTED_LICENSE, CLASS_SPDX_LISTED_LICENSE_EXCEPTION};

// Enumeration class names
public static final String ENUM_FILE_TYPE = "FileType";
Expand Down
1 change: 1 addition & 0 deletions src/main/java/org/spdx/library/model/SpdxModelFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ public class SpdxModelFactory {
typeToClass.put(SpdxConstants.CLASS_SPDX_LICENSE, License.class);
typeToClass.put(SpdxConstants.CLASS_SPDX_LISTED_LICENSE, SpdxListedLicense.class);
typeToClass.put(SpdxConstants.CLASS_SPDX_LICENSE_EXCEPTION, LicenseException.class);
typeToClass.put(SpdxConstants.CLASS_SPDX_LISTED_LICENSE_EXCEPTION, ListedLicenseException.class);
typeToClass.put(SpdxConstants.CLASS_OR_LATER_OPERATOR, OrLaterOperator.class);
typeToClass.put(SpdxConstants.CLASS_WITH_EXCEPTION_OPERATOR, WithExceptionOperator.class);
typeToClass.put(SpdxConstants.CLASS_SPDX_FILE, SpdxFile.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ enum Operator {
OPERATOR_MAP.put("with", Operator.WITH);
}
/**
* Parses a license expression into an license for use in the RDF Parser
* Parses a license expression into an license for use in the Model
* @param expression Expression to be parsed
* @param store Store containing any extractedLicenseInfos - if any extractedLicenseInfos by ID already exist, they will be used. If
* none exist for an ID, they will be added. If null, the default model store will be used.
Expand Down Expand Up @@ -187,8 +187,8 @@ private static AnyLicenseInfo parseLicenseExpression(String[] tokens, IModelStor
} else if (token.startsWith(SpdxConstants.NON_STD_LICENSE_ID_PRENUM)) {
throw new LicenseParserException("WITH must be followed by a license exception. "+token+" is a Listed License type.");
} else {
licenseException = (LicenseException) SpdxModelFactory.createModelObject(store,
documentUri, token, SpdxConstants.CLASS_SPDX_LICENSE_EXCEPTION, copyManager);
licenseException = (ListedLicenseException) SpdxModelFactory.createModelObject(store,
documentUri, token, SpdxConstants.CLASS_SPDX_LISTED_LICENSE_EXCEPTION, copyManager);
}
AnyLicenseInfo operand = operandStack.pop();
if (operand == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ public static boolean isSpdxListedExceptionId(String id) {
* @return the standard SPDX license exception or null if the ID is not in the SPDX license list
* @throws InvalidSPDXAnalysisException
*/
public static LicenseException getListedExceptionById(String id) throws InvalidSPDXAnalysisException {
public static ListedLicenseException getListedExceptionById(String id) throws InvalidSPDXAnalysisException {
return ListedLicenses.getListedLicenses().getListedExceptionById(id);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ public ListedLicenseException(String id, String name, String text) throws Invali
super(id, name, text);
}

@Override
public String getType() {
return SpdxConstants.CLASS_SPDX_LISTED_LICENSE_EXCEPTION;
}

/**
* @param exceptionTextHtml
* @throws InvalidSPDXAnalysisException
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,13 @@
*/
public abstract class SimpleLicensingInfo extends AnyLicenseInfo {

Collection<CrossRef> crossRef;
/**
* Open or create a model object with the default store and default document URI
* @param id ID for this object - must be unique within the SPDX document
* @throws InvalidSPDXAnalysisException
*/
@SuppressWarnings("unchecked")
SimpleLicensingInfo(String id) throws InvalidSPDXAnalysisException {
super(id);
crossRef = (Collection<CrossRef>)(Collection<?>)this.getObjectPropertyValueSet(SpdxConstants.PROP_CROSS_REF, CrossRef.class);
if (!(this instanceof IndividualUriValue)) {
setPropertyValue(SpdxConstants.PROP_LICENSE_ID, id); // Needs to be set as a property per spec
}
Expand All @@ -64,12 +61,10 @@ public abstract class SimpleLicensingInfo extends AnyLicenseInfo {
* @param create if true, create the license if it does not exist
* @throws InvalidSPDXAnalysisException
*/
@SuppressWarnings("unchecked")
SimpleLicensingInfo(IModelStore modelStore, String documentUri, String id,
@Nullable ModelCopyManager copyManager, boolean create)
throws InvalidSPDXAnalysisException {
super(modelStore, documentUri, id, copyManager, create);
crossRef = (Collection<CrossRef>)(Collection<?>)this.getObjectPropertyValueSet(SpdxConstants.PROP_CROSS_REF, CrossRef.class);
if (!(this instanceof IndividualUriValue)) {
setPropertyValue(SpdxConstants.PROP_LICENSE_ID, id); // Needs to be set as a property per spec
}
Expand Down Expand Up @@ -142,8 +137,4 @@ public void setSeeAlso(Collection<String> seeAlsoUrl) throws InvalidSPDXAnalysis
setPropertyValue(SpdxConstants.RDFS_PROP_SEE_ALSO, seeAlsoUrl);
}
}

public Collection<CrossRef> getCrossRef() throws InvalidSPDXAnalysisException {
return this.crossRef;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package org.spdx.library.model.license;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
Expand All @@ -40,13 +41,17 @@
*/
public class SpdxListedLicense extends License {

Collection<CrossRef> crossRef;

/**
* Open or create a model object with the default store and default document URI
* @param id ID for this object - must be unique within the SPDX document
* @throws InvalidSPDXAnalysisException
*/
@SuppressWarnings("unchecked")
public SpdxListedLicense(String id) throws InvalidSPDXAnalysisException {
super(id);
crossRef = (Collection<CrossRef>)(Collection<?>)this.getObjectPropertyValueSet(SpdxConstants.PROP_CROSS_REF, CrossRef.class);
}

/**
Expand All @@ -58,10 +63,12 @@ public SpdxListedLicense(String id) throws InvalidSPDXAnalysisException {
* @param create if true, create the license if it does not exist
* @throws InvalidSPDXAnalysisException
*/
@SuppressWarnings("unchecked")
public SpdxListedLicense(IModelStore modelStore, String documentUri, String id,
@Nullable ModelCopyManager copyManager, boolean create)
throws InvalidSPDXAnalysisException {
super(modelStore, documentUri, id, copyManager, create);
crossRef = (Collection<CrossRef>)(Collection<?>)this.getObjectPropertyValueSet(SpdxConstants.PROP_CROSS_REF, CrossRef.class);
}

/**
Expand All @@ -79,6 +86,7 @@ public SpdxListedLicense(IModelStore modelStore, String documentUri, String id,
* @param deprecatedVersion License list version when this license was first deprecated (null if not deprecated)
* @throws InvalidSPDXAnalysisException
*/
@SuppressWarnings("unchecked")
public SpdxListedLicense(String name, String id, String text, Collection<String> sourceUrl, String comments,
String standardLicenseHeader, String template, boolean osiApproved, Boolean fsfLibre,
String licenseTextHtml, boolean isDeprecated, String deprecatedVersion) throws InvalidSPDXAnalysisException {
Expand All @@ -94,6 +102,7 @@ public SpdxListedLicense(String name, String id, String text, Collection<String>
setLicenseTextHtml(licenseTextHtml);
setDeprecated(isDeprecated);
setDeprecatedVersion(deprecatedVersion);
crossRef = (Collection<CrossRef>)(Collection<?>)this.getObjectPropertyValueSet(SpdxConstants.PROP_CROSS_REF, CrossRef.class);
}

/**
Expand All @@ -104,6 +113,7 @@ public SpdxListedLicense(SpdxListedLicense.Builder builder) throws InvalidSPDXAn
this(builder.name, builder.id, builder.text, builder.sourceUrl, builder.comments, builder.standardLicenseHeader,
builder.template, builder.osiApproved, builder.fsfLibre, builder.licenseTextHtml, builder.isDeprecated,
builder.deprecatedVersion);
this.crossRef.addAll(builder.crossRefs);
}

@Override
Expand Down Expand Up @@ -206,6 +216,10 @@ public void setDeprecatedVersion(String deprecatedVersion) throws InvalidSPDXAna
setPropertyValue(SpdxConstants.PROP_LIC_DEPRECATED_VERSION, deprecatedVersion);
}

public Collection<CrossRef> getCrossRef() throws InvalidSPDXAnalysisException {
return this.crossRef;
}

@Override
public String getType() {
return SpdxConstants.CLASS_SPDX_LISTED_LICENSE;
Expand Down Expand Up @@ -251,6 +265,7 @@ public static class Builder {
private String licenseTextHtml;
private boolean isDeprecated;
private String deprecatedVersion;
private List<CrossRef> crossRefs = new ArrayList<CrossRef>();

/**
* @param name License name
Expand Down Expand Up @@ -344,6 +359,10 @@ public Builder setDeprecatedVersion(String deprecatedVersion) {
this.deprecatedVersion = deprecatedVersion;
return this;
}

public Builder addCrossRefs(CrossRef crossRef) {
; this.crossRefs.add(crossRef);
return this;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ public void create(String documentUri, String id, String type) throws InvalidSPD
}
this.licenseIds.put(id.toLowerCase(), id);
this.listedLicenseCache.put(id, new LicenseJson(id));
} else if (SpdxConstants.CLASS_SPDX_LICENSE_EXCEPTION.equals(type)) {
} else if (SpdxConstants.CLASS_SPDX_LISTED_LICENSE_EXCEPTION.equals(type)) {
if (this.licenseIds.containsKey(id.toLowerCase()) || this.exceptionIds.containsKey(id.toLowerCase())) {
logger.error("Duplicate SPDX ID on create: "+id);;
throw new DuplicateSpdxIdException("ID "+id+" already exists.");
Expand Down Expand Up @@ -838,7 +838,7 @@ public Optional<TypedValue> getTypedValue(String documentUri, String id) throws
if (licenseIds.containsKey(id.toLowerCase())) {
return Optional.of(new TypedValue(id, SpdxConstants.CLASS_SPDX_LISTED_LICENSE));
} else if (exceptionIds.containsKey(id.toLowerCase())) {
return Optional.of(new TypedValue(id, SpdxConstants.CLASS_SPDX_LICENSE_EXCEPTION));
return Optional.of(new TypedValue(id, SpdxConstants.CLASS_SPDX_LISTED_LICENSE_EXCEPTION));
} else if (crossRefs.containsKey(id)) {
return Optional.of(new TypedValue(id, SpdxConstants.CLASS_CROSS_REF));
} else {
Expand Down Expand Up @@ -903,9 +903,9 @@ public Stream<TypedValue> getAllItems(String documentUri, @Nullable String typeF
allItems.add(new TypedValue(licenseId, SpdxConstants.CLASS_SPDX_LISTED_LICENSE));
}
}
if (Objects.isNull(typeFilter) || SpdxConstants.CLASS_SPDX_LICENSE_EXCEPTION.equals(typeFilter)) {
if (Objects.isNull(typeFilter) || SpdxConstants.CLASS_SPDX_LISTED_LICENSE_EXCEPTION.equals(typeFilter)) {
for (String exceptionId:this.exceptionIds.values()) {
allItems.add(new TypedValue(exceptionId, SpdxConstants.CLASS_SPDX_LICENSE_EXCEPTION));
allItems.add(new TypedValue(exceptionId, SpdxConstants.CLASS_SPDX_LISTED_LICENSE_EXCEPTION));
}
}
if (Objects.isNull(typeFilter) || SpdxConstants.CLASS_CROSS_REF.equals(typeFilter)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ protected void setUp() throws Exception {
STD_IDS[i], STD_TEXTS[i], new ArrayList<String>(Arrays.asList(new String[] {"URL "+String.valueOf(i)})), "Notes "+String.valueOf(i),
"LicHeader "+String.valueOf(i), "Template "+String.valueOf(i), true, false, "", false, "");
}
LICENSE_EXCEPTIONS = new LicenseException[EXCEPTION_IDS.length];
LICENSE_EXCEPTIONS = new ListedLicenseException[EXCEPTION_IDS.length];
for (int i = 0; i < EXCEPTION_IDS.length; i++) {
LICENSE_EXCEPTIONS[i] = new LicenseException(EXCEPTION_IDS[i], EXCEPTION_NAMES[i], EXCEPTION_TEXTS[i]);
LICENSE_EXCEPTIONS[i] = new ListedLicenseException(EXCEPTION_IDS[i], EXCEPTION_NAMES[i], EXCEPTION_TEXTS[i]);
}

SpdxDocument doc = new SpdxDocument(modelStore, TEST_DOCUMENT_URI, null, true);
Expand Down
Loading

0 comments on commit cd1b91d

Please sign in to comment.