|
13 | 13 | */
|
14 | 14 | package org.cyclonedx.schema;
|
15 | 15 |
|
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; |
17 | 37 | import java.util.ArrayList;
|
18 | 38 | import java.util.Collection;
|
19 | 39 | import java.util.List;
|
20 |
| - |
21 |
| -import org.cyclonedx.parsers.JsonParser; |
22 |
| -import org.cyclonedx.Version; |
| 40 | +import org.apache.commons.lang3.StringUtils; |
23 | 41 | import org.junit.jupiter.api.DynamicTest;
|
24 | 42 | import org.junit.jupiter.api.TestFactory;
|
25 | 43 |
|
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 | + } |
28 | 79 |
|
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 | + } |
30 | 88 |
|
31 | 89 | @TestFactory
|
32 | 90 | Collection<DynamicTest> dynamicTestsWithCollection() throws Exception {
|
33 |
| - final List<String> files = getAllResources(); |
| 91 | + final List<String> resources = getAllResources(); |
34 | 92 | 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 { |
49 |
| - schemaVersion = null; |
50 |
| - } |
51 |
| - if (file.startsWith("valid") && schemaVersion != null) { |
52 |
| - dynamicTests.add(DynamicTest.dynamicTest(file, () -> assertTrue( |
53 |
| - isValidJson(schemaVersion, "/" + schemaVersion.getVersionString() + "/" + file), file))); |
54 |
| - } else if (file.startsWith("invalid") && schemaVersion != null) { |
55 |
| - dynamicTests.add(DynamicTest.dynamicTest(file, () -> assertFalse( |
56 |
| - 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 | + } |
57 | 105 | }
|
58 | 106 | }
|
59 | 107 | }
|
60 | 108 | return dynamicTests;
|
61 | 109 | }
|
62 | 110 |
|
63 |
| - private boolean isValidJson(Version version, String resource) throws Exception { |
64 |
| - final File file = new File(this.getClass().getResource(resource).getFile()); |
65 |
| - final JsonParser parser = new JsonParser(); |
66 |
| - return parser.isValid(file, version); |
67 |
| - |
68 |
| - // Uncomment to provide more detailed validation errors |
69 |
| - /* |
70 |
| - try { |
71 |
| - final String jsonString = FileUtils.readFileToString(file, StandardCharsets.UTF_8); |
72 |
| - parser.getJsonSchema(version, true).validate(new JSONObject(jsonString)); |
73 |
| - return true; |
74 |
| - } catch (ValidationException e) { |
75 |
| - 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) { |
76 | 117 | return false;
|
77 | 118 | }
|
78 |
| - */ |
| 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; |
79 | 138 | }
|
80 | 139 | }
|
0 commit comments