Skip to content

Commit 4ef52be

Browse files
author
Peter Amstutz
committed
Improve documentation. Add feature of skipping some inner scopes.
1 parent c6d4a7b commit 4ef52be

File tree

3 files changed

+36
-17
lines changed

3 files changed

+36
-17
lines changed

schema_salad/metaschema/metaschema.yml

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -144,12 +144,18 @@ $graph:
144144
- "null"
145145
- int
146146
doc: |
147-
Remove the specified number of layers from the containing identifer
148-
scope and join with the field value to yield the identifier. For
149-
example, an identifer scope of `#foo/bar/baz`, `refScope: 0` and
150-
identifier `quux` will yield `#foo/bar/baz/quux`. `refScope: 1` will
151-
yield `#foo/bar/quux`, `refScope: 2` will yield `#foo/quux` and so
152-
forth.
147+
If the field contains a relative reference, it must be resolved by
148+
searching for valid document references in each successive parent scope
149+
in the document fragment. For example, a reference of `foo` in the
150+
context `#foo/bar/baz` will first check for the existence of
151+
`#foo/bar/baz/foo`, followed by `#foo/bar/foo`, then `#foo/foo` and
152+
then finally `#foo`. The first valid URI in the search order shall be
153+
used as the fully resolved value of the identifier. The value of the
154+
refScope field is the specified number of levels from the containing
155+
identifer scope before starting the search, so if `refScope: 2` then
156+
"baz" and "bar" must be stripped to get the base `#foo` and search
157+
`#foo/foo` and the `#foo`. The last scope searched must be the top
158+
level scope before determining if the identifier cannot be resolved.
153159
154160
- name: SpecializeDef
155161
type: record

schema_salad/ref_resolver.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ def add_context(self, newcontext, baseuri=""):
208208
self.identity_links.add(key)
209209
elif isinstance(value, dict) and value.get("@type") == "@id":
210210
self.url_fields.add(key)
211-
if value.get("refScope", False):
211+
if "refScope" in value:
212212
self.scoped_ref_fields[key] = value["refScope"]
213213
if value.get("identity", False):
214214
self.identity_links.add(key)
@@ -548,16 +548,14 @@ def validate_link(self, field, link, docid):
548548
if field in self.scoped_ref_fields:
549549
split = urlparse.urlsplit(docid)
550550
sp = split.fragment.split("/")
551-
print field, self.scoped_ref_fields[field], sp
552-
if self.scoped_ref_fields[field] in ("grandparent"):
553-
sp.pop()
554-
if self.scoped_ref_fields[field] in ("parent", "grandparent"):
551+
n = self.scoped_ref_fields[field]
552+
while n > 0 and len(sp) > 0:
555553
sp.pop()
554+
n -= 1
556555
while True:
557556
sp.append(str(link))
558557
url = urlparse.urlunsplit(
559558
(split.scheme, split.netloc, split.path, split.query, "/".join(sp)))
560-
print "trying", url, "field", field
561559
if url in self.idx:
562560
return url
563561
sp.pop()

tests/test_examples.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,9 @@ def test_scoped_ref(self):
129129
"mapSubject": "id",
130130
"mapPredicate": "type"
131131
},
132+
"outputs": {
133+
"mapSubject": "id",
134+
},
132135
"steps": {
133136
"mapSubject": "id"
134137
},
@@ -138,6 +141,12 @@ def test_scoped_ref(self):
138141
"inputs": {
139142
"inp": "string"
140143
},
144+
"outputs": {
145+
"out": {
146+
"type": "string",
147+
"source": "step2/out"
148+
}
149+
},
141150
"steps": {
142151
"step1": {
143152
"in": {
@@ -150,17 +159,22 @@ def test_scoped_ref(self):
150159
"in": {
151160
"inp": "step1/out"
152161
},
153-
"scatter": "inp"
162+
"scatter": "inp",
163+
"out": ["out"]
154164
}
155165
}
156166
}, "http://example2.com/")
157167

158-
print yaml.dump(ra)
159-
160-
self.assertEquals({'inputs': [{
168+
self.assertEquals(
169+
{'inputs': [{
161170
'id': 'http://example2.com/#inp',
162171
'type': 'string'
163172
}],
173+
'outputs': [{
174+
'id': 'http://example2.com/#out',
175+
'type': 'string',
176+
'source': 'http://example2.com/#step2/out'
177+
}],
164178
'steps': [{
165179
'id': 'http://example2.com/#step1',
166180
'scatter': 'http://example2.com/#step1/inp',
@@ -175,7 +189,8 @@ def test_scoped_ref(self):
175189
'in': [{
176190
'id': 'http://example2.com/#step2/inp',
177191
'source': 'http://example2.com/#step1/out'
178-
}]
192+
}],
193+
"out": ["http://example2.com/#step2/out"],
179194
}]
180195
}, ra)
181196

0 commit comments

Comments
 (0)