Skip to content

Commit 6efe743

Browse files
ryanjdewkkanthet
authored andcommitted
DHFPROD-1891 Create JSON/XML schema to validate against entity instances (#1910)
1 parent 91e5832 commit 6efe743

File tree

3 files changed

+77
-0
lines changed

3 files changed

+77
-0
lines changed

marklogic-data-hub/src/main/resources/ml-modules/root/data-hub/4/impl/hub-entities.xqy

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,3 +300,60 @@ declare function hent:fix-tde($nodes as node()*, $entity-model-contexts as xs:st
300300
)
301301
default return $n
302302
};
303+
304+
declare variable $number-types as xs:string+ := ("byte","decimal","double","float","int","integer","long","negativeInteger","nonNegativeInteger","nonPositiveInteger","positiveInteger","short","unsignedLong","unsignedInt","unsignedShort","unsignedByte");
305+
declare variable $string-types as xs:string+ := "dateTime";
306+
307+
declare function hent:json-schema-generate($entity-title as xs:string, $uber-model as map:map)
308+
{
309+
let $uber-model := map:new((
310+
(: Ensure we're not change a map for anyone else :)
311+
map:map(document{$uber-model}/*),
312+
map:entry("language", "zxx"),
313+
map:entry("$schema", "http://json-schema.org/draft-07/schema#")
314+
))
315+
let $definitions := $uber-model => map:get("definitions")
316+
(: JSON Schema needs an extra level of wrapping to account for Entity Model label wrapping it. :)
317+
let $_nest-refs :=
318+
for $definition-type in map:keys($definitions)
319+
let $definition-properties := $definitions => map:get($definition-type) => map:get("properties")
320+
for $property-name in map:keys($definition-properties)
321+
let $property := $definition-properties => map:get($property-name)
322+
let $property-items := $property => map:get("items")
323+
let $datatype := $property => map:get("datatype")
324+
let $_set-types := (
325+
$property => map:put("type", if ($datatype = $number-types) then "number" else if ($datatype = $string-types) then "string" else $datatype),
326+
$property => map:delete("datatype"),
327+
if ($property-items instance of map:map) then (
328+
let $items-datatype := $property => map:get("datatype")
329+
return (
330+
$property-items => map:put("type", if ($items-datatype = $number-types) then "number" else if ($items-datatype = $string-types) then "string" else $datatype),
331+
$property-items => map:delete("datatype"))
332+
) else ()
333+
)
334+
return
335+
(: references can be in the property or in items for arrays :)
336+
if ($property => map:contains("$ref")) then
337+
map:put($definition-properties, $property-name,
338+
map:new((
339+
map:entry("type", "object"),
340+
map:entry("properties",
341+
map:entry(fn:tokenize(map:get($property,"$ref"),"/")[fn:last()], $property)
342+
)
343+
))
344+
)
345+
else if ($property-items instance of map:map and $property-items => map:contains("$ref")) then
346+
map:put($property, "items",
347+
map:new((
348+
map:entry("type", "object"),
349+
map:entry("properties",
350+
map:entry(fn:tokenize(map:get($property-items,"$ref"),"/")[fn:last()], $property-items)
351+
)
352+
))
353+
)
354+
else ()
355+
let $_set-info := (
356+
$uber-model => map:put("properties", map:entry($entity-title, map:entry("$ref", "#/definitions/"||$entity-title)))
357+
)
358+
return xdmp:to-json($uber-model)
359+
};

marklogic-data-hub/src/main/resources/ml-modules/root/data-hub/4/triggers/entity-model-delete-trigger.xqy

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ let $entity-def := fn:doc($trgr:uri)
1515
let $entity-title := $entity-def/info/title
1616
let $entity-version := $entity-def/info/version
1717
let $tde-uri := "/tde/" || $entity-title || "-" || $entity-version || ".tdex"
18+
let $schema-xml-uri := fn:replace($trgr:uri, "\.json$", ".xsd")
19+
let $schema-json-uri := fn:replace($trgr:uri, "\.json$", ".schema.json")
1820
return (
1921
xdmp:invoke-function(
2022
function() {
@@ -23,6 +25,12 @@ return (
2325
else (),
2426
if (fn:doc-available($tde-uri)) then
2527
xdmp:document-delete($tde-uri)
28+
else (),
29+
if (fn:doc-available($schema-xml-uri)) then
30+
xdmp:document-delete($schema-xml-uri)
31+
else (),
32+
if (fn:doc-available($schema-json-uri)) then
33+
xdmp:document-delete($schema-json-uri)
2634
else ()
2735
}, map:entry("database", xdmp:schema-database())
2836
)

marklogic-data-hub/src/main/resources/ml-modules/root/data-hub/4/triggers/entity-model-trigger.xqy

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,18 @@ return (
9292
(: Insert entity model into SCHEMA db :)
9393
xdmp:invoke-function(
9494
function() {
95+
xdmp:document-insert(
96+
fn:replace($trgr:uri, "\.json$", ".xsd"),
97+
es:schema-generate($uber-model),
98+
$default-permissions,
99+
"ml-data-hub-xml-schema"
100+
),
101+
xdmp:document-insert(
102+
fn:replace($trgr:uri, "\.json$", ".schema.json"),
103+
hent:json-schema-generate($entity-title, $uber-model),
104+
$default-permissions,
105+
"ml-data-hub-json-schema"
106+
),
95107
xdmp:document-insert(
96108
$trgr:uri,
97109
$valid-entity-model,

0 commit comments

Comments
 (0)