11package io .frictionlessdata .datapackage ;
22
33import com .fasterxml .jackson .databind .JsonNode ;
4+ import com .networknt .schema .ValidationMessage ;
45import io .frictionlessdata .datapackage .exceptions .DataPackageException ;
56import io .frictionlessdata .tableschema .exception .ValidationException ;
67import io .frictionlessdata .tableschema .schema .FormalSchemaValidator ;
1112import java .io .IOException ;
1213import java .io .InputStream ;
1314import 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 */
1920public 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 */
0 commit comments