diff --git a/com.vogella.adapters/META-INF/MANIFEST.MF b/com.vogella.adapters/META-INF/MANIFEST.MF index d21db6d..cb6569c 100644 --- a/com.vogella.adapters/META-INF/MANIFEST.MF +++ b/com.vogella.adapters/META-INF/MANIFEST.MF @@ -15,5 +15,5 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.core.resources, org.eclipse.e4.ui.workbench Bundle-RequiredExecutionEnvironment: JavaSE-25 -Import-Package: jakarta.annotation;version="[2.1.0,3.0.0)" +Import-Package: jakarta.annotation;version="[2.1.0,4.0.0)" Automatic-Module-Name: com.vogella.adapters diff --git a/com.vogella.contribute.parts/META-INF/MANIFEST.MF b/com.vogella.contribute.parts/META-INF/MANIFEST.MF index e30f33e..07ffb07 100644 --- a/com.vogella.contribute.parts/META-INF/MANIFEST.MF +++ b/com.vogella.contribute.parts/META-INF/MANIFEST.MF @@ -18,6 +18,6 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.ui.workbench;bundle-version="3.134.0", org.eclipse.e4.core.contexts Bundle-RequiredExecutionEnvironment: JavaSE-25 -Import-Package: jakarta.annotation;version="[2.1.0,3.0.0)", +Import-Package: jakarta.annotation;version="[2.1.0,4.0.0)", jakarta.inject;version="[2.0.0,3.0.0)" Automatic-Module-Name: com.vogella.contribute.parts diff --git a/com.vogella.ide.first/META-INF/MANIFEST.MF b/com.vogella.ide.first/META-INF/MANIFEST.MF index c602fbc..8bbd56b 100644 --- a/com.vogella.ide.first/META-INF/MANIFEST.MF +++ b/com.vogella.ide.first/META-INF/MANIFEST.MF @@ -12,6 +12,6 @@ Require-Bundle: org.eclipse.osgi, org.eclipse.e4.core.di.annotations Bundle-RequiredExecutionEnvironment: JavaSE-25 Import-Package: com.vogella.tasks.model, - jakarta.annotation;version="[2.1.0,3.0.0)", + jakarta.annotation;version="[2.1.0,4.0.0)", jakarta.inject;version="[2.0.0,3.0.0)" Automatic-Module-Name: com.vogella.ide.first diff --git a/com.vogella.json.validation.tests/.classpath b/com.vogella.json.validation.tests/.classpath new file mode 100644 index 0000000..2198f33 --- /dev/null +++ b/com.vogella.json.validation.tests/.classpath @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/com.vogella.json.validation.tests/.project b/com.vogella.json.validation.tests/.project new file mode 100644 index 0000000..6be8a94 --- /dev/null +++ b/com.vogella.json.validation.tests/.project @@ -0,0 +1,34 @@ + + + com.vogella.json.validation.tests + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.m2e.core.maven2Nature + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/com.vogella.json.validation.tests/.settings/org.eclipse.jdt.core.prefs b/com.vogella.json.validation.tests/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..c540a97 --- /dev/null +++ b/com.vogella.json.validation.tests/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,9 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=25 +org.eclipse.jdt.core.compiler.compliance=25 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=25 diff --git a/com.vogella.json.validation.tests/META-INF/MANIFEST.MF b/com.vogella.json.validation.tests/META-INF/MANIFEST.MF new file mode 100644 index 0000000..3cb3117 --- /dev/null +++ b/com.vogella.json.validation.tests/META-INF/MANIFEST.MF @@ -0,0 +1,10 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: JSON Schema Validation Example Tests +Bundle-SymbolicName: com.vogella.json.validation.tests +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: VOGELLA +Fragment-Host: com.vogella.json.validation;bundle-version="1.0.0" +Require-Bundle: junit-jupiter-api;bundle-version="5.11.0" +Automatic-Module-Name: com.vogella.json.validation.tests +Bundle-RequiredExecutionEnvironment: JavaSE-25 diff --git a/com.vogella.json.validation.tests/build.properties b/com.vogella.json.validation.tests/build.properties new file mode 100644 index 0000000..34d2e4d --- /dev/null +++ b/com.vogella.json.validation.tests/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/com.vogella.json.validation.tests/pom.xml b/com.vogella.json.validation.tests/pom.xml new file mode 100644 index 0000000..a8f2941 --- /dev/null +++ b/com.vogella.json.validation.tests/pom.xml @@ -0,0 +1,17 @@ + + 4.0.0 + + + com.vogella.tycho + releng + 1.0.0-SNAPSHOT + + + com.vogella.json + com.vogella.json.validation.tests + 1.0.0-SNAPSHOT + eclipse-test-plugin + + diff --git a/com.vogella.json.validation.tests/src/com/vogella/json/validation/tests/JsonSchemaValidationExampleTest.java b/com.vogella.json.validation.tests/src/com/vogella/json/validation/tests/JsonSchemaValidationExampleTest.java new file mode 100644 index 0000000..9cec746 --- /dev/null +++ b/com.vogella.json.validation.tests/src/com/vogella/json/validation/tests/JsonSchemaValidationExampleTest.java @@ -0,0 +1,55 @@ +package com.vogella.json.validation.tests; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.Set; + +import org.junit.jupiter.api.Test; + +import com.networknt.schema.ValidationMessage; +import com.vogella.json.validation.JsonSchemaValidationExample; + +class JsonSchemaValidationExampleTest { + + private final JsonSchemaValidationExample example = new JsonSchemaValidationExample(); + + @Test + void validDocumentHasNoErrors() throws Exception { + try (InputStream schema = schema(); InputStream data = resource("data.json")) { + Set errors = example.validate(schema, data); + assertTrue(errors.isEmpty(), () -> "Expected no errors but got: " + errors); + } + } + + @Test + void invalidDocumentReportsErrors() throws Exception { + // Missing required "name", negative "age", and an undeclared property. + String invalid = """ + { + "age": -1, + "unexpected": true + } + """; + try (InputStream schema = schema(); + InputStream data = new ByteArrayInputStream(invalid.getBytes(StandardCharsets.UTF_8))) { + Set errors = example.validate(schema, data); + assertFalse(errors.isEmpty(), "Expected validation errors for an invalid document"); + } + } + + private static InputStream schema() { + return resource("schema.json"); + } + + private static InputStream resource(String name) { + InputStream in = JsonSchemaValidationExample.class.getResourceAsStream(name); + if (in == null) { + throw new IllegalStateException("Missing classpath resource: " + name); + } + return in; + } +} diff --git a/com.vogella.json.validation/.classpath b/com.vogella.json.validation/.classpath new file mode 100644 index 0000000..7a42e53 --- /dev/null +++ b/com.vogella.json.validation/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/com.vogella.json.validation/.project b/com.vogella.json.validation/.project new file mode 100644 index 0000000..e6a71e5 --- /dev/null +++ b/com.vogella.json.validation/.project @@ -0,0 +1,34 @@ + + + com.vogella.json.validation + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.m2e.core.maven2Nature + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/com.vogella.json.validation/.settings/org.eclipse.jdt.core.prefs b/com.vogella.json.validation/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..c540a97 --- /dev/null +++ b/com.vogella.json.validation/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,9 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=25 +org.eclipse.jdt.core.compiler.compliance=25 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=25 diff --git a/com.vogella.json.validation/META-INF/MANIFEST.MF b/com.vogella.json.validation/META-INF/MANIFEST.MF new file mode 100644 index 0000000..558fcdb --- /dev/null +++ b/com.vogella.json.validation/META-INF/MANIFEST.MF @@ -0,0 +1,11 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: JSON Schema Validation Example +Bundle-SymbolicName: com.vogella.json.validation +Bundle-Version: 1.0.0.qualifier +Bundle-Vendor: VOGELLA +Automatic-Module-Name: com.vogella.json.validation +Bundle-RequiredExecutionEnvironment: JavaSE-25 +Export-Package: com.vogella.json.validation +Require-Bundle: com.networknt.json-schema-validator;bundle-version="1.5.6", + com.fasterxml.jackson.core.jackson-databind;bundle-version="[2.18.0,3.0.0)" diff --git a/com.vogella.json.validation/build.properties b/com.vogella.json.validation/build.properties new file mode 100644 index 0000000..34d2e4d --- /dev/null +++ b/com.vogella.json.validation/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/com.vogella.json.validation/src/com/vogella/json/validation/JsonSchemaValidationExample.java b/com.vogella.json.validation/src/com/vogella/json/validation/JsonSchemaValidationExample.java new file mode 100644 index 0000000..8d352ed --- /dev/null +++ b/com.vogella.json.validation/src/com/vogella/json/validation/JsonSchemaValidationExample.java @@ -0,0 +1,64 @@ +package com.vogella.json.validation; + +import java.io.IOException; +import java.io.InputStream; +import java.io.UncheckedIOException; +import java.util.Set; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.networknt.schema.JsonSchema; +import com.networknt.schema.JsonSchemaFactory; +import com.networknt.schema.SpecVersion; +import com.networknt.schema.ValidationMessage; + +/** + * Validates a JSON document against a JSON Schema (Draft 2020-12) using + * networknt/json-schema-validator. + */ +public class JsonSchemaValidationExample { + + private static final ObjectMapper MAPPER = new ObjectMapper(); + private static final JsonSchemaFactory FACTORY = JsonSchemaFactory + .getInstance(SpecVersion.VersionFlag.V202012); + + /** + * Validates the JSON read from {@code data} against the schema read from + * {@code schema}. + * + * @return the validation errors, empty if the document is valid + */ + public Set validate(InputStream schema, InputStream data) { + try { + JsonSchema jsonSchema = FACTORY.getSchema(schema); + JsonNode node = MAPPER.readTree(data); + return jsonSchema.validate(node); + } catch (IOException e) { + throw new UncheckedIOException("Could not read JSON schema or data", e); + } + } + + public static void main(String[] args) { + JsonSchemaValidationExample example = new JsonSchemaValidationExample(); + try (InputStream schema = resource("schema.json"); + InputStream data = resource("data.json")) { + Set errors = example.validate(schema, data); + if (errors.isEmpty()) { + System.out.println("data.json is valid against schema.json"); + } else { + System.out.println("data.json is invalid:"); + errors.forEach(error -> System.out.println(" " + error.getMessage())); + } + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + private static InputStream resource(String name) { + InputStream in = JsonSchemaValidationExample.class.getResourceAsStream(name); + if (in == null) { + throw new IllegalStateException("Missing classpath resource: " + name); + } + return in; + } +} diff --git a/com.vogella.json.validation/src/com/vogella/json/validation/data.json b/com.vogella.json.validation/src/com/vogella/json/validation/data.json new file mode 100644 index 0000000..9ad3614 --- /dev/null +++ b/com.vogella.json.validation/src/com/vogella/json/validation/data.json @@ -0,0 +1,5 @@ +{ + "name": "Alice", + "age": 30, + "email": "alice@example.com" +} diff --git a/com.vogella.json.validation/src/com/vogella/json/validation/schema.json b/com.vogella.json.validation/src/com/vogella/json/validation/schema.json new file mode 100644 index 0000000..aec2aba --- /dev/null +++ b/com.vogella.json.validation/src/com/vogella/json/validation/schema.json @@ -0,0 +1,12 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Person", + "type": "object", + "properties": { + "name": { "type": "string" }, + "age": { "type": "integer", "minimum": 0 }, + "email": { "type": "string", "format": "email" } + }, + "required": ["name", "age"], + "additionalProperties": false +} diff --git a/com.vogella.tasks.ui/META-INF/MANIFEST.MF b/com.vogella.tasks.ui/META-INF/MANIFEST.MF index 8efba09..139d9e1 100644 --- a/com.vogella.tasks.ui/META-INF/MANIFEST.MF +++ b/com.vogella.tasks.ui/META-INF/MANIFEST.MF @@ -24,7 +24,7 @@ Require-Bundle: org.eclipse.core.runtime, Bundle-RequiredExecutionEnvironment: JavaSE-25 Import-Package: com.vogella.tasks.events, com.vogella.tasks.model, - jakarta.annotation;version="[2.1.0,3.0.0)", + jakarta.annotation;version="[2.1.0,4.0.0)", jakarta.inject;version="[2.0.0,3.0.0)" Automatic-Module-Name: com.vogella.tasks.ui Bundle-ActivationPolicy: lazy diff --git a/pom.xml b/pom.xml index 308bb4c..c802d21 100644 --- a/pom.xml +++ b/pom.xml @@ -140,8 +140,10 @@ z.ex.search com.vogella.ide.iconreplacer com.vogella.ide.parallelstart + com.vogella.json.validation + com.vogella.json.validation.tests