aboutsummaryrefslogtreecommitdiffstats
path: root/bsfs/namespace
diff options
context:
space:
mode:
Diffstat (limited to 'bsfs/namespace')
-rw-r--r--bsfs/namespace/__init__.py21
-rw-r--r--bsfs/namespace/namespace.py104
-rw-r--r--bsfs/namespace/predefined.py39
3 files changed, 164 insertions, 0 deletions
diff --git a/bsfs/namespace/__init__.py b/bsfs/namespace/__init__.py
new file mode 100644
index 0000000..98d472f
--- /dev/null
+++ b/bsfs/namespace/__init__.py
@@ -0,0 +1,21 @@
+"""
+
+Part of the BlackStar filesystem (bsfs) module.
+A copy of the license is provided with the project.
+Author: Matthias Baumgartner, 2022
+"""
+# imports
+import typing
+
+# inner-module imports
+from . import predefined as ns
+from .namespace import ClosedNamespace, Namespace
+
+# exports
+__all__: typing.Sequence[str] = (
+ 'ClosedNamespace',
+ 'Namespace',
+ 'ns',
+ )
+
+## EOF ##
diff --git a/bsfs/namespace/namespace.py b/bsfs/namespace/namespace.py
new file mode 100644
index 0000000..f652dcd
--- /dev/null
+++ b/bsfs/namespace/namespace.py
@@ -0,0 +1,104 @@
+"""
+
+Part of the BlackStar filesystem (bsfs) module.
+A copy of the license is provided with the project.
+Author: Matthias Baumgartner, 2022
+"""
+# imports
+import typing
+
+# bsfs imports
+from bsfs.utils import URI, typename
+
+# exports
+__all__: typing.Sequence[str] = (
+ 'ClosedNamespace',
+ 'Namespace',
+ )
+
+
+## code ##
+
+class Namespace():
+ """A namespace consists of a common prefix that is used in a set of URIs.
+
+ Note that the prefix must include the separator between
+ path and fragment (typically a '#' or a '/').
+ """
+
+ # namespace prefix.
+ prefix: URI
+
+ # fragment separator.
+ fsep: str
+
+ # path separator.
+ psep: str
+
+ def __init__(self, prefix: URI, fsep: str = '#', psep: str = '/'):
+ # ensure prefix type
+ prefix = URI(prefix)
+ # truncate fragment separator
+ while prefix.endswith(fsep):
+ prefix = URI(prefix[:-1])
+ # truncate path separator
+ while prefix.endswith(psep):
+ prefix = URI(prefix[:-1])
+ # store members
+ self.prefix = prefix
+ self.fsep = fsep
+ self.psep = psep
+
+ def __eq__(self, other: typing.Any) -> bool:
+ return isinstance(other, type(self)) \
+ and self.prefix == other.prefix \
+ and self.fsep == other.fsep \
+ and self.psep == other.psep
+
+ def __hash__(self) -> int:
+ return hash((type(self), self.prefix, self.fsep, self.psep))
+
+ def __str__(self) -> str:
+ return f'{typename(self)}({self.prefix})'
+
+ def __repr__(self) -> str:
+ return f'{typename(self)}({self.prefix}, {self.fsep}, {self.psep})'
+
+ def __getattr__(self, fragment: str) -> URI:
+ """Return prefix + fragment."""
+ return URI(self.prefix + self.fsep + fragment)
+
+ def __getitem__(self, fragment: str) -> URI:
+ """Alias for getattr(self, fragment)."""
+ return self.__getattr__(fragment)
+
+ def __add__(self, value: typing.Any) -> 'Namespace':
+ """Concatenate another namespace to this one."""
+ if not isinstance(value, str):
+ return NotImplemented
+ return Namespace(self.prefix + self.psep + value, self.fsep, self.psep)
+
+
+class ClosedNamespace(Namespace):
+ """Namespace that covers a restricted set of URIs."""
+
+ # set of permissible fragments.
+ fragments: typing.Set[str]
+
+ def __init__(self, prefix: URI, *args: str, fsep: str = '#', psep: str = '/'):
+ super().__init__(prefix, fsep, psep)
+ self.fragments = set(args)
+
+ def __eq__(self, other: typing.Any) -> bool:
+ return super().__eq__(other) and self.fragments == other.fragments
+
+ def __hash__(self) -> int:
+ return hash((type(self), self.prefix, tuple(sorted(self.fragments))))
+
+ def __getattr__(self, fragment: str) -> URI:
+ """Return prefix + fragment or raise a KeyError if the fragment is not part of this namespace."""
+ if fragment not in self.fragments:
+ raise KeyError(f'{fragment} is not a valid fragment of namespace {self.prefix}')
+ return super().__getattr__(fragment)
+
+## EOF ##
diff --git a/bsfs/namespace/predefined.py b/bsfs/namespace/predefined.py
new file mode 100644
index 0000000..cd48a46
--- /dev/null
+++ b/bsfs/namespace/predefined.py
@@ -0,0 +1,39 @@
+"""
+
+Part of the BlackStar filesystem (bsfs) module.
+A copy of the license is provided with the project.
+Author: Matthias Baumgartner, 2022
+"""
+# imports
+import typing
+
+# bsfs imports
+from bsfs.utils import URI
+
+# inner-module imports
+from . import namespace
+
+# essential bsfs namespaces
+bsfs: namespace.Namespace = namespace.Namespace(URI('http://bsfs.ai/schema'), fsep='/')
+
+# additional bsfs namespaces
+bse: namespace.Namespace = namespace.Namespace(URI('http://bsfs.ai/schema/Entity'))
+bsm: namespace.Namespace = namespace.Namespace(URI('http://bsfs.ai/schema/Meta'))
+
+# generic namespaces
+rdf: namespace.Namespace = namespace.Namespace(URI('http://www.w3.org/1999/02/22-rdf-syntax-ns'))
+rdfs: namespace.Namespace = namespace.Namespace(URI('http://www.w3.org/2000/01/rdf-schema'))
+schema: namespace.Namespace = namespace.Namespace(URI('http://schema.org'), fsep='/')
+xsd: namespace.Namespace = namespace.Namespace(URI('http://www.w3.org/2001/XMLSchema'))
+
+__all__: typing.Sequence[str] = (
+ 'bse',
+ 'bsfs',
+ 'bsm',
+ 'rdf',
+ 'rdfs',
+ 'schema',
+ 'xsd',
+ )
+
+## EOF ##