Skip to content

Commit ada73d2

Browse files
committed
Add InvalidLicenseExpression class
Supports improvements to the license parsing error handling. See spdx/Spdx-Java-Library#339 for reference.
1 parent 1745c1d commit ada73d2

File tree

3 files changed

+207
-1
lines changed

3 files changed

+207
-1
lines changed

src/main/java/org/spdx/library/model/v2/SpdxModelFactoryCompatV2.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.spdx.core.SpdxIdNotFoundException;
2323
import org.spdx.core.TypedValue;
2424
import org.spdx.library.model.v2.license.AnyLicenseInfo;
25+
import org.spdx.library.model.v2.license.InvalidLicenseExpression;
2526
import org.spdx.library.model.v2.license.SpdxListedLicense;
2627
import org.spdx.storage.IModelStore;
2728
import org.spdx.storage.IModelStore.IdType;
@@ -104,6 +105,7 @@ public class SpdxModelFactoryCompatV2 {
104105
typeToClassV2.put(SpdxConstantsCompatV2.ENUM_REFERENCE_RELATIONSHIP_TYPE, org.spdx.library.model.v2.enumerations.RelationshipType.class);
105106
typeToClassV2.put(SpdxConstantsCompatV2.CLASS_EXTERNAL_EXTRACTED_LICENSE, org.spdx.library.model.v2.license.ExternalExtractedLicenseInfo.class);
106107
typeToClassV2.put(SpdxConstantsCompatV2.ENUM_PURPOSE, org.spdx.library.model.v2.enumerations.Purpose.class);
108+
typeToClassV2.put(InvalidLicenseExpression.INVALID_LICENSE_EXPRESSION_TYPE, org.spdx.library.model.v2.license.InvalidLicenseExpression.class);
107109
SPDX_TYPE_TO_CLASS_V2 = Collections.unmodifiableMap(typeToClassV2);
108110
Map<Class<?>, String> classToType = new HashMap<>();
109111
for (Entry<String, Class<?>> entry:typeToClassV2.entrySet()) {
@@ -299,5 +301,4 @@ public static Class<?> classUriToClass(String classUri) throws InvalidSPDXAnalys
299301
String type = classUri.substring(indexOfPound+1);
300302
return typeToClass(type);
301303
}
302-
303304
}
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/*
2+
* SPDX-FileCopyrightText: Copyright (c) 2025 Source Auditor Inc.
3+
* SPDX-FileType: SOURCE
4+
* SPDX-License-Identifier: Apache-2.0
5+
* <p>
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
* <p>
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
* <p>
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
package org.spdx.library.model.v2.license;
20+
21+
import org.spdx.core.IModelCopyManager;
22+
import org.spdx.core.InvalidSPDXAnalysisException;
23+
import org.spdx.storage.IModelStore;
24+
import org.spdx.storage.PropertyDescriptor;
25+
26+
import javax.annotation.Nullable;
27+
import java.util.ArrayList;
28+
import java.util.List;
29+
import java.util.Optional;
30+
import java.util.Set;
31+
32+
import static org.spdx.library.model.v2.SpdxConstantsCompatV2.SPDX_NAMESPACE;
33+
34+
/**
35+
* Represents a license expression string which can not be parsed - used for error handling
36+
*/
37+
public class InvalidLicenseExpression extends AnyLicenseInfo {
38+
39+
public static final PropertyDescriptor MESSAGE_PROPERTY = new PropertyDescriptor("invalidLicenseMessage", SPDX_NAMESPACE);
40+
public static final PropertyDescriptor LICENSE_EXPRESSION_PROPERTY = new PropertyDescriptor("invalidLicenseExpression", SPDX_NAMESPACE);
41+
public static final String INVALID_LICENSE_EXPRESSION_TYPE = "InvalidLicenseExpression";
42+
/**
43+
* Create a new InvalidLicenseExpression object
44+
* @param modelStore container which includes the license
45+
* @param documentUri URI for the SPDX document containing the license
46+
* @param id identifier for the license
47+
* @param copyManager if non-null, allows for copying of any properties set which use other model stores or document URI's
48+
* @param create if true, create the license if it does not exist
49+
* @throws InvalidSPDXAnalysisException on error
50+
*/
51+
public InvalidLicenseExpression(IModelStore modelStore, String documentUri, String id,
52+
@Nullable IModelCopyManager copyManager, boolean create)
53+
throws InvalidSPDXAnalysisException {
54+
super(modelStore, documentUri, id, copyManager, create);
55+
}
56+
57+
/**
58+
* Create a new InvalidLicenseExpression object and initializes the message and licenseExpression
59+
* @param modelStore container which includes the license
60+
* @param documentUri URI for the SPDX document containing the license
61+
* @param id identifier for the license
62+
* @param copyManager if non-null, allows for copying of any properties set which use other model stores or document URI's
63+
* @param message Error message describing the nature of the invalid license expression
64+
* @param licenseExpression License expression string that caused the error
65+
* @throws InvalidSPDXAnalysisException on error
66+
*/
67+
public InvalidLicenseExpression(IModelStore modelStore, String documentUri, String id,
68+
@Nullable IModelCopyManager copyManager, String message,
69+
String licenseExpression) throws InvalidSPDXAnalysisException {
70+
super(modelStore, documentUri, id, copyManager, true);
71+
setMessage(message);
72+
setLicenseExpression(licenseExpression);
73+
}
74+
75+
@Override
76+
protected List<String> _verify(Set<String> verifiedElementIds, String specVersion) {
77+
List<String> retval = new ArrayList<>();
78+
try {
79+
retval.add(String.format("Invalid license expression '%s': %s",
80+
getLicenseExpression(), getMessage()));
81+
} catch(Exception e) {
82+
retval.add(String.format("Error getting properties: %s", e.getMessage()));
83+
}
84+
return retval;
85+
}
86+
87+
@Override
88+
public String getType() {
89+
return INVALID_LICENSE_EXPRESSION_TYPE;
90+
}
91+
92+
@Override
93+
public String toString() {
94+
try {
95+
return getLicenseExpression();
96+
} catch (InvalidSPDXAnalysisException e) {
97+
return "";
98+
}
99+
}
100+
101+
/**
102+
* @return the error message associated with the license expression
103+
* @throws InvalidSPDXAnalysisException on storage related errors
104+
*/
105+
public String getMessage() throws InvalidSPDXAnalysisException {
106+
Optional<String> o = getStringPropertyValue(MESSAGE_PROPERTY);
107+
return o.orElse("[Error message not set]");
108+
}
109+
110+
/**
111+
* @param message the message to set
112+
* @throws InvalidSPDXAnalysisException on storage related errors
113+
*/
114+
public void setMessage(String message) throws InvalidSPDXAnalysisException {
115+
setPropertyValue(MESSAGE_PROPERTY, message);
116+
}
117+
118+
/**
119+
* @return the license expression which had parsing errors
120+
* @throws InvalidSPDXAnalysisException on storage related errors
121+
*/
122+
public String getLicenseExpression() throws InvalidSPDXAnalysisException {
123+
Optional<String> o = getStringPropertyValue(LICENSE_EXPRESSION_PROPERTY);
124+
return o.orElse("[Error message not set]");
125+
}
126+
127+
/**
128+
* @param expression the license expression to set
129+
* @throws InvalidSPDXAnalysisException on storage related errors
130+
*/
131+
public void setLicenseExpression(String expression) throws InvalidSPDXAnalysisException {
132+
setPropertyValue(LICENSE_EXPRESSION_PROPERTY, expression);
133+
}
134+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* SPDX-FileCopyrightText: Copyright (c) 2025 Source Auditor Inc.
3+
* SPDX-FileType: SOURCE
4+
* SPDX-License-Identifier: Apache-2.0
5+
* <p>
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
* <p>
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
* <p>
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
package org.spdx.library.model.compat.v2.license;
20+
21+
import junit.framework.TestCase;
22+
import org.spdx.core.DefaultModelStore;
23+
import org.spdx.core.InvalidSPDXAnalysisException;
24+
import org.spdx.core.ModelRegistry;
25+
import org.spdx.library.model.compat.v2.MockCopyManager;
26+
import org.spdx.library.model.compat.v2.MockModelStore;
27+
import org.spdx.library.model.v2.SpdxConstantsCompatV2;
28+
import org.spdx.library.model.v2.SpdxModelFactoryCompatV2;
29+
import org.spdx.library.model.v2.SpdxModelInfoV2_X;
30+
import org.spdx.library.model.v2.license.ExtractedLicenseInfo;
31+
import org.spdx.library.model.v2.license.InvalidLicenseExpression;
32+
import org.spdx.storage.IModelStore;
33+
34+
import java.util.List;
35+
36+
public class InvalidLicenseExpressionTest extends TestCase {
37+
38+
/* (non-Javadoc)
39+
* @see junit.framework.TestCase#setUp()
40+
*/
41+
protected void setUp() throws Exception {
42+
super.setUp();
43+
ModelRegistry.getModelRegistry().registerModel(new SpdxModelInfoV2_X());
44+
DefaultModelStore.initialize(new MockModelStore(), "http://defaultdocument", new MockCopyManager());
45+
}
46+
47+
/* (non-Javadoc)
48+
* @see junit.framework.TestCase#tearDown()
49+
*/
50+
protected void tearDown() throws Exception {
51+
super.tearDown();
52+
}
53+
54+
public void testInvalidLicenseExpressionMessageLicenseExpression() throws InvalidSPDXAnalysisException {
55+
String message = "error message";
56+
String expression = "license expression";
57+
String id = DefaultModelStore.getDefaultModelStore().getNextId(IModelStore.IdType.Anonymous);
58+
InvalidLicenseExpression inv1 = new InvalidLicenseExpression(DefaultModelStore.getDefaultModelStore(), DefaultModelStore.getDefaultDocumentUri(),
59+
id, DefaultModelStore.getDefaultCopyManager(), message, expression);
60+
61+
InvalidLicenseExpression inv2 = (InvalidLicenseExpression) SpdxModelFactoryCompatV2.createModelObjectV2(DefaultModelStore.getDefaultModelStore(), DefaultModelStore.getDefaultDocumentUri(),
62+
id, InvalidLicenseExpression.INVALID_LICENSE_EXPRESSION_TYPE, DefaultModelStore.getDefaultCopyManager());
63+
assertEquals(message, inv2.getMessage());
64+
assertEquals(expression, inv2.getLicenseExpression());
65+
List<String> verify = inv2.verify();
66+
assertEquals(1, verify.size());
67+
assertTrue(verify.get(0).contains(message));
68+
assertTrue(verify.get(0).contains(expression));
69+
}
70+
71+
}

0 commit comments

Comments
 (0)