|
5 | 5 | [org.everit.json.schema.loader |
6 | 6 | SchemaLoader SchemaClient SchemaLoader$SchemaLoaderBuilder] |
7 | 7 | [org.everit.json.schema Schema] |
8 | | - [org.everit.json.schema ValidationException])) |
| 8 | + [org.everit.json.schema ValidationException] |
| 9 | + [org.everit.json.schema FormatValidator] |
| 10 | + [java.util Optional])) |
9 | 11 |
|
10 | 12 | (defn- ^JSONTokener prepare-tokener |
11 | 13 | "Prepares a JSONTokener instance for further processing" |
|
37 | 39 | (when-not is-input-valid? |
38 | 40 | (throw (ex-info "Unsupported Schema input" {:input input}))))) |
39 | 41 |
|
| 42 | +(defn- format-validator [key validation-fn] |
| 43 | + (reify FormatValidator |
| 44 | + (formatName [_] key) |
| 45 | + (validate [_ value] |
| 46 | + (if-let [validation-error-message (validation-fn value)] |
| 47 | + (Optional/of validation-error-message) |
| 48 | + (Optional/empty))))) |
| 49 | + |
40 | 50 | (defn ^JSONObject prepare-schema* |
41 | 51 | "Prepares JSON Schema based on input string or map. An optional parameter map |
42 | 52 | can be supplied to refer to relative file schemas via classpath in $ref fields. |
43 | 53 |
|
| 54 | + Setting :format-validators to map of format name and validation function adds |
| 55 | + them as custom format validators. |
| 56 | + Validator takes value and returns validation error message or nil if success |
| 57 | + (prepare-schema* input { |
| 58 | + :format-validators {\"uuid\" (fn [value] |
| 59 | + (when-not (uuid? (parse-uuid value)) |
| 60 | + (format \"[%s] is not a valid UUID value\" value)))}}) |
| 61 | +
|
44 | 62 | Setting :classpath-aware? to true enables absolute classpath resolution. |
45 | 63 | (prepare-schema* input {:classpath-aware? true}) |
46 | 64 |
|
|
54 | 72 | (SchemaLoader/load (JSONObject. (prepare-tokener input)))) |
55 | 73 | ([input params] |
56 | 74 | (assert-schema-input-valid! input) |
57 | | - (if-not (:classpath-aware? params) |
58 | | - (prepare-schema* input) |
59 | | - (let [resolution-scope (:default-resolution-scope params) |
60 | | - set-resolution-scope (fn [^SchemaLoader$SchemaLoaderBuilder builder] |
61 | | - (if resolution-scope |
62 | | - (.resolutionScope builder ^String resolution-scope) |
63 | | - builder)) |
64 | | - schema-loader (-> (SchemaLoader/builder) |
65 | | - (.schemaClient (SchemaClient/classPathAwareClient)) |
66 | | - ^SchemaLoader$SchemaLoaderBuilder (set-resolution-scope) |
67 | | - (.schemaJson |
68 | | - ^JSONObject (JSONObject. (prepare-tokener input))) |
69 | | - (.build))] |
70 | | - (.build (.load schema-loader)))))) |
| 75 | + (let [set-format-validators (fn [^SchemaLoader$SchemaLoaderBuilder builder] |
| 76 | + (doseq [[k validation-fn] (:format-validators params)] |
| 77 | + (.addFormatValidator builder (format-validator k validation-fn))) |
| 78 | + builder)] |
| 79 | + (if-not (:classpath-aware? params) |
| 80 | + (.build (.load (-> (SchemaLoader/builder) |
| 81 | + ^SchemaLoader$SchemaLoaderBuilder (set-format-validators) |
| 82 | + (.schemaJson ^JSONObject (JSONObject. (prepare-tokener input))) |
| 83 | + (.build)))) |
| 84 | + (let [resolution-scope (:default-resolution-scope params) |
| 85 | + set-resolution-scope (fn [^SchemaLoader$SchemaLoaderBuilder builder] |
| 86 | + (if resolution-scope |
| 87 | + (.resolutionScope builder ^String resolution-scope) |
| 88 | + builder)) |
| 89 | + schema-loader (-> (SchemaLoader/builder) |
| 90 | + (.schemaClient (SchemaClient/classPathAwareClient)) |
| 91 | + ^SchemaLoader$SchemaLoaderBuilder (set-resolution-scope) |
| 92 | + ^SchemaLoader$SchemaLoaderBuilder (set-format-validators) |
| 93 | + (.schemaJson ^JSONObject (JSONObject. (prepare-tokener input))) |
| 94 | + (.build))] |
| 95 | + (.build (.load schema-loader))))))) |
71 | 96 |
|
72 | 97 | (def ^JSONObject prepare-schema (memoize prepare-schema*)) |
73 | 98 |
|
|
0 commit comments