Skip to content

Commit 39516e5

Browse files
authored
Add map and typedsl resolution documentation. (#96)
* Add map and typedsl resolution documentation. * Improve schema layout in spec. * Update Salad spec to mark as v1.0 instead of draft-1.
1 parent 0b76655 commit 39516e5

14 files changed

+224
-22
lines changed

schema_salad/makedoc.py

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,8 @@ def fix_doc(doc): # type: (Union[List[str], str]) -> str
158158

159159
class RenderType(object):
160160

161-
def __init__(self, toc, j, renderlist, redirects):
162-
# type: (ToC, List[Dict], str, Dict) -> None
161+
def __init__(self, toc, j, renderlist, redirects, primitiveType):
162+
# type: (ToC, List[Dict], str, Dict, str) -> None
163163
self.typedoc = StringIO()
164164
self.toc = toc
165165
self.subs = {} # type: Dict[str, str]
@@ -168,6 +168,7 @@ def __init__(self, toc, j, renderlist, redirects):
168168
self.rendered = set() # type: Set[str]
169169
self.redirects = redirects
170170
self.title = None # type: Optional[str]
171+
self.primitiveType = primitiveType
171172

172173
for t in j:
173174
if "extends" in t:
@@ -227,7 +228,6 @@ def typefmt(self,
227228
jsonldPredicate=None # type: Optional[Dict[str, str]]
228229
):
229230
# type: (...) -> Union[str, unicode]
230-
global primitiveType
231231
if isinstance(tp, list):
232232
if nbsp and len(tp) <= 3:
233233
return "&nbsp;|&nbsp;".join([self.typefmt(n, redirects, jsonldPredicate=jsonldPredicate) for n in tp])
@@ -264,7 +264,7 @@ def typefmt(self,
264264
if str(tp) in redirects:
265265
return """<a href="%s">%s</a>""" % (redirects[tp], redirects[tp])
266266
elif str(tp) in basicTypes:
267-
return """<a href="%s">%s</a>""" % (primitiveType, schema.avro_name(str(tp)))
267+
return """<a href="%s">%s</a>""" % (self.primitiveType, schema.avro_name(str(tp)))
268268
else:
269269
_, frg = urlparse.urldefrag(tp)
270270
if frg is not '':
@@ -277,6 +277,9 @@ def render_type(self, f, depth): # type: (Dict[str, Any], int) -> None
277277
return
278278
self.rendered.add(f["name"])
279279

280+
if f.get("abstract"):
281+
return
282+
280283
if "doc" not in f:
281284
f["doc"] = ""
282285

@@ -324,7 +327,7 @@ def extendsfrom(item, ex):
324327

325328
_, frg = urlparse.urldefrag(f["name"])
326329
num = self.toc.add_entry(depth, frg)
327-
doc = "## %s %s\n" % (num, frg)
330+
doc = "%s %s %s\n" % (("#" * depth), num, frg)
328331
else:
329332
doc = ""
330333

@@ -413,12 +416,12 @@ def extendsfrom(item, ex):
413416
self.render_type(self.typemap[s], depth)
414417

415418

416-
def avrold_doc(j, outdoc, renderlist, redirects, brand, brandlink):
417-
# type: (List[Dict[unicode, Any]], IO[Any], str, Dict, str, str) -> None
419+
def avrold_doc(j, outdoc, renderlist, redirects, brand, brandlink, primtype):
420+
# type: (List[Dict[unicode, Any]], IO[Any], str, Dict, str, str, str) -> None
418421
toc = ToC()
419422
toc.start_numbering = False
420423

421-
rt = RenderType(toc, j, renderlist, redirects)
424+
rt = RenderType(toc, j, renderlist, redirects, primtype)
422425
content = rt.typedoc.getvalue() # type: unicode
423426

424427
outdoc.write("""
@@ -496,8 +499,7 @@ def avrold_doc(j, outdoc, renderlist, redirects, brand, brandlink):
496499
</html>""")
497500

498501

499-
if __name__ == "__main__":
500-
502+
def main(): # type: () -> None
501503
parser = argparse.ArgumentParser()
502504
parser.add_argument("schema")
503505
parser.add_argument('--only', action='append')
@@ -526,10 +528,12 @@ def avrold_doc(j, outdoc, renderlist, redirects, brand, brandlink):
526528
s.append(j)
527529
else:
528530
raise ValueError("Schema must resolve to a list or a dict")
529-
530-
primitiveType = args.primtype
531531
redirect = {}
532532
for r in (args.redirect or []):
533533
redirect[r.split("=")[0]] = r.split("=")[1]
534534
renderlist = args.only if args.only else []
535-
avrold_doc(s, sys.stdout, renderlist, redirect, args.brand, args.brandlink)
535+
avrold_doc(s, sys.stdout, renderlist, redirect, args.brand, args.brandlink, args.primtype)
536+
537+
538+
if __name__ == "__main__":
539+
main()

schema_salad/metaschema/map_res.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
- |
2+
## Identifier maps
3+
4+
The schema may designate certain fields as having a `mapSubject`. If the
5+
value of the field is a JSON object, it must be transformed into an array of
6+
JSON objects. Each key-value pair from the source JSON object is a list
7+
item, each list item must be a JSON objects, and the value of the key is
8+
assigned to the field specified by `mapSubject`.
9+
10+
Fields which have `mapSubject` specified may also supply a `mapPredicate`.
11+
If the value of a map item is not a JSON object, the item is transformed to a
12+
JSON object with the key assigned to the field specified by `mapSubject` and
13+
the value assigned to the field specified by `mapPredicate`.
14+
15+
### Identifier map example
16+
17+
Given the following schema:
18+
19+
```
20+
- $include: map_res_schema.yml
21+
- |
22+
```
23+
24+
Process the following example:
25+
26+
```
27+
- $include: map_res_src.yml
28+
- |
29+
```
30+
31+
This becomes:
32+
33+
```
34+
- $include: map_res_proc.yml
35+
- |
36+
```
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"mapped": [
3+
{
4+
"value": "daphne",
5+
"key": "fred"
6+
},
7+
{
8+
"value": "scooby",
9+
"key": "shaggy"
10+
}
11+
]
12+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"$graph": [{
3+
"name": "MappedType",
4+
"type": "record",
5+
"documentRoot": true,
6+
"fields": [{
7+
"name": "mapped",
8+
"type": {
9+
"type": "array",
10+
"items": "ExampleRecord"
11+
},
12+
"jsonldPredicate": {
13+
"mapSubject": "key",
14+
"mapPredicate": "value"
15+
}
16+
}],
17+
},
18+
{
19+
"name": "ExampleRecord",
20+
"type": "record",
21+
"fields": [{
22+
"name": "key",
23+
"type": "string"
24+
}, {
25+
"name": "value",
26+
"type": "string"
27+
}
28+
]
29+
}]
30+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"mapped": {
3+
"shaggy": {
4+
"value": "scooby"
5+
},
6+
"fred": "daphne"
7+
}
8+
}

schema_salad/metaschema/metaschema.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ $graph:
1818
- $import: link_res.yml
1919
- $import: vocab_res.yml
2020
- $include: import_include.md
21+
- $import: map_res.yml
22+
- $import: typedsl_res.yml
2123

2224
- name: "Link_Validation"
2325
type: documentation
@@ -154,6 +156,7 @@ $graph:
154156
- name: NamedType
155157
type: record
156158
abstract: true
159+
docParent: "#Schema"
157160
fields:
158161
- name: name
159162
type: string
@@ -164,6 +167,7 @@ $graph:
164167
- name: DocType
165168
type: record
166169
abstract: true
170+
docParent: "#Schema"
167171
fields:
168172
- name: doc
169173
type:
@@ -240,6 +244,7 @@ $graph:
240244

241245

242246
- name: SaladRecordSchema
247+
docParent: "#Schema"
243248
type: record
244249
extends: [NamedType, RecordSchema, SchemaDefinedType]
245250
documentRoot: true
@@ -277,6 +282,7 @@ $graph:
277282
mapPredicate: specializeTo
278283

279284
- name: SaladEnumSchema
285+
docParent: "#Schema"
280286
type: record
281287
extends: [EnumSchema, SchemaDefinedType]
282288
documentRoot: true
@@ -297,6 +303,7 @@ $graph:
297303
298304
- name: Documentation
299305
type: record
306+
docParent: "#Schema"
300307
extends: [NamedType, DocType]
301308
documentRoot: true
302309
doc: |

schema_salad/metaschema/metaschema_base.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ $namespaces:
88
xsd: "http://www.w3.org/2001/XMLSchema#"
99

1010
$graph:
11+
12+
- name: "Schema"
13+
type: documentation
14+
doc: |
15+
# Schema
16+
1117
- name: PrimitiveType
1218
type: enum
1319
symbols:
@@ -35,6 +41,7 @@ $graph:
3541
- name: Any
3642
type: enum
3743
symbols: ["#Any"]
44+
docAfter: "#PrimitiveType"
3845
doc: |
3946
The **Any** type validates for any non-null value.
4047

schema_salad/metaschema/salad.md

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Web.
2626

2727
This document is the product of the [Common Workflow Language working
2828
group](https://groups.google.com/forum/#!forum/common-workflow-language). The
29-
latest version of this document is available in the "schema_salad" directory at
29+
latest version of this document is available in the "schema_salad" repository at
3030

3131
https://github.com/common-workflow-language/schema_salad
3232

@@ -38,7 +38,7 @@ under the terms of the Apache License, version 2.0.
3838
# Introduction
3939

4040
The JSON data model is an extremely popular way to represent structured
41-
data. It is attractive because of it's relative simplicity and is a
41+
data. It is attractive because of its relative simplicity and is a
4242
natural fit with the standard types of many programming languages.
4343
However, this simplicity means that basic JSON lacks expressive features
4444
useful for working with complex data structures and document formats, such
@@ -70,12 +70,17 @@ and RDF schema, and production of RDF triples by applying the JSON-LD
7070
context. The schema language also provides for robust support of inline
7171
documentation.
7272

73-
## Introduction to draft 1
73+
## Introduction to v1.0
7474

75-
This is the first version of Schema Salad. It is developed concurrently
76-
with draft 3 of the Common Workflow Language for use in specifying the
77-
Common Workflow Language, however Schema Salad is intended to be useful to
78-
a broader audience.
75+
This is the second version of of the Schema Salad specification. It is
76+
developed concurrently with v1.0 of the Common Workflow Language for use in
77+
specifying the Common Workflow Language, however Schema Salad is intended to be
78+
useful to a broader audience. Compared to the draft-1 schema salad
79+
specification, the following changes have been made:
80+
81+
* Use of [mapSubject and mapPredicate](#Identifier_maps) to transform maps to lists of records.
82+
* Resolution of the [domain Specific Language for types](#Domain_Specific_Language_for_types)
83+
* Consolidation of the formal [schema into section 5](#Schema).
7984

8085
## References to Other Specifications
8186

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
- |
2+
## Domain Specific Language for types
3+
4+
Fields may be tagged `typeDSL: true`. If so, the field is expanded using the
5+
following micro-DSL for schema salad types:
6+
7+
* If the type ends with a question mark `?` it is expanded to a union with `null`
8+
* If the type ends with square brackets `[]` it is expanded to an array with items of the preceeding type symbol
9+
* The type may end with both `[]?` to indicate it is an optional array.
10+
* Identifier resolution is applied after type DSL expansion.
11+
12+
### Type DSL example
13+
14+
Given the following schema:
15+
16+
```
17+
- $include: typedsl_res_schema.yml
18+
- |
19+
```
20+
21+
Process the following example:
22+
23+
```
24+
- $include: typedsl_res_src.yml
25+
- |
26+
```
27+
28+
This becomes:
29+
30+
```
31+
- $include: typedsl_res_proc.yml
32+
- |
33+
```
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
[
2+
{
3+
"extype": "string"
4+
},
5+
{
6+
"extype": [
7+
"null",
8+
"string"
9+
]
10+
},
11+
{
12+
"extype": {
13+
"type": "array",
14+
"items": "string"
15+
}
16+
},
17+
{
18+
"extype": [
19+
"null",
20+
{
21+
"type": "array",
22+
"items": "string"
23+
}
24+
]
25+
}
26+
]
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"$graph": [
3+
{"$import": "metaschema_base.yml"},
4+
{
5+
"name": "TypeDSLExample",
6+
"type": "record",
7+
"documentRoot": true,
8+
"fields": [{
9+
"name": "extype",
10+
"type": "string",
11+
"jsonldPredicate": {
12+
_type: "@vocab",
13+
"typeDSL": true
14+
}
15+
}]
16+
}]
17+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[{
2+
"extype": "string"
3+
}, {
4+
"extype": "string?"
5+
}, {
6+
"extype": "string[]"
7+
}, {
8+
"extype": "string[]?"
9+
}]

0 commit comments

Comments
 (0)