Source code for prov.identifier
__author__ = "Trung Dong Huynh"
__email__ = "trungdong@donggiang.com"
[docs]class Identifier(object):
"""Base class for all identifiers and also represents xsd:anyURI."""
# TODO: make Identifier an "abstract" base class and move xsd:anyURI
# into a subclass
def __init__(self, uri):
"""
Constructor.
:param uri: URI string for the long namespace identifier.
"""
self._uri = str(uri) # Ensure this is a unicode string
@property
def uri(self):
"""Identifier's URI."""
return self._uri
def __str__(self):
return self._uri
def __eq__(self, other):
return self.uri == other.uri if isinstance(other, Identifier) else False
def __hash__(self):
return hash((self.uri, self.__class__))
def __repr__(self):
return "<%s: %s>" % (self.__class__.__name__, self._uri)
[docs] def provn_representation(self):
"""PROV-N representation of qualified name in a string."""
return '"%s" %%%% xsd:anyURI' % self._uri
[docs]class QualifiedName(Identifier):
"""Qualified name of an identifier in a particular namespace."""
def __init__(self, namespace, localpart):
"""
Constructor.
:param namespace: Namespace to use for qualified name resolution.
:param localpart: Portion of identifier not part of the namespace prefix.
"""
Identifier.__init__(self, "".join([namespace.uri, localpart]))
self._namespace = namespace
self._localpart = localpart
self._str = (
":".join([namespace.prefix, localpart]) if namespace.prefix else localpart
)
@property
def namespace(self):
"""Namespace of qualified name."""
return self._namespace
@property
def localpart(self):
"""Local part of qualified name."""
return self._localpart
def __str__(self):
return self._str
def __repr__(self):
return "<%s: %s>" % (self.__class__.__name__, self._str)
def __hash__(self):
return hash(self.uri)
[docs] def provn_representation(self):
"""PROV-N representation of qualified name in a string."""
return "'%s'" % self._str
[docs]class Namespace(object):
"""PROV Namespace."""
def __init__(self, prefix: str, uri: str):
"""
Constructor.
:param prefix: String short hand prefix for the namespace.
:param uri: URI string for the long namespace identifier (cannot be blank).
"""
if not uri or uri.isspace():
raise ValueError("Not a valid URI to create a namespace.")
self._prefix = prefix
self._uri = uri
self._cache = dict()
@property
def uri(self):
"""Namespace URI."""
return self._uri
@property
def prefix(self):
"""Namespace prefix."""
return self._prefix
[docs] def contains(self, identifier):
"""
Indicates whether the identifier provided is contained in this namespace.
:param identifier: Identifier to check.
:return: bool
"""
uri = (
identifier
if isinstance(identifier, str)
else (identifier.uri if isinstance(identifier, Identifier) else None)
)
return uri.startswith(self._uri) if uri else False
[docs] def qname(self, identifier):
"""
Returns the qualified name of the identifier given using the namespace
prefix.
:param identifier: Identifier to resolve to a qualified name.
:return: :py:class:`QualifiedName`
"""
uri = (
identifier
if isinstance(identifier, str)
else (identifier.uri if isinstance(identifier, Identifier) else None)
)
if uri and uri.startswith(self._uri):
return QualifiedName(self, uri[len(self._uri) :])
else:
return None
def __eq__(self, other):
return (
(self._uri == other.uri and self._prefix == other.prefix)
if isinstance(other, Namespace)
else False
)
def __ne__(self, other):
return (
not isinstance(other, Namespace)
or self._uri != other.uri
or self._prefix != other.prefix
)
def __hash__(self):
return hash((self._uri, self._prefix))
def __repr__(self):
return "<%s: %s {%s}>" % (self.__class__.__name__, self._prefix, self._uri)
def __getitem__(self, localpart):
if localpart in self._cache:
return self._cache[localpart]
else:
qname = QualifiedName(self, localpart)
self._cache[localpart] = qname
return qname