Skip to content

Commit cb51521

Browse files
committed
version of PR !244 that uses curies
1 parent 46e3f6d commit cb51521

File tree

5 files changed

+364
-320
lines changed

5 files changed

+364
-320
lines changed
+66-25
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,81 @@
11
from logging import warning
2-
from typing import Optional, Union, Dict
2+
from typing import Optional, Union, Dict, List
33

44
from rdflib import Namespace, URIRef
5+
from curies import Converter, Record
6+
7+
class CurieNamespaceCatalog(object):
8+
catalog: Dict[str, "CurieNamespace"]
9+
def __init__(self) -> None:
10+
self.namespaces = []
11+
self._converter: Optional[Converter] = None
12+
13+
@property
14+
def converter(self):
15+
if not self._converter:
16+
self._converter = self._buildConverter()
17+
return self._converter
18+
19+
def _buildConverter(self):
20+
records = []
21+
namespaces_to_treat = self.namespaces[:]
22+
while len(namespaces_to_treat) > 0:
23+
ns = namespaces_to_treat.pop(0)
24+
prefix = ns.prefix
25+
uri = str(ns)
26+
all_prefixes = [prefix]
27+
all_uris = [uri]
28+
iteration_needed = True
29+
while iteration_needed:
30+
iteration_needed = False
31+
for possible_synonym in namespaces_to_treat[:]:
32+
if possible_synonym.prefix in all_prefixes:
33+
all_uris.append(str(possible_synonym))
34+
namespaces_to_treat.remove(possible_synonym)
35+
iteration_needed = True
36+
if str(possible_synonym) in all_uris:
37+
all_prefixes.append(possible_synonym.prefix)
38+
namespaces_to_treat.remove(possible_synonym)
39+
iteration_needed = True
40+
records.append(Record(prefix, uri , [x for x in all_prefixes if not x == prefix], [x for x in all_uris if not x == uri]))
41+
return Converter(records=records)
542

643

7-
class CurieNamespace(Namespace):
8-
# We would prefer to use curies.Converter here, but there doesn't appear to be any way to build it incrementally
9-
catalog: Dict[str, "CurieNamespace"] = dict()
1044

11-
@classmethod
12-
def to_curie(cls, uri: Union[str, URIRef]) -> str:
13-
uri = str(uri)
14-
candidate_ns = ""
15-
for prefix, ns in cls.catalog.items():
16-
if uri.startswith(ns) and len(ns) > len(candidate_ns):
17-
candidate_ns = ns
18-
if candidate_ns:
19-
return candidate_ns.curie(uri[len(candidate_ns):])
20-
return None
2145

46+
def to_curie(self, uri: Union[str, URIRef]) -> str:
47+
return self.converter.compress(uri)
48+
49+
def to_uri(self, curie: str) -> Optional[URIRef]:
50+
expanded = self.converter.expand(curie)
51+
return None if expanded is None else URIRef(expanded)
52+
53+
def add_namespace(self,ns: "CurieNamespace"):
54+
self.namespaces.append(ns)
55+
self._converter = None
56+
2257
@classmethod
23-
def to_uri(cls, curie: str) -> Optional[URIRef]:
24-
prefix, localname = curie.split(':', 1)
25-
ns = CurieNamespace.catalog.get(prefix, None)
26-
return ns[localname] if ns else None
58+
def create(cls, *namespaces: List["CurieNamespace"]):
59+
cat = CurieNamespaceCatalog()
60+
[cat.add_namespace(x) for x in namespaces]
61+
return cat
62+
63+
def clear(self):
64+
self.catalog = dict()
65+
66+
def as_dict(self):
67+
return self.catalog.copy()
68+
2769

28-
def __new__(cls, prefix: str, ns: Union[str, bytes, URIRef]) -> "CurieNamespace":
70+
class CurieNamespace(Namespace):
71+
def __new__(cls, prefix: str, ns: Union[str, URIRef]):
2972
rt = Namespace.__new__(cls, str(ns) if not isinstance(ns, bytes) else ns)
3073
rt.prefix = prefix
31-
if prefix in CurieNamespace.catalog:
32-
if CurieNamespace.catalog[prefix] != str(rt):
33-
# prefix is bound to a different namespace
34-
warning(f"Prefix: {prefix} already references {CurieNamespace.catalog[prefix]} - not updated to {rt}")
35-
else:
36-
CurieNamespace.catalog[prefix] = rt
3774
return rt
3875

3976
def curie(self, reference: Optional[str] = '') -> str:
4077
return self.prefix + ':' + reference
78+
79+
def addTo(self, catalog: CurieNamespaceCatalog) -> "CurieNamespace":
80+
catalog.add_namespace(self)
81+
return self

0 commit comments

Comments
 (0)