Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make license expressions completely case insensitive #153

Merged
merged 3 commits into from
Apr 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion Test/org/spdx/rdfparser/license/TestLicenseInfoFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
import com.google.common.base.Charsets;
import com.google.common.io.Files;


import org.apache.jena.graph.Node;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
Expand Down Expand Up @@ -368,6 +367,23 @@ public void testParseSPDXLicenseString() throws InvalidLicenseStringException {
}
}

@Test
public void testParseSPDXLicenseStringMixedCase() throws InvalidLicenseStringException {
String parseString = COMPLEX_LICENSE.toString();
StringBuilder mixedCase = new StringBuilder();
for (int i = 0; i < parseString.length(); i++) {
if (i % 2 == 0) {
mixedCase.append(parseString.substring(i, i+1).toUpperCase());
} else {
mixedCase.append(parseString.substring(i, i+1).toLowerCase());
}
}
AnyLicenseInfo li = LicenseInfoFactory.parseSPDXLicenseString(mixedCase.toString());
if (!li.equals(COMPLEX_LICENSE)) {
fail("Parsed license does not equal");
}
}

@Test
public void testSpecialLicenses() throws InvalidLicenseStringException, InvalidSPDXAnalysisException {
// NONE
Expand Down
13 changes: 13 additions & 0 deletions resources/log4j2.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
10 changes: 5 additions & 5 deletions src/org/spdx/rdfparser/SpdxDocumentContainer.java
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public class SpdxDocumentContainer implements IModelContainer, SpdxRdfConstants
Set<String> spdxRefs = Sets.newHashSet();

/**
* Map of license ID to extracted license info
* Map of lower case license ID to extracted license info
*/
Map<String, ExtractedLicenseInfo> licenseIdToExtractedLicense = Maps.newHashMap();

Expand Down Expand Up @@ -530,7 +530,7 @@ public void addNewExtractedLicenseInfo(ExtractedLicenseInfo license) throws Inva
Property p = model.getProperty(SPDX_NAMESPACE, PROP_SPDX_EXTRACTED_LICENSES);
Resource s = getResource(getSpdxDocNode());
s.addProperty(p, license.createResource(this));
this.licenseIdToExtractedLicense.put(license.getLicenseId(), license);
this.licenseIdToExtractedLicense.put(license.getLicenseId().toLowerCase(), license);
}

/**
Expand All @@ -539,7 +539,7 @@ public void addNewExtractedLicenseInfo(ExtractedLicenseInfo license) throws Inva
* @throws InvalidSPDXAnalysisException
*/
public boolean extractedLicenseExists(String id) throws InvalidSPDXAnalysisException {
return this.licenseIdToExtractedLicense.containsKey(id);
return this.licenseIdToExtractedLicense.containsKey(id.toLowerCase());
}

/**
Expand All @@ -548,7 +548,7 @@ public boolean extractedLicenseExists(String id) throws InvalidSPDXAnalysisExcep
* @throws InvalidSPDXAnalysisException
*/
public ExtractedLicenseInfo getExtractedLicense(String id) throws InvalidSPDXAnalysisException {
return this.licenseIdToExtractedLicense.get(id);
return this.licenseIdToExtractedLicense.get(id.toLowerCase());
}

/**
Expand All @@ -567,7 +567,7 @@ public void getExtractedLicenseInfosFromModel() throws InvalidSPDXAnalysisExcept
throw new InvalidSPDXAnalysisException("Invalid type for extracted license infos: " + extractedAnyLicenseInfo[i]);
}
ExtractedLicenseInfo lic = (ExtractedLicenseInfo)extractedAnyLicenseInfo[i];
this.licenseIdToExtractedLicense.put(lic.getLicenseId(), lic);
this.licenseIdToExtractedLicense.put(lic.getLicenseId().toLowerCase(), lic);
}
}

Expand Down
13 changes: 5 additions & 8 deletions src/org/spdx/rdfparser/license/LicenseExpressionParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,6 @@ enum Operator {

static {
OPERATOR_MAP.put("+", Operator.OR_LATER);
OPERATOR_MAP.put("AND", Operator.AND);
OPERATOR_MAP.put("OR", Operator.OR);
OPERATOR_MAP.put("WITH", Operator.WITH);
OPERATOR_MAP.put("and", Operator.AND);
OPERATOR_MAP.put("or", Operator.OR);
OPERATOR_MAP.put("with", Operator.WITH);
Expand All @@ -68,9 +65,9 @@ static AnyLicenseInfo parseLicenseExpression(String expression, SpdxDocumentCont
throw(new LicenseParserException("Empty license expression"));
}
String[] tokens = tokenizeExpression(expression);
if (tokens.length == 1 && tokens[0].equals(SpdxRdfConstants.NOASSERTION_VALUE)) {
if (tokens.length == 1 && tokens[0].toLowerCase().equals(SpdxRdfConstants.NOASSERTION_VALUE.toLowerCase())) {
return new SpdxNoAssertionLicense();
} else if (tokens.length == 1 && tokens[0].equals(SpdxRdfConstants.NONE_VALUE)) {
} else if (tokens.length == 1 && tokens[0].toLowerCase().equals(SpdxRdfConstants.NONE_VALUE.toLowerCase())) {
return new SpdxNoneLicense();
} else {
try {
Expand Down Expand Up @@ -129,7 +126,7 @@ private static AnyLicenseInfo parseLicenseExpression(String[] tokens, SpdxDocume
throw(new LicenseParserException("Expected license expression"));
}
Stack<AnyLicenseInfo> operandStack = new Stack<AnyLicenseInfo>();
Stack<Operator> operatorStack = new Stack<Operator>();
Stack<Operator> operatorStack = new Stack<Operator>();
int tokenIndex = 0;
String token;
while (tokenIndex < tokens.length) {
Expand All @@ -143,10 +140,10 @@ private static AnyLicenseInfo parseLicenseExpression(String[] tokens, SpdxDocume
String[] nestedTokens = Arrays.copyOfRange(tokens, tokenIndex, rightParenIndex);
operandStack.push(parseLicenseExpression(nestedTokens, container));
tokenIndex = rightParenIndex + 1;
} else if (OPERATOR_MAP.get(token) == null) { // assumed to be a simple licensing type
} else if (OPERATOR_MAP.get(token.toLowerCase()) == null) { // assumed to be a simple licensing type
operandStack.push(parseSimpleLicenseToken(token, container));
} else {
Operator operator = OPERATOR_MAP.get(token);
Operator operator = OPERATOR_MAP.get(token.toLowerCase());
if (operator == Operator.WITH) {
// special processing here since With must be with an exception, not a licenseInfo
if (!operatorStack.isEmpty() && Operator.OR_LATER.equals(operatorStack.peek())) {
Expand Down
9 changes: 5 additions & 4 deletions src/org/spdx/rdfparser/license/LicenseJsonTOC.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@
*/
package org.spdx.rdfparser.license;

import java.util.Map;
import java.util.Set;

import com.google.common.collect.Sets;
import com.google.common.collect.Maps;

/**
* Table of Contents for the listed license list as represented as a JSON index file
Expand Down Expand Up @@ -106,13 +107,13 @@ public LicenseJson[] getLicenses() {
return licenses;
}

public Set<String> getLicenseIds() {
Set<String> retval = Sets.newHashSet();
public Map<String, String> getLicenseIds() {
Map<String, String> retval = Maps.newHashMap();
if (licenses == null) {
return retval;
}
for (LicenseJson license:licenses) {
retval.add(license.licenseId);
retval.put(license.licenseId.toLowerCase(), license.licenseId);
}
return retval;
}
Expand Down
21 changes: 11 additions & 10 deletions src/org/spdx/rdfparser/license/ListedLicenses.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import java.nio.charset.Charset;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

Expand All @@ -44,7 +43,6 @@
import org.spdx.rdfparser.model.IRdfModel;

import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.gson.Gson;

/**
Expand All @@ -65,7 +63,10 @@ public class ListedLicenses implements IModelContainer {

private Model listedLicenseModel = null;

Set<String> listdLicenseIds = null;
/**
* Map of lowercase listed license ID to proper cased listed license ID
*/
Map<String, String> listdLicenseIds = null;

Map<String, SpdxListedLicense> listedLicenseCache = null;
Map<IModelContainer, Map<Node, SpdxListedLicense>> listedLicenseNodeCache = Maps.newHashMap();
Expand Down Expand Up @@ -333,7 +334,7 @@ private void loadListedLicenseIDs() {
listedLicenseModificationLock.writeLock().lock();
try {
listedLicenseCache = Maps.newHashMap(); // clear the cache
listdLicenseIds = Sets.newHashSet(); //Clear the listed license IDs to avoid stale licenses.
listdLicenseIds = Maps.newHashMap(); //Clear the listed license IDs to avoid stale licenses.
//TODO: Can the keys of listedLicenseCache be used instead of this set?
//NOTE: This includes deprecated licenses - should this be changed to only return non-deprecated licenses?
InputStream tocStream = null;
Expand Down Expand Up @@ -386,7 +387,7 @@ private void loadListedLicenseIDs() {
logger.warn("Unable to close JSON TOC input stream");
}
}
}
}
} finally {
listedLicenseModificationLock.writeLock().unlock();
}
Expand All @@ -400,7 +401,7 @@ private void loadListedLicenseIDs() {
public boolean isSpdxListedLicenseID(String licenseID) {
try {
listedLicenseModificationLock.readLock().lock();
return listdLicenseIds.contains(licenseID);
return listdLicenseIds.containsKey(licenseID.toLowerCase());
} finally {
listedLicenseModificationLock.readLock().unlock();
}
Expand Down Expand Up @@ -446,7 +447,7 @@ private static Properties loadLicenseProperties() {
public String[] getSpdxListedLicenseIds() {
listedLicenseModificationLock.readLock().lock();
try {
return listdLicenseIds.toArray(new String[listdLicenseIds.size()]);
return listdLicenseIds.values().toArray(new String[listdLicenseIds.size()]);
} finally {
listedLicenseModificationLock.readLock().unlock();
}
Expand All @@ -466,7 +467,7 @@ public String getLicenseListVersion() {
* @throws InvalidSPDXAnalysisException
*/
public SpdxListedLicense getListedLicenseById(String licenseId)throws InvalidSPDXAnalysisException {
SpdxListedLicense retval = getLicenseFromUri(LISTED_LICENSE_URI_PREFIX + licenseId + JSONLD_URL_SUFFIX);
SpdxListedLicense retval = getLicenseFromUri(LISTED_LICENSE_URI_PREFIX + listdLicenseIds.get(licenseId.toLowerCase()) + JSONLD_URL_SUFFIX);
if (retval != null) {
retval = (SpdxListedLicense)retval.clone(); // We need to clone the license to remove the references to the model in the cache
}
Expand Down Expand Up @@ -536,15 +537,15 @@ public synchronized String getNextSpdxElementRef() {
*/
@Override
public boolean spdxElementRefExists(String elementRef) {
return(listdLicenseIds.contains(elementRef));
return(listdLicenseIds.values().contains(elementRef));
}

/* (non-Javadoc)
* @see org.spdx.rdfparser.IModelContainer#addSpdxElementRef(java.lang.String)
*/
@Override
public void addSpdxElementRef(String elementRef) {
listdLicenseIds.add(elementRef);
listdLicenseIds.put(elementRef.toLowerCase(),elementRef);
}

/* (non-Javadoc)
Expand Down