Skip to content

Commit e5f2044

Browse files
Improved schema validation
1 parent 5e71272 commit e5f2044

File tree

5 files changed

+64
-52
lines changed

5 files changed

+64
-52
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ This project follows the [Open Knowledge International coding standards](https:/
217217
Get started:
218218
```sh
219219
# install jabba and maven2
220-
$ cd tableschema-java
220+
$ cd datapackage-java
221221
$ jabba install 17
222222
$ jabba use 17
223223
$ mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<modelVersion>4.0.0</modelVersion>
55
<groupId>io.frictionlessdata</groupId>
66
<artifactId>datapackage-java</artifactId>
7-
<version>0.7.2-SNAPSHOT</version>
7+
<version>0.7.3-SNAPSHOT</version>
88
<packaging>jar</packaging>
99
<issueManagement>
1010
<url>https://github.com/frictionlessdata/datapackage-java/issues</url>
@@ -23,7 +23,7 @@
2323
<maven.compiler.source>${java.version}</maven.compiler.source>
2424
<maven.compiler.target>${java.version}</maven.compiler.target>
2525
<maven.compiler.compiler>${java.version}</maven.compiler.compiler>
26-
<tableschema-java-version>0.7.2</tableschema-java-version>
26+
<tableschema-java-version>0.7.3</tableschema-java-version>
2727
<junit.version>5.12.0</junit.version>
2828
<slf4j-simple.version>2.0.17</slf4j-simple.version>
2929
<apache-commons-collections4.version>4.4</apache-commons-collections4.version>

src/main/java/io/frictionlessdata/datapackage/Validator.java

Lines changed: 51 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.frictionlessdata.datapackage;
22

33
import com.fasterxml.jackson.databind.JsonNode;
4+
import com.networknt.schema.ValidationMessage;
45
import io.frictionlessdata.datapackage.exceptions.DataPackageException;
56
import io.frictionlessdata.tableschema.exception.ValidationException;
67
import io.frictionlessdata.tableschema.schema.FormalSchemaValidator;
@@ -11,88 +12,92 @@
1112
import java.io.IOException;
1213
import java.io.InputStream;
1314
import java.net.URL;
15+
import java.util.Set;
1416

1517
/**
16-
*
17-
* Validates against schema.
18+
* Validates a package schema against the frictionlessdata table-schema.json (from the TableSchema project).
1819
*/
1920
public class Validator {
2021

2122
/**
2223
* Validates a given JSON Object against the default profile schema.
23-
* @param jsonObjectToValidate
24-
* @throws IOException
25-
* @throws DataPackageException
26-
* @throws ValidationException
24+
*
25+
* @param jsonObjectToValidate JSON Object to validate
26+
* @throws IOException If an I/O error occurs
27+
* @throws DataPackageException If the profile id is invalid
28+
* @throws ValidationException If the JSON Object is invalid
2729
*/
28-
public static void validate(JsonNode jsonObjectToValidate) throws IOException, DataPackageException, ValidationException{
29-
30+
public static void validate(JsonNode jsonObjectToValidate) throws IOException, DataPackageException, ValidationException {
3031
// If a profile value is provided.
31-
if(jsonObjectToValidate.has(Package.JSON_KEY_PROFILE)){
32-
String profile = jsonObjectToValidate.get(Package.JSON_KEY_PROFILE).asText();
33-
32+
Set<ValidationMessage> errors;
33+
String profileId = Profile.PROFILE_DATA_PACKAGE_DEFAULT;
34+
if (jsonObjectToValidate.has(Package.JSON_KEY_PROFILE)) {
35+
profileId = jsonObjectToValidate.get(Package.JSON_KEY_PROFILE).asText();
36+
3437
String[] schemes = {"http", "https"};
3538
UrlValidator urlValidator = new UrlValidator(schemes);
36-
37-
if (urlValidator.isValid(profile)) {
38-
validate(jsonObjectToValidate, new URL(profile));
39-
}else{
40-
validate(jsonObjectToValidate, profile);
39+
40+
if (urlValidator.isValid(profileId)) {
41+
errors = validate(jsonObjectToValidate, new URL(profileId));
42+
} else {
43+
errors = validate(jsonObjectToValidate, profileId);
4144
}
42-
43-
}else{
45+
} else {
4446
// If no profile value is provided, use default value.
45-
validate(jsonObjectToValidate, Profile.PROFILE_DATA_PACKAGE_DEFAULT);
46-
}
47+
errors = validate(jsonObjectToValidate, Profile.PROFILE_DATA_PACKAGE_DEFAULT);
48+
}
49+
50+
if (!errors.isEmpty()) {
51+
throw new ValidationException("Error validating Schema", "profile id: " + profileId, errors);
52+
}
4753
}
48-
54+
4955
/**
5056
* Validates a given JSON Object against the a given profile schema.
57+
*
5158
* @param jsonObjectToValidate
5259
* @param profileId
5360
* @throws DataPackageException
54-
* @throws ValidationException
61+
* @throws ValidationException
5562
*/
56-
public static void validate(JsonNode jsonObjectToValidate, String profileId) throws DataPackageException, ValidationException{
57-
63+
private static Set<ValidationMessage> validate(JsonNode jsonObjectToValidate, String profileId) throws DataPackageException {
5864
InputStream inputStream = Validator.class.getResourceAsStream("/schemas/" + profileId + ".json");
59-
if(inputStream != null){
60-
FormalSchemaValidator schema = FormalSchemaValidator.fromJson(inputStream, true);
61-
schema.validate(jsonObjectToValidate); // throws a ValidationException if this object is invalid
62-
63-
}else{
65+
if (inputStream != null) {
66+
FormalSchemaValidator schema = FormalSchemaValidator.fromJson(inputStream);
67+
Set<ValidationMessage> errors = schema.validate(jsonObjectToValidate);// throws a ValidationException if this object is invalid
68+
return errors;
69+
} else {
6470
throw new DataPackageException("Invalid profile id: " + profileId);
6571
}
66-
6772
}
68-
73+
6974
/**
70-
*
7175
* @param jsonObjectToValidate
7276
* @param schemaUrl
7377
* @throws IOException
7478
* @throws DataPackageException
75-
* @throws ValidationException
79+
* @throws ValidationException
7680
*/
77-
public static void validate(JsonNode jsonObjectToValidate, URL schemaUrl) throws IOException, DataPackageException, ValidationException{
78-
try{
81+
private static Set<ValidationMessage> validate(JsonNode jsonObjectToValidate, URL schemaUrl) throws IOException, DataPackageException {
82+
try {
7983
InputStream inputStream = schemaUrl.openStream();
80-
FormalSchemaValidator schema = FormalSchemaValidator.fromJson(inputStream, true);
81-
schema.validate(jsonObjectToValidate); // throws a ValidationException if this object is invalid
82-
83-
}catch(FileNotFoundException e){
84-
throw new DataPackageException("Invalid profile schema URL: " + schemaUrl);
85-
}
84+
FormalSchemaValidator schema = FormalSchemaValidator.fromJson(inputStream);
85+
Set<ValidationMessage> errors = schema.validate(jsonObjectToValidate);// throws a ValidationException if this object is invalid
86+
return errors;
87+
} catch (FileNotFoundException e) {
88+
throw new DataPackageException("Invalid profile schema URL: " + schemaUrl);
89+
}
8690
}
87-
91+
8892
/**
8993
* Validates a given JSON String against the default profile schema.
94+
*
9095
* @param jsonStringToValidate
9196
* @throws IOException
9297
* @throws DataPackageException
93-
* @throws ValidationException
98+
* @throws ValidationException
9499
*/
95-
public static void validate(String jsonStringToValidate) throws IOException, DataPackageException, ValidationException{
100+
public static void validate(String jsonStringToValidate) throws IOException, DataPackageException, ValidationException {
96101
JsonNode jsonObject = JsonUtil.getInstance().createNode(jsonStringToValidate);
97102
validate(jsonObject);
98103
}
@@ -104,6 +109,7 @@ public static void validate(String jsonStringToValidate) throws IOException, Dat
104109
* http or https scheme."
105110
*
106111
* https://frictionlessdata.io/specs/data-resource/#url-or-path
112+
*
107113
* @param url URL to test
108114
* @return true if the String contains a URL starting with HTTP/HTTPS
109115
*/
@@ -118,6 +124,7 @@ public static boolean isValidUrl(URL url) {
118124
* http or https scheme."
119125
*
120126
* https://frictionlessdata.io/specs/data-resource/#url-or-path
127+
*
121128
* @param objString String to test
122129
* @return true if the String contains a URL starting with HTTP/HTTPS
123130
*/

src/test/java/io/frictionlessdata/datapackage/ForeignKeysTest.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ public class ForeignKeysTest {
1414
void testValidationURLAsSchemaReference() throws Exception{
1515
Path resourcePath = TestUtil.getResourcePath("/fixtures/datapackages/foreign-keys.json");
1616
Package pkg = new Package(resourcePath, true);
17-
System.out.println(pkg);
1817
Resource teams = pkg.getResource("teams");
1918
teams.checkRelations();
2019
}

src/test/java/io/frictionlessdata/datapackage/PackageTest.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
*
4242
*/
4343
public class PackageTest {
44+
private static boolean verbose = false;
4445
private static URL validUrl;
4546
static String resource1String = "{\"name\": \"first-resource\", \"path\": " +
4647
"[\"data/cities.csv\", \"data/cities2.csv\", \"data/cities3.csv\"]}";
@@ -669,7 +670,9 @@ public void testWriteImageToFolderPackage() throws Exception{
669670
File dir = new File (tempDirPath.toFile(), "with-image");
670671
Path dirPath = Files.createDirectory(dir.toPath(), new FileAttribute[] {});
671672
pkg.write(dirPath.toFile(), false);
672-
System.out.println(tempDirPath);
673+
if (verbose) {
674+
System.out.println(tempDirPath);
675+
}
673676
File descriptor = new File (dir, "datapackage.json");
674677
String json = String.join("\n", Files.readAllLines(descriptor.toPath()));
675678
Assertions.assertFalse(json.contains("\"imageData\""));
@@ -689,7 +692,9 @@ public void testWriteImageToZipPackage() throws Exception{
689692
Package dp = new Package(createdFile.toPath(), true);
690693
dp.setImage("logo/ file.svg", fileData);
691694
dp.write(new File(tempDirPath.toFile(), "with-image.zip"), true);
692-
System.out.println(tempDirPath);
695+
if (verbose) {
696+
System.out.println(tempDirPath);
697+
}
693698
}
694699

695700

@@ -703,7 +708,9 @@ public void testWriteWithConsumer() throws Exception{
703708
File dir = new File (tempDirPath.toFile(), "test-package");
704709
Path dirPath = Files.createDirectory(dir.toPath(), new FileAttribute[] {});
705710
pkg.write(dirPath.toFile(), PackageTest::fingerprintFiles, false);
706-
System.out.println(tempDirPath);
711+
if (verbose) {
712+
System.out.println(tempDirPath);
713+
}
707714
File fingerprints = new File (dir, "fingerprints.txt");
708715
String content = String.join("\n", Files.readAllLines(fingerprints.toPath()));
709716
String refContent =
@@ -919,7 +926,6 @@ public void testBeanResource1() throws Exception {
919926
}
920927

921928
private static void fingerprintFiles(Path path) {
922-
System.out.println(path);
923929
List<String> fingerprints = new ArrayList<>();
924930
MessageDigest md;
925931
try {

0 commit comments

Comments
 (0)