from abc import ABCMeta
from enum import Enum, EnumMeta
from typing import Final, Callable, TypeVar
from operator import lt, le, gt, ge
from re import match
from owlapy import namespaces
from owlapy.model._iri import HasIRI, IRI
from owlapy.namespaces import Namespaces
class _Vocabulary(HasIRI):
__slots__ = '_namespace', '_remainder', '_iri'
_namespace: Namespaces
_remainder: str
_iri: IRI
def __init__(self, namespace: Namespaces, remainder: str):
self._namespace = namespace
self._remainder = remainder
self._iri = IRI(namespace, remainder)
def get_iri(self) -> IRI:
return self._iri
def as_str(self) -> str:
return self._iri.as_str()
def __repr__(self):
return f"<<{self._namespace.prefix}:{self._remainder}>>"
class _meta_Enum(ABCMeta, EnumMeta):
__slots__ = ()
pass
[docs]class OWLRDFVocabulary(_Vocabulary, Enum, metaclass=_meta_Enum):
def __new__(cls, namespace: Namespaces, remainder: str, *args):
obj = object.__new__(cls)
obj._value_ = f"{namespace.prefix}:{remainder}"
return obj
OWL_THING = (namespaces.OWL, "Thing") #:
OWL_NOTHING = (namespaces.OWL, "Nothing") #:
OWL_CLASS = (namespaces.OWL, "Class") #:
OWL_NAMED_INDIVIDUAL = (namespaces.OWL, "NamedIndividual") #:
OWL_TOP_OBJECT_PROPERTY = (namespaces.OWL, "topObjectProperty") #:
OWL_BOTTOM_OBJECT_PROPERTY = (namespaces.OWL, "bottomObjectProperty") #:
OWL_TOP_DATA_PROPERTY = (namespaces.OWL, "topDataProperty") #:
OWL_BOTTOM_DATA_PROPERTY = (namespaces.OWL, "bottomDataProperty") #:
RDFS_LITERAL = (namespaces.RDFS, "Literal") #:
[docs]class XSDVocabulary(_Vocabulary, Enum, metaclass=_meta_Enum):
def __new__(cls, remainder: str, *args):
obj = object.__new__(cls)
obj._value_ = f"{namespaces.XSD.prefix}:{remainder}"
return obj
def __init__(self, remainder: str):
super().__init__(namespaces.XSD, remainder)
DECIMAL: Final = "decimal" #:
INTEGER: Final = "integer" #:
LONG: Final = "long" #:
DOUBLE: Final = "double" #:
FLOAT: Final = "float" #:
BOOLEAN: Final = "boolean" #:
STRING: Final = "string" #:
DATE: Final = "date" #:
DATE_TIME: Final = "dateTime" #:
DATE_TIME_STAMP: Final = "dateTimeStamp" #:
DURATION: Final = "duration" #:
_X = TypeVar('_X')
# TODO: Add langRange facet
[docs]class OWLFacet(_Vocabulary, Enum, metaclass=_meta_Enum):
def __new__(cls, remainder: str, *args):
obj = object.__new__(cls)
obj._value_ = f"{namespaces.XSD.prefix}:{remainder}"
return obj
def __init__(self, remainder: str, symbolic_form: str, operator: Callable[[_X, _X], bool]):
super().__init__(namespaces.XSD, remainder)
self._symbolic_form = symbolic_form
self._operator = operator
@property
def symbolic_form(self):
return self._symbolic_form
@property
def operator(self):
return self._operator
[docs] @staticmethod
def from_str(name: str) -> 'OWLFacet':
try:
return next(facet for facet in OWLFacet if name == facet.symbolic_form)
except StopIteration:
raise ValueError(f"No facet with symbolic form {name} exists.")
MIN_INCLUSIVE: Final = ("minInclusive", ">=", ge) #:
MIN_EXCLUSIVE: Final = ("minExclusive", ">", gt) #:
MAX_INCLUSIVE: Final = ("maxInclusive", "<=", le) #:
MAX_EXCLUSIVE: Final = ("maxExclusive", "<", lt) #:
LENGTH: Final = ("length", "length", lambda a, b: len(a) == b.parse_integer()) #:
MIN_LENGTH: Final = ("minLength", "minLength", lambda a, b: len(a) >= b.parse_integer()) #:
MAX_LENGTH: Final = ("maxLength", "maxLength", lambda a, b: len(a) <= b.parse_integer()) #:
PATTERN: Final = ("pattern", "pattern", lambda a, b: bool(match(b.parse_string() + "$", a.get_literal())))
TOTAL_DIGITS: Final = ("totalDigits", "totalDigits",
lambda a, b: sum(1 for c in a.get_literal() if c.isdigit()) <= b.parse_integer())
FRACTION_DIGITS: Final = ("fractionDigits", "fractionDigits",
lambda a, b: a.get_literal()[::-1].find('.') <= b.parse_integer())