Skip to content

Commit f5aa93e

Browse files
authored
Merge branch '1.7-dev' into feat/licenses-multi-mix-all
2 parents 3f3873e + 88de88c commit f5aa93e

6 files changed

+270
-110
lines changed

tools/pom.xml

+34-9
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,9 @@
5454
<lib.commons.io.version>2.17.0</lib.commons.io.version>
5555
<lib.commons.lang3.version>3.17.0</lib.commons.lang3.version>
5656
<lib.commons.text.version>1.12.0</lib.commons.text.version>
57+
<lib.json.schema.validator>1.5.5</lib.json.schema.validator>
5758
<lib.unirest.version>1.4.9</lib.unirest.version>
58-
<lib.cyclonedx.core.java.version>10.0.0</lib.cyclonedx.core.java.version>
59+
<lib.slf4j.api>2.0.16</lib.slf4j.api>
5960
</properties>
6061

6162
<scm>
@@ -98,6 +99,24 @@
9899
</repository>
99100
</repositories>
100101

102+
<dependencyManagement>
103+
<dependencies>
104+
105+
<dependency>
106+
<groupId>org.slf4j</groupId>
107+
<artifactId>slf4j-api</artifactId>
108+
<version>${lib.slf4j.api}</version>
109+
</dependency>
110+
111+
<dependency>
112+
<groupId>org.slf4j</groupId>
113+
<artifactId>slf4j-simple</artifactId>
114+
<version>${lib.slf4j.api}</version>
115+
</dependency>
116+
117+
</dependencies>
118+
</dependencyManagement>
119+
101120
<dependencies>
102121
<!-- Apache Commons -->
103122
<dependency>
@@ -123,16 +142,22 @@
123142
<scope>compile</scope>
124143
</dependency>
125144
<!-- Unit tests -->
145+
<dependency>
146+
<groupId>com.networknt</groupId>
147+
<artifactId>json-schema-validator</artifactId>
148+
<version>${lib.json.schema.validator}</version>
149+
<scope>test</scope>
150+
</dependency>
126151
<dependency>
127152
<groupId>org.junit.jupiter</groupId>
128-
<artifactId>junit-jupiter-engine</artifactId>
129-
<version>5.7.0</version>
153+
<artifactId>junit-jupiter-api</artifactId>
154+
<version>5.11.4</version>
130155
<scope>test</scope>
131156
</dependency>
157+
<!-- Runtime-only test dependency -->
132158
<dependency>
133-
<groupId>org.cyclonedx</groupId>
134-
<artifactId>cyclonedx-core-java</artifactId>
135-
<version>${lib.cyclonedx.core.java.version}</version>
159+
<groupId>org.slf4j</groupId>
160+
<artifactId>slf4j-simple</artifactId>
136161
<scope>test</scope>
137162
</dependency>
138163
</dependencies>
@@ -142,15 +167,15 @@
142167
<plugin>
143168
<groupId>org.apache.maven.plugins</groupId>
144169
<artifactId>maven-surefire-plugin</artifactId>
145-
<version>3.5.1</version>
170+
<version>3.5.2</version>
146171
</plugin>
147172
</plugins>
148173
<testResources>
149174
<testResource>
150-
<directory>${basedir}/../schema</directory>
175+
<directory>${project.basedir}/../schema</directory>
151176
</testResource>
152177
<testResource>
153-
<directory>src/test/resources/</directory>
178+
<directory>src/test/resources</directory>
154179
</testResource>
155180
</testResources>
156181
</build>

tools/src/test/java/org/cyclonedx/schema/BaseSchemaVerificationTest.java

+6-9
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,14 @@ List<String> getAllResources() throws Exception {
3434
return files;
3535
}
3636

37-
List<String> getResources(final String resourceDirectory) throws Exception {
38-
final List<String> files = new ArrayList<>();
39-
String dir = resourceDirectory;
40-
if (!resourceDirectory.endsWith("/")) {
41-
dir += "/";
42-
}
43-
try (InputStream in = this.getClass().getClassLoader().getResourceAsStream(dir)) {
37+
private List<String> getResources(final String resourceDirectory) throws Exception {
38+
final List<String> resources = new ArrayList<>();
39+
try (InputStream in = this.getClass().getClassLoader().getResourceAsStream(resourceDirectory)) {
4440
if (in != null) {
45-
files.addAll(IOUtils.readLines(in, StandardCharsets.UTF_8));
41+
IOUtils.readLines(in, StandardCharsets.UTF_8)
42+
.forEach(resource -> resources.add(resourceDirectory + resource));
4643
}
4744
}
48-
return files;
45+
return resources;
4946
}
5047
}

tools/src/test/java/org/cyclonedx/schema/JsonSchemaVerificationTest.java

+108-46
Original file line numberDiff line numberDiff line change
@@ -13,70 +13,132 @@
1313
*/
1414
package org.cyclonedx.schema;
1515

16-
import java.io.File;
16+
import static org.junit.jupiter.api.Assertions.assertFalse;
17+
import static org.junit.jupiter.api.Assertions.assertTrue;
18+
19+
import com.fasterxml.jackson.core.JsonParser;
20+
import com.fasterxml.jackson.databind.JsonNode;
21+
import com.fasterxml.jackson.databind.ObjectMapper;
22+
import com.fasterxml.jackson.databind.json.JsonMapper;
23+
import com.networknt.schema.DefaultJsonMetaSchemaFactory;
24+
import com.networknt.schema.DisallowUnknownKeywordFactory;
25+
import com.networknt.schema.JsonMetaSchema;
26+
import com.networknt.schema.JsonMetaSchemaFactory;
27+
import com.networknt.schema.JsonSchema;
28+
import com.networknt.schema.JsonSchemaFactory;
29+
import com.networknt.schema.NonValidationKeyword;
30+
import com.networknt.schema.SchemaId;
31+
import com.networknt.schema.SchemaLocation;
32+
import com.networknt.schema.SchemaValidatorsConfig;
33+
import com.networknt.schema.resource.ClasspathSchemaLoader;
34+
import com.networknt.schema.resource.DisallowSchemaLoader;
35+
import java.io.IOException;
36+
import java.io.InputStream;
1737
import java.util.ArrayList;
1838
import java.util.Collection;
1939
import java.util.List;
20-
21-
import org.cyclonedx.parsers.JsonParser;
22-
import org.cyclonedx.Version;
40+
import org.apache.commons.lang3.StringUtils;
2341
import org.junit.jupiter.api.DynamicTest;
2442
import org.junit.jupiter.api.TestFactory;
2543

26-
import static org.junit.jupiter.api.Assertions.assertTrue;
27-
import static org.junit.jupiter.api.Assertions.assertFalse;
44+
class JsonSchemaVerificationTest extends BaseSchemaVerificationTest {
2845

29-
public class JsonSchemaVerificationTest extends BaseSchemaVerificationTest {
46+
private static final ObjectMapper MAPPER = new JsonMapper();
47+
48+
private static final String JSF_NAMESPACE = "http://cyclonedx.org/schema/jsf-0.82.schema.json";
49+
private static final String SPDX_NAMESPACE = "http://cyclonedx.org/schema/spdx.schema.json";
50+
51+
private static final JsonSchema VERSION_12;
52+
private static final JsonSchema VERSION_13;
53+
private static final JsonSchema VERSION_14;
54+
private static final JsonSchema VERSION_15;
55+
private static final JsonSchema VERSION_16;
56+
private static final JsonSchema VERSION_17;
57+
58+
static {
59+
JsonMetaSchemaFactory metaSchemaFactory = new DefaultJsonMetaSchemaFactory() {
60+
@Override
61+
public JsonMetaSchema getMetaSchema(
62+
String iri, JsonSchemaFactory schemaFactory, SchemaValidatorsConfig config) {
63+
return addCustomKeywords(super.getMetaSchema(iri, schemaFactory, config));
64+
}
65+
};
66+
JsonSchemaFactory factory = JsonSchemaFactory.builder()
67+
.defaultMetaSchemaIri(SchemaId.V7)
68+
.metaSchema(addCustomKeywords(JsonMetaSchema.getV7()))
69+
.metaSchemaFactory(metaSchemaFactory)
70+
.schemaLoaders(b -> b.add(new ClasspathSchemaLoader()).add(DisallowSchemaLoader.getInstance()))
71+
.schemaMappers(b -> b.mapPrefix(SPDX_NAMESPACE, "classpath:spdx.schema.json")
72+
.mapPrefix(JSF_NAMESPACE, "classpath:jsf-0.82.schema.json"))
73+
.build();
74+
VERSION_12 = factory.getSchema(SchemaLocation.of("classpath:bom-1.2-strict.schema.json"));
75+
VERSION_13 = factory.getSchema(SchemaLocation.of("classpath:bom-1.3-strict.schema.json"));
76+
VERSION_14 = factory.getSchema(SchemaLocation.of("classpath:bom-1.4.schema.json"));
77+
VERSION_15 = factory.getSchema(SchemaLocation.of("classpath:bom-1.5.schema.json"));
78+
VERSION_16 = factory.getSchema(SchemaLocation.of("classpath:bom-1.6.schema.json"));
79+
VERSION_17 = factory.getSchema(SchemaLocation.of("classpath:bom-1.7.schema.json"));
80+
}
81+
82+
private static JsonMetaSchema addCustomKeywords(JsonMetaSchema metaSchema) {
83+
return JsonMetaSchema.builder(metaSchema)
84+
// Non-standard keywords in the CycloneDX schema files.
85+
.keyword(new NonValidationKeyword("deprecated"))
86+
.keyword(new NonValidationKeyword("meta:enum"))
87+
.unknownKeywordFactory(new DisallowUnknownKeywordFactory())
88+
.build();
89+
}
3090

3191
@TestFactory
3292
Collection<DynamicTest> dynamicTestsWithCollection() throws Exception {
33-
final List<String> files = getAllResources();
93+
final List<String> resources = getAllResources();
3494
final List<DynamicTest> dynamicTests = new ArrayList<>();
35-
for (final String file: files) {
36-
if (file.endsWith(".json")) {
37-
final Version schemaVersion;
38-
if (file.endsWith("-1.2.json")) {
39-
schemaVersion = Version.VERSION_12;
40-
} else if (file.endsWith("-1.3.json")) {
41-
schemaVersion = Version.VERSION_13;
42-
} else if (file.endsWith("-1.4.json")) {
43-
schemaVersion = Version.VERSION_14;
44-
} else if (file.endsWith("-1.5.json")) {
45-
schemaVersion = Version.VERSION_15;
46-
} else if (file.endsWith("-1.6.json")) {
47-
schemaVersion = Version.VERSION_16;
48-
} else if (file.endsWith("-1.7.json")) {
49-
schemaVersion = Version.VERSION_17;
50-
} else {
51-
schemaVersion = null;
52-
}
53-
if (file.startsWith("valid") && schemaVersion != null) {
54-
dynamicTests.add(DynamicTest.dynamicTest(file, () -> assertTrue(
55-
isValidJson(schemaVersion, "/" + schemaVersion.getVersionString() + "/" + file), file)));
56-
} else if (file.startsWith("invalid") && schemaVersion != null) {
57-
dynamicTests.add(DynamicTest.dynamicTest(file, () -> assertFalse(
58-
isValidJson(schemaVersion, "/" + schemaVersion.getVersionString() + "/" + file), file)));
95+
for (final String resource : resources) {
96+
String resourceName = StringUtils.substringAfterLast(resource, "/");
97+
if (resourceName.endsWith(".json")) {
98+
JsonSchema schema = getSchema(resourceName);
99+
if (schema != null) {
100+
if (resourceName.startsWith("valid")) {
101+
dynamicTests.add(DynamicTest.dynamicTest(
102+
resource, () -> assertTrue(isValid(schema, resource), resource)));
103+
} else if (resourceName.startsWith("invalid")) {
104+
dynamicTests.add(DynamicTest.dynamicTest(
105+
resource, () -> assertFalse(isValid(schema, resource), resource)));
106+
}
59107
}
60108
}
61109
}
62110
return dynamicTests;
63111
}
64112

65-
private boolean isValidJson(Version version, String resource) throws Exception {
66-
final File file = new File(this.getClass().getResource(resource).getFile());
67-
final JsonParser parser = new JsonParser();
68-
return parser.isValid(file, version);
69-
70-
// Uncomment to provide more detailed validation errors
71-
/*
72-
try {
73-
final String jsonString = FileUtils.readFileToString(file, StandardCharsets.UTF_8);
74-
parser.getJsonSchema(version, true).validate(new JSONObject(jsonString));
75-
return true;
76-
} catch (ValidationException e) {
77-
e.printStackTrace();
113+
private boolean isValid(JsonSchema schema, String resource) {
114+
try (InputStream input = getClass().getClassLoader().getResourceAsStream(resource);
115+
JsonParser parser = MAPPER.createParser(input)) {
116+
JsonNode node = parser.readValueAsTree();
117+
return schema.validate(node).isEmpty();
118+
} catch (IOException e) {
78119
return false;
79120
}
80-
*/
121+
}
122+
123+
private JsonSchema getSchema(String resourceName) {
124+
if (resourceName.endsWith("-1.2.json")) {
125+
return VERSION_12;
126+
}
127+
if (resourceName.endsWith("-1.3.json")) {
128+
return VERSION_13;
129+
}
130+
if (resourceName.endsWith("-1.4.json")) {
131+
return VERSION_14;
132+
}
133+
if (resourceName.endsWith("-1.5.json")) {
134+
return VERSION_15;
135+
}
136+
if (resourceName.endsWith("-1.6.json")) {
137+
return VERSION_16;
138+
}
139+
if (resourceName.endsWith("-1.7.json")) {
140+
return VERSION_17;
141+
}
142+
return null;
81143
}
82144
}

0 commit comments

Comments
 (0)