From 76a523cec2c541a4c83beccb18a70372efb5ae61 Mon Sep 17 00:00:00 2001
From: Matthias Bodenbenner <m.bodenbenner@wzl-mq.rwth-aachen.de>
Date: Thu, 11 Jan 2024 09:37:01 +0100
Subject: [PATCH] 9.0.1- bug fixes & small refactoring

---
 README.md               |  6 +++++-
 requirements.txt        |  2 +-
 setup.py                |  4 ++--
 src/http/server.py      |  2 +-
 src/soil/component.py   | 15 ++++-----------
 src/soil/element.py     |  9 ++++-----
 src/soil/function.py    |  4 ++--
 src/soil/measurement.py | 18 ++----------------
 src/soil/parameter.py   | 15 +--------------
 9 files changed, 22 insertions(+), 53 deletions(-)

diff --git a/README.md b/README.md
index 7b2f58c..d0ada77 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
 [![Build](https://git-ce.rwth-aachen.de/wzl-mq-ms/forschung-lehre/lava/unified-device-interface/python/badges/master/pipeline.svg)](https://git-ce.rwth-aachen.de/wzl-mq-ms/forschung-lehre/lava/unified-device-interface/python/commits/master)
 
 # Python Unified Device Interface
-Current stable version: 9.0.0
+Current stable version: 9.0.1
 
 ## Installation
 1. Install the WZL-UDI package via pip
@@ -53,10 +53,14 @@ https://doi.org/10.1117/12.2527461
 The authors acknowledge funding from the LaVA project (Large Volume Applications, contract 17IND03 of the European Metrology Programme for Innovation and Research EMPIR). The EMPIR initiative is co-funded by the European Union’s Horizon 2020 research and innovation programme and the EMPIR Participating States.
 
 Funded by the Deutsche Forschungsgemeinschaft (DFG, German Research Foundation) under Germany's Excellence Strategy – EXC-2023 Internet of Production – 390621612.
+
 Funded by the Deutsche Forschungsgemeinschaft (DFG, German Research Foundation) under Project-ID 432233186 -- AIMS. 
 
 ## Recent changes
 
+**9.0.1** - 2024-01-11
+  - bug fix of semantic name resolution
+
 **9.0.0** - 2024-01-10
   - added semantic features
     - the device can return profiles, metadata and data defined and structured according to semantic web standards using RDF and SHACL
diff --git a/requirements.txt b/requirements.txt
index 042289c..9d3aff5 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -7,4 +7,4 @@ rdflib==7.0.0
 sphinx==3.5.2
 sphinx-rtd-theme==1.0.0
 strict-rfc3339==0.7
-wzl-mqtt~=2.6.0
\ No newline at end of file
+wzl-mqtt~=2.6.1
\ No newline at end of file
diff --git a/setup.py b/setup.py
index c019b33..d8f626c 100644
--- a/setup.py
+++ b/setup.py
@@ -4,7 +4,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
     long_description = fh.read()
 
 setup(name='wzl-udi',
-      version='9.0.0',
+      version='9.0.1',
       url='https://git-ce.rwth-aachen.de/wzl-mq-public/soil/python',
       project_urls={
           "Bug Tracker": "https://git-ce.rwth-aachen.de/wzl-mq-public/soil/python/-/issues",
@@ -25,7 +25,7 @@ setup(name='wzl-udi',
                         'Deprecated~=1.2.13',
                         'nest-asyncio~=1.5.6',
                         'strict-rfc3339==0.7',
-                        'wzl-mqtt~=2.5.3',
+                        'wzl-mqtt~=2.6.1',
                         'rdflib~=7.0.0'
                         ],
       zip_safe=False)
diff --git a/src/http/server.py b/src/http/server.py
index a947643..2cac618 100644
--- a/src/http/server.py
+++ b/src/http/server.py
@@ -180,7 +180,7 @@ class HTTPServer(object):
             semantic = request.query['semantic']
 
         if len(splitted_request) > 0 and splitted_request[0] == Semantics.prefix:
-            item, semantic = self.root.resolve_semantic_path(splitted_request[1:])
+            item, semantic = self.root.resolve_semantic_path(splitted_request[1])
         else:
             try:
                 item = self.root[splitted_request]
diff --git a/src/soil/component.py b/src/soil/component.py
index b80b951..daca80d 100644
--- a/src/soil/component.py
+++ b/src/soil/component.py
@@ -395,20 +395,13 @@ class Component(Element):
             raise DeviceException('The provided kind of semantic information cannot be returned.')
         return result
 
-    def resolve_semantic_path(self, path: List[str]):
+    def resolve_semantic_path(self, suffix: str) -> (Element, str):
         try:
-            super().resolve_semantic_path(path)
+            return super().resolve_semantic_path(suffix)
         except ChildNotFoundException:
-            triples = list(self._metadata.triples((None, Namespaces.rdf.type, None)))
-            triples = list(filter(lambda x: x[2] == Namespaces.ssn.System, triples))
-            assert len(triples) > 0
-
-            if path[0] == triples[0][0].split('/')[-1] and len(path) == 1:
-                return self, 'metadata'
-
             for child in self.children:
                 try:
-                    return child.resolve_semantic_path(path)
+                    return child.resolve_semantic_path(suffix)
                 except ChildNotFoundException:
                     continue
 
@@ -419,4 +412,4 @@ class Component(Element):
         if self._metadata is None:
             return ""
         subject = next(self._metadata.subjects(predicate=Namespaces.rdf.type, object=Namespaces.ssn.System))
-        return subject.toPython()
\ No newline at end of file
+        return subject.toPython()
diff --git a/src/soil/element.py b/src/soil/element.py
index c7e332d..cf0c30a 100644
--- a/src/soil/element.py
+++ b/src/soil/element.py
@@ -112,12 +112,11 @@ class Element(ABC):
     def serialize_semantics(self, kind: str) -> rdflib.Graph:
         ...
 
-    def resolve_semantic_path(self, path: List[str]) -> ('Element', str):
-        if len(path) == 0:
-            raise ChildNotFoundException('Could not resolve the semantic path.')
-
-        if path[0] == f'{self._profilename}Shape' and len(path) == 1:
+    def resolve_semantic_path(self, suffix: str) -> ('Element', str):
+        if suffix == f'{self._profilename}Shape':
             return self, 'profile'
+        elif suffix == self.semantic_name.split('/')[-1]:
+            return self, 'metadata'
 
         raise ChildNotFoundException('Could not resolve the semantic path.')
 
diff --git a/src/soil/function.py b/src/soil/function.py
index b531f8c..53c2a45 100644
--- a/src/soil/function.py
+++ b/src/soil/function.py
@@ -195,10 +195,10 @@ class Function(Element):
         # This method does nothing intentionally, as we do not have any semantic definition for function
         return None
 
-    def resolve_semantic_path(self, path: List[str]) -> ('Element', str):
+    def resolve_semantic_path(self, suffix: str) -> (Element, str):
         # This method does nothing intentionally, as we do not have any semantic definition for function
         raise ChildNotFoundException('Could not resolve the semantic path.')
 
     @property
     def semantic_name(self) -> str:
-        return ""
\ No newline at end of file
+        return ""
diff --git a/src/soil/measurement.py b/src/soil/measurement.py
index 063431c..217f46f 100644
--- a/src/soil/measurement.py
+++ b/src/soil/measurement.py
@@ -6,8 +6,6 @@ import rdflib
 from deprecated import deprecated
 
 from .datatype import Datatype
-from .element import Element
-from .error import ChildNotFoundException
 from .figure import Figure
 from .semantics import Semantics, Namespaces
 from ..utils import root_logger
@@ -223,22 +221,10 @@ class Measurement(Figure):
             raise DeviceException('The provided kind of semantic information cannot be returned.')
         return result
 
-    def resolve_semantic_path(self, path: List[str]) -> (Element, str):
-        try:
-            super().resolve_semantic_path(path)
-        except ChildNotFoundException:
-            triples = list(self._metadata.triples((None, Namespaces.rdf.type, None)))
-            triples = list(filter(lambda x: x[2] == Namespaces.sosa.ObservableProperty, triples))
-            assert len(triples) > 0
-
-            if path[0] == triples[0][0].split('/')[-1] and len(path) == 1:
-                return self, 'metadata'
-
-            raise ChildNotFoundException('Could not resolve the semantic path.')
-
     @property
     def semantic_name(self) -> str:
         if self._metadata is None:
             return ""
-        subject = next(self._metadata.subjects(predicate=Namespaces.rdf.type, object=Namespaces.sosa.ObservableProperty))
+        subject = next(
+            self._metadata.subjects(predicate=Namespaces.rdf.type, object=Namespaces.sosa.ObservableProperty))
         return subject.toPython()
diff --git a/src/soil/parameter.py b/src/soil/parameter.py
index 5c794b3..62b094b 100644
--- a/src/soil/parameter.py
+++ b/src/soil/parameter.py
@@ -6,7 +6,7 @@ from typing import Dict, Callable, Any, List
 import rdflib
 
 from .datatype import Datatype
-from .error import ReadOnlyException, ChildNotFoundException
+from .error import ReadOnlyException
 from .figure import Figure
 from .semantics import Semantics, Namespaces
 from ..utils import root_logger
@@ -154,19 +154,6 @@ class Parameter(Figure):
             raise DeviceException('The provided kind of semantic information cannot be returned.')
         return result
 
-    def resolve_semantic_path(self, path: List[str]) -> ('Element', str):
-        try:
-            super().resolve_semantic_path(path)
-        except ChildNotFoundException:
-            triples = list(self._metadata.triples((None, Namespaces.rdf.type, None)))
-            triples = list(filter(lambda x: x[2] == Namespaces.ssn.Property, triples))
-            assert len(triples) > 0
-
-            if path[0] == triples[0][0].split('/')[-1] and len(path) == 1:
-                return self, 'metadata'
-
-            raise ChildNotFoundException('Could not resolve the semantic path.')
-
     @property
     def semantic_name(self) -> str:
         if self._metadata is None:
-- 
GitLab