bcf - fix issues with unexpected reloads from zip

It wasn't considering that self._topics could be an empty dict because there are no topics and it would also reload it. Now we have None value to distinguish when it actually wasn't loaded before.

Same for viewpoints, reference files and document references.

I've also imade mplementations identical/more similar between v2 and v3.
This commit is contained in:
Andrej730
2024-08-12 16:58:35 +05:00
parent 65cc5bf4c1
commit f9e8d6d478
4 changed files with 46 additions and 32 deletions
+8 -8
View File
@@ -24,7 +24,7 @@ class BcfXml:
self._xml_handler = xml_handler or XmlParserSerializer()
self._version: Optional[mdl.Version] = None
self._project_info: Optional[mdl.ProjectExtension] = None
self._topics: dict[str, TopicHandler] = {}
self._topics: Optional[dict[str, TopicHandler]] = None
self._extension_schema: Optional[bytes] = None
self._zip_file = self._load_zip_file()
@@ -88,21 +88,21 @@ class BcfXml:
@property
def topics(self) -> dict[str, TopicHandler]:
"""BCF topics."""
if not self._topics and self._zip_file:
self._topics = self._load_topics(self._zip_file, self._xml_handler)
if self._topics is None:
self._topics = self._load_topics()
return self._topics
def _load_topics(
self, zip_file: zipfile.ZipFile, xml_handler: AbstractXmlParserSerializer
) -> dict[str, TopicHandler]:
def _load_topics(self) -> dict[str, TopicHandler]:
topics = {}
for topic_dir in zipfile.Path(zip_file).iterdir():
if self._zip_file is None:
return topics
for topic_dir in zipfile.Path(self._zip_file).iterdir():
if not topic_dir.is_dir():
continue
markup_path = topic_dir.joinpath("markup.bcf")
if not markup_path.exists():
continue
topics[topic_dir.name] = TopicHandler(topic_dir, xml_handler)
topics[topic_dir.name] = TopicHandler(topic_dir, self._xml_handler)
return topics
@classmethod
+21 -11
View File
@@ -27,9 +27,9 @@ class TopicHandler:
xml_handler: Optional[AbstractXmlParserSerializer] = None,
) -> None:
self._markup: Optional[mdl.Markup] = None
self._viewpoints: dict[str, VisualizationInfoHandler] = {}
self._reference_files: dict[str, bytes] = {}
self._document_references: dict[str, bytes] = {}
self._viewpoints: Optional[dict[str, VisualizationInfoHandler]] = None
self._reference_files: Optional[dict[str, bytes]] = None
self._document_references: Optional[dict[str, bytes]] = None
self._bim_snippet: Optional[bytes] = None
self._xml_handler = xml_handler or XmlParserSerializer()
self._topic_dir = topic_dir
@@ -80,14 +80,24 @@ class TopicHandler:
@property
def viewpoints(self) -> dict[str, VisualizationInfoHandler]:
if not self._viewpoints and self._topic_dir:
if self._viewpoints is None:
self._viewpoints = self._load_viewpoints()
return self._viewpoints
def _load_viewpoints(self) -> dict[str, VisualizationInfoHandler]:
if self._topic_dir and self.markup and (viewpoints := self.markup.viewpoints):
return VisualizationInfoHandler.from_topic_viewpoints(self._topic_dir, viewpoints)
return {}
@property
def reference_files(self) -> dict[str, bytes]:
if self._reference_files or not self.header:
if self._reference_files is not None:
return self._reference_files
self._reference_files = {}
if not self.header:
return self._reference_files
for ref in self.header.file:
if ref.is_external:
continue
@@ -99,8 +109,13 @@ class TopicHandler:
@property
def document_references(self) -> dict[str, bytes]:
if self._document_references or not self.topic:
if self._document_references is not None:
return self._document_references
self._document_references = {}
if not self.topic:
return self._document_references
for doc in self.topic.document_reference:
if doc.is_external or not doc.referenced_document:
continue
@@ -118,11 +133,6 @@ class TopicHandler:
return bim_snippet_path.read_bytes()
return None
def _load_viewpoints(self) -> dict[str, VisualizationInfoHandler]:
if self.markup and (viewpoints := self.markup.viewpoints):
return VisualizationInfoHandler.from_topic_viewpoints(self._topic_dir, viewpoints)
return {}
@classmethod
def create_new(
cls,
+9 -5
View File
@@ -26,7 +26,7 @@ class BcfXml:
self._version: Optional[mdl.Version] = None
self._project_info: Optional[mdl.ProjectInfo] = None
self._extensions: Optional[mdl.Extensions] = None
self._topics: dict[str, TopicHandler] = {}
self._topics: Optional[dict[str, TopicHandler]] = None
self._documents: Optional[DocumentsHandler] = None
self._zip_file = self._load_zip_file()
@@ -91,18 +91,22 @@ class BcfXml:
@property
def topics(self) -> dict[str, TopicHandler]:
"""BCF topics."""
if not self._topics and self._zip_file:
self._load_topics()
if self._topics is None:
self._topics = self._load_topics()
return self._topics
def _load_topics(self) -> None:
def _load_topics(self) -> dict[str, TopicHandler]:
topics = {}
if self._zip_file is None:
return topics
for topic_dir in zipfile.Path(self._zip_file).iterdir():
if not topic_dir.is_dir():
continue
markup_path = topic_dir.joinpath("markup.bcf")
if not markup_path.exists():
continue
self._topics[topic_dir.name] = TopicHandler(topic_dir, self._xml_handler)
topics[topic_dir.name] = TopicHandler(topic_dir, self._xml_handler)
return topics
@property
def documents(self) -> Optional[DocumentsHandler]:
+8 -8
View File
@@ -26,7 +26,7 @@ class TopicHandler:
xml_handler: Optional[AbstractXmlParserSerializer] = None,
) -> None:
self._markup: Optional[mdl.Markup] = None
self._viewpoints: dict[str, VisualizationInfoHandler] = {}
self._viewpoints: Optional[dict[str, VisualizationInfoHandler]] = None
self._bim_snippet: Optional[bytes] = None
self._xml_handler = xml_handler or XmlParserSerializer()
self._topic_dir = topic_dir
@@ -77,15 +77,15 @@ class TopicHandler:
@property
def viewpoints(self) -> dict[str, "VisualizationInfoHandler"]:
if (
not self._viewpoints
and self._topic_dir
and self.topic.viewpoints
and (viewpoints := self.topic.viewpoints.view_point)
):
self._viewpoints = VisualizationInfoHandler.from_topic_viewpoints(self._topic_dir, viewpoints)
if self._viewpoints is None:
self._viewpoints = self._load_viewpoints()
return self._viewpoints
def _load_viewpoints(self) -> dict[str, "VisualizationInfoHandler"]:
if self._topic_dir and self.topic.viewpoints and (viewpoints := self.topic.viewpoints.view_point):
return VisualizationInfoHandler.from_topic_viewpoints(self._topic_dir, viewpoints)
return {}
def _load_bim_snippet(self) -> Optional[bytes]:
bim_snippet_obj = self.topic.bim_snippet
if bim_snippet_obj and not bim_snippet_obj.is_external and self._topic_dir: