|
| 1 | +import json |
| 2 | +from hypermedia_resource.base import HypermediaResource |
| 3 | + |
| 4 | +RESERVED_ATTRIBUTES = ["_links", "_embedded"] |
| 5 | + |
| 6 | +def parse_attributes(hal_rep, resource): |
| 7 | + attrs = [[key, value] for key, value in hal_rep.items() |
| 8 | + if key not in RESERVED_ATTRIBUTES] |
| 9 | + for attr in attrs: |
| 10 | + resource.attributes.add(attr[0], attr[1]) |
| 11 | + |
| 12 | +def parse_link(rel, link, resource): |
| 13 | + if "templated" in link and link["templated"]: |
| 14 | + return |
| 15 | + if (link.has_key("method") and link["method"] != "GET"): |
| 16 | + resource = resource.actions.add(rel, link["href"], link["method"]) |
| 17 | + else: |
| 18 | + resource = resource.links.add(rel=rel, href=link["href"]) |
| 19 | + if link.has_key("request_encoding"): |
| 20 | + resource.response_types.add(link["request_encoding"]) |
| 21 | + if link.has_key("data"): |
| 22 | + # Right now, it only supports name and values |
| 23 | + for name, value in link["data"].items(): |
| 24 | + attr = resource.attributes.add(name) |
| 25 | + if value.has_key("options"): |
| 26 | + for option in value["options"]: |
| 27 | + attr.options.add(option, option) |
| 28 | + return resource |
| 29 | + |
| 30 | +def parse_links(hal_rep, resource): |
| 31 | + if not "_links" in hal_rep or not hal_rep["_links"]: |
| 32 | + return |
| 33 | + for rel, link in hal_rep["_links"].items(): |
| 34 | + if type(link) is dict: |
| 35 | + parse_link(rel, link, resource) |
| 36 | + else: |
| 37 | + for item in link: |
| 38 | + parse_link(rel, item, resource) |
| 39 | + |
| 40 | +def parse_embedded(rel, embedded, resource): |
| 41 | + href = embedded["_links"]["self"] |
| 42 | + item = resource.embedded_resources.add(rel, href) |
| 43 | + parse_attributes(embedded, item) |
| 44 | + parse_links(embedded, item) |
| 45 | + parse_embeddeds(embedded, item) |
| 46 | + return item |
| 47 | + |
| 48 | +def parse_embeddeds(hal_rep, resource): |
| 49 | + if not "_embedded" in hal_rep or not hal_rep["_embedded"]: |
| 50 | + return |
| 51 | + for rel, link in hal_rep["_embedded"].items(): |
| 52 | + if type(link) is dict: |
| 53 | + parse_embedded(rel, link, resource) |
| 54 | + else: |
| 55 | + for item in link: |
| 56 | + parse_embedded(rel, item, resource) |
| 57 | + |
| 58 | +class HaleJSONAdapter(object): |
| 59 | + |
| 60 | + media_type = "application/vnd.hale+json" |
| 61 | + |
| 62 | + @classmethod |
| 63 | + def parse(self, raw_json): |
| 64 | + hal_rep = json.loads(raw_json) |
| 65 | + resource = HypermediaResource() |
| 66 | + parse_attributes(hal_rep, resource) |
| 67 | + parse_links(hal_rep, resource) |
| 68 | + parse_embeddeds(hal_rep, resource) |
| 69 | + return resource |
0 commit comments