Skip to content

Commit 0a978ea

Browse files
committed
Merge remote-tracking branch 'origin/master' into 1.7-dev
2 parents 36dc8f6 + d570ffb commit 0a978ea

File tree

6 files changed

+260
-110
lines changed

6 files changed

+260
-110
lines changed

tools/pom.xml

Lines changed: 34 additions & 9 deletions
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

Lines changed: 6 additions & 9 deletions
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

Lines changed: 103 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -13,70 +13,127 @@
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 {
45+
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+
57+
static {
58+
JsonMetaSchemaFactory metaSchemaFactory = new DefaultJsonMetaSchemaFactory() {
59+
@Override
60+
public JsonMetaSchema getMetaSchema(
61+
String iri, JsonSchemaFactory schemaFactory, SchemaValidatorsConfig config) {
62+
return addCustomKeywords(super.getMetaSchema(iri, schemaFactory, config));
63+
}
64+
};
65+
JsonSchemaFactory factory = JsonSchemaFactory.builder()
66+
.defaultMetaSchemaIri(SchemaId.V7)
67+
.metaSchema(addCustomKeywords(JsonMetaSchema.getV7()))
68+
.metaSchemaFactory(metaSchemaFactory)
69+
.schemaLoaders(b -> b.add(new ClasspathSchemaLoader()).add(DisallowSchemaLoader.getInstance()))
70+
.schemaMappers(b -> b.mapPrefix(SPDX_NAMESPACE, "classpath:spdx.schema.json")
71+
.mapPrefix(JSF_NAMESPACE, "classpath:jsf-0.82.schema.json"))
72+
.build();
73+
VERSION_12 = factory.getSchema(SchemaLocation.of("classpath:bom-1.2-strict.schema.json"));
74+
VERSION_13 = factory.getSchema(SchemaLocation.of("classpath:bom-1.3-strict.schema.json"));
75+
VERSION_14 = factory.getSchema(SchemaLocation.of("classpath:bom-1.4.schema.json"));
76+
VERSION_15 = factory.getSchema(SchemaLocation.of("classpath:bom-1.5.schema.json"));
77+
VERSION_16 = factory.getSchema(SchemaLocation.of("classpath:bom-1.6.schema.json"));
78+
}
2879

29-
public class JsonSchemaVerificationTest extends BaseSchemaVerificationTest {
80+
private static JsonMetaSchema addCustomKeywords(JsonMetaSchema metaSchema) {
81+
return JsonMetaSchema.builder(metaSchema)
82+
// Non-standard keywords in the CycloneDX schema files.
83+
.keyword(new NonValidationKeyword("deprecated"))
84+
.keyword(new NonValidationKeyword("meta:enum"))
85+
.unknownKeywordFactory(new DisallowUnknownKeywordFactory())
86+
.build();
87+
}
3088

3189
@TestFactory
3290
Collection<DynamicTest> dynamicTestsWithCollection() throws Exception {
33-
final List<String> files = getAllResources();
91+
final List<String> resources = getAllResources();
3492
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)));
93+
for (final String resource : resources) {
94+
String resourceName = StringUtils.substringAfterLast(resource, "/");
95+
if (resourceName.endsWith(".json")) {
96+
JsonSchema schema = getSchema(resourceName);
97+
if (schema != null) {
98+
if (resourceName.startsWith("valid")) {
99+
dynamicTests.add(DynamicTest.dynamicTest(
100+
resource, () -> assertTrue(isValid(schema, resource), resource)));
101+
} else if (resourceName.startsWith("invalid")) {
102+
dynamicTests.add(DynamicTest.dynamicTest(
103+
resource, () -> assertFalse(isValid(schema, resource), resource)));
104+
}
59105
}
60106
}
61107
}
62108
return dynamicTests;
63109
}
64110

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();
111+
private boolean isValid(JsonSchema schema, String resource) {
112+
try (InputStream input = getClass().getClassLoader().getResourceAsStream(resource);
113+
JsonParser parser = MAPPER.createParser(input)) {
114+
JsonNode node = parser.readValueAsTree();
115+
return schema.validate(node).isEmpty();
116+
} catch (IOException e) {
78117
return false;
79118
}
80-
*/
119+
}
120+
121+
private JsonSchema getSchema(String resourceName) {
122+
if (resourceName.endsWith("-1.2.json")) {
123+
return VERSION_12;
124+
}
125+
if (resourceName.endsWith("-1.3.json")) {
126+
return VERSION_13;
127+
}
128+
if (resourceName.endsWith("-1.4.json")) {
129+
return VERSION_14;
130+
}
131+
if (resourceName.endsWith("-1.5.json")) {
132+
return VERSION_15;
133+
}
134+
if (resourceName.endsWith("-1.6.json")) {
135+
return VERSION_16;
136+
}
137+
return null;
81138
}
82139
}

0 commit comments

Comments
 (0)