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._xml_handler = xml_handler or XmlParserSerializer()
self._version: Optional[mdl.Version] = None self._version: Optional[mdl.Version] = None
self._project_info: Optional[mdl.ProjectExtension] = 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._extension_schema: Optional[bytes] = None
self._zip_file = self._load_zip_file() self._zip_file = self._load_zip_file()
@@ -88,21 +88,21 @@ class BcfXml:
@property @property
def topics(self) -> dict[str, TopicHandler]: def topics(self) -> dict[str, TopicHandler]:
"""BCF topics.""" """BCF topics."""
if not self._topics and self._zip_file: if self._topics is None:
self._topics = self._load_topics(self._zip_file, self._xml_handler) self._topics = self._load_topics()
return self._topics return self._topics
def _load_topics( def _load_topics(self) -> dict[str, TopicHandler]:
self, zip_file: zipfile.ZipFile, xml_handler: AbstractXmlParserSerializer
) -> dict[str, TopicHandler]:
topics = {} 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(): if not topic_dir.is_dir():
continue continue
markup_path = topic_dir.joinpath("markup.bcf") markup_path = topic_dir.joinpath("markup.bcf")
if not markup_path.exists(): if not markup_path.exists():
continue continue
topics[topic_dir.name] = TopicHandler(topic_dir, xml_handler) topics[topic_dir.name] = TopicHandler(topic_dir, self._xml_handler)
return topics return topics
@classmethod @classmethod
+21 -11
View File
@@ -27,9 +27,9 @@ class TopicHandler:
xml_handler: Optional[AbstractXmlParserSerializer] = None, xml_handler: Optional[AbstractXmlParserSerializer] = None,
) -> None: ) -> None:
self._markup: Optional[mdl.Markup] = None self._markup: Optional[mdl.Markup] = None
self._viewpoints: dict[str, VisualizationInfoHandler] = {} self._viewpoints: Optional[dict[str, VisualizationInfoHandler]] = None
self._reference_files: dict[str, bytes] = {} self._reference_files: Optional[dict[str, bytes]] = None
self._document_references: dict[str, bytes] = {} self._document_references: Optional[dict[str, bytes]] = None
self._bim_snippet: Optional[bytes] = None self._bim_snippet: Optional[bytes] = None
self._xml_handler = xml_handler or XmlParserSerializer() self._xml_handler = xml_handler or XmlParserSerializer()
self._topic_dir = topic_dir self._topic_dir = topic_dir
@@ -80,14 +80,24 @@ class TopicHandler:
@property @property
def viewpoints(self) -> dict[str, VisualizationInfoHandler]: def viewpoints(self) -> dict[str, VisualizationInfoHandler]:
if not self._viewpoints and self._topic_dir: if self._viewpoints is None:
self._viewpoints = self._load_viewpoints() self._viewpoints = self._load_viewpoints()
return self._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 @property
def reference_files(self) -> dict[str, bytes]: 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 return self._reference_files
self._reference_files = {}
if not self.header:
return self._reference_files
for ref in self.header.file: for ref in self.header.file:
if ref.is_external: if ref.is_external:
continue continue
@@ -99,8 +109,13 @@ class TopicHandler:
@property @property
def document_references(self) -> dict[str, bytes]: 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 return self._document_references
self._document_references = {}
if not self.topic:
return self._document_references
for doc in self.topic.document_reference: for doc in self.topic.document_reference:
if doc.is_external or not doc.referenced_document: if doc.is_external or not doc.referenced_document:
continue continue
@@ -118,11 +133,6 @@ class TopicHandler:
return bim_snippet_path.read_bytes() return bim_snippet_path.read_bytes()
return None 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 @classmethod
def create_new( def create_new(
cls, cls,
+9 -5
View File
@@ -26,7 +26,7 @@ class BcfXml:
self._version: Optional[mdl.Version] = None self._version: Optional[mdl.Version] = None
self._project_info: Optional[mdl.ProjectInfo] = None self._project_info: Optional[mdl.ProjectInfo] = None
self._extensions: Optional[mdl.Extensions] = 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._documents: Optional[DocumentsHandler] = None
self._zip_file = self._load_zip_file() self._zip_file = self._load_zip_file()
@@ -91,18 +91,22 @@ class BcfXml:
@property @property
def topics(self) -> dict[str, TopicHandler]: def topics(self) -> dict[str, TopicHandler]:
"""BCF topics.""" """BCF topics."""
if not self._topics and self._zip_file: if self._topics is None:
self._load_topics() self._topics = self._load_topics()
return self._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(): for topic_dir in zipfile.Path(self._zip_file).iterdir():
if not topic_dir.is_dir(): if not topic_dir.is_dir():
continue continue
markup_path = topic_dir.joinpath("markup.bcf") markup_path = topic_dir.joinpath("markup.bcf")
if not markup_path.exists(): if not markup_path.exists():
continue 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 @property
def documents(self) -> Optional[DocumentsHandler]: def documents(self) -> Optional[DocumentsHandler]:
+8 -8
View File
@@ -26,7 +26,7 @@ class TopicHandler:
xml_handler: Optional[AbstractXmlParserSerializer] = None, xml_handler: Optional[AbstractXmlParserSerializer] = None,
) -> None: ) -> None:
self._markup: Optional[mdl.Markup] = 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._bim_snippet: Optional[bytes] = None
self._xml_handler = xml_handler or XmlParserSerializer() self._xml_handler = xml_handler or XmlParserSerializer()
self._topic_dir = topic_dir self._topic_dir = topic_dir
@@ -77,15 +77,15 @@ class TopicHandler:
@property @property
def viewpoints(self) -> dict[str, "VisualizationInfoHandler"]: def viewpoints(self) -> dict[str, "VisualizationInfoHandler"]:
if ( if self._viewpoints is None:
not self._viewpoints self._viewpoints = self._load_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)
return self._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]: def _load_bim_snippet(self) -> Optional[bytes]:
bim_snippet_obj = self.topic.bim_snippet bim_snippet_obj = self.topic.bim_snippet
if bim_snippet_obj and not bim_snippet_obj.is_external and self._topic_dir: if bim_snippet_obj and not bim_snippet_obj.is_external and self._topic_dir: