From 54be7472cbdd3a9beca69fb3f11fd50ae1a5d384 Mon Sep 17 00:00:00 2001 From: Balint Bende Date: Thu, 25 Jul 2024 17:15:34 +0200 Subject: [PATCH] [BMSPT-306] multiple viewpoint and snapshot export to file --- .../Builder/Bcf30/DocumentReferenceBuilder.cs | 2 +- src/bcf-toolkit/Converter/Bcf21/FileWriter.cs | 83 +++++++++++++------ src/bcf-toolkit/Converter/Bcf30/FileWriter.cs | 52 ++++++------ src/tests/Converter/Bcf21/ConverterTests.cs | 15 ++++ 4 files changed, 102 insertions(+), 50 deletions(-) diff --git a/src/bcf-toolkit/Builder/Bcf30/DocumentReferenceBuilder.cs b/src/bcf-toolkit/Builder/Bcf30/DocumentReferenceBuilder.cs index 8566ab1..64f168e 100644 --- a/src/bcf-toolkit/Builder/Bcf30/DocumentReferenceBuilder.cs +++ b/src/bcf-toolkit/Builder/Bcf30/DocumentReferenceBuilder.cs @@ -15,7 +15,7 @@ public DocumentReferenceBuilder SetGuid(string guid) { return this; } - public DocumentReferenceBuilder SetDescription(string description) { + public DocumentReferenceBuilder SetDescription(string? description) { _documentReference.Description = description; return this; } diff --git a/src/bcf-toolkit/Converter/Bcf21/FileWriter.cs b/src/bcf-toolkit/Converter/Bcf21/FileWriter.cs index deb21ef..cf4b9bf 100644 --- a/src/bcf-toolkit/Converter/Bcf21/FileWriter.cs +++ b/src/bcf-toolkit/Converter/Bcf21/FileWriter.cs @@ -109,16 +109,31 @@ public static void SerializeAndWriteBcfToStream( var topicFolder = $"{guid}"; zip.CreateEntryFromObject($"{topicFolder}/markup.bcf", markup); - - var visInfo = - (VisualizationInfo)markup.GetFirstViewPoint()?.GetVisualizationInfo()!; - zip.CreateEntryFromObject($"{topicFolder}/viewpoint.bcfv", visInfo); - - var snapshotFileName = markup.GetFirstViewPoint()?.Snapshot; - var base64String = markup.GetFirstViewPoint()?.SnapshotData?.Data; - if (snapshotFileName == null || base64String == null) continue; - var bytes = Convert.FromBase64String(base64String); - zip.CreateEntryFromBytes($"{topicFolder}/{snapshotFileName}", bytes); + + foreach (var viewpoint in markup.Viewpoints) { + zip.CreateEntryFromObject($"{topicFolder}/{viewpoint.Viewpoint}", viewpoint.VisualizationInfo); + + var snapshotFileName = viewpoint.Snapshot; + var snapshotBase64String = viewpoint.SnapshotData?.Data; + if (string.IsNullOrEmpty(snapshotFileName) || snapshotBase64String == null) + continue; + var snapshotBytes = Convert.FromBase64String(snapshotBase64String); + zip.CreateEntryFromBytes($"{topicFolder}/{snapshotFileName}", snapshotBytes); + } + + //Additional files can be referenced by other files via their relative + //paths. It is recommended to put them in a folder called Documents in the + //root folder of the zip archive. + var internalDocuments = markup + .Topic.DocumentReference + .Where(d => !d.IsExternal); + foreach (var document in internalDocuments) { + var documentFileName = Path.GetFileName(document.ReferencedDocument); + var documentBase64String = document.DocumentData.Data; + if (string.IsNullOrEmpty(documentFileName)) continue; + var documentBytes = Convert.FromBase64String(documentBase64String); + zip.CreateEntryFromBytes($"documents/{documentFileName}", documentBytes); + } } zip.CreateEntryFromObject("project.bcfp", bcfObject.Project); @@ -179,21 +194,41 @@ public static async Task SerializeAndWriteBcfToFolder( topicFolder, "markup.bcf", markup)); - - var visInfo = - (VisualizationInfo)markup.GetFirstViewPoint()?.GetVisualizationInfo()!; - writeTasks.Add( - BcfExtensions.SerializeAndWriteXmlFile( + + foreach (var viewpoint in markup.Viewpoints) { + writeTasks.Add( BcfExtensions.SerializeAndWriteXmlFile( topicFolder, - "viewpoint.bcfv", - visInfo)); - - var snapshotFileName = markup.GetFirstViewPoint()?.Snapshot; - var base64String = markup.GetFirstViewPoint()?.SnapshotData?.Data; - if (snapshotFileName == null || base64String == null) continue; - writeTasks.Add(File.WriteAllBytesAsync( - $"{topicFolder}/{snapshotFileName}", - Convert.FromBase64String(base64String))); + viewpoint.Viewpoint, + viewpoint.VisualizationInfo)); + + var snapshotFileName = viewpoint.Snapshot; + var snapshotBase64String = viewpoint.SnapshotData?.Data; + if (string.IsNullOrEmpty(snapshotFileName) || snapshotBase64String == null) + continue; + writeTasks.Add(File.WriteAllBytesAsync( + $"{topicFolder}/{snapshotFileName}", + Convert.FromBase64String(snapshotBase64String))); + } + + //Additional files can be referenced by other files via their relative + //paths. It is recommended to put them in a folder called Documents in the + //root folder of the zip archive. + var documentFolder = $"{tmpFolder}/documents"; + var internalDocuments = markup + .Topic.DocumentReference + .Where(d => !d.IsExternal); + foreach (var document in internalDocuments) { + var documentFileName = Path.GetFileName(document.ReferencedDocument); + var documentBase64String = document.DocumentData.Data; + if (string.IsNullOrEmpty(documentFileName)) continue; + + if (Directory.Exists(documentFolder) is not true) + Directory.CreateDirectory(documentFolder); + + writeTasks.Add(File.WriteAllBytesAsync( + $"{documentFolder}/{documentFileName}", + Convert.FromBase64String(documentBase64String))); + } } writeTasks.Add( diff --git a/src/bcf-toolkit/Converter/Bcf30/FileWriter.cs b/src/bcf-toolkit/Converter/Bcf30/FileWriter.cs index 837aa6d..7693e9a 100644 --- a/src/bcf-toolkit/Converter/Bcf30/FileWriter.cs +++ b/src/bcf-toolkit/Converter/Bcf30/FileWriter.cs @@ -128,17 +128,17 @@ public static void SerializeAndWriteBcfToStream(IBcf bcf, ZipArchive zip, var topicFolder = $"{guid}"; zip.CreateEntryFromObject($"{topicFolder}/markup.bcf", markup); - - var visInfo = - (VisualizationInfo)markup.GetFirstViewPoint()?.GetVisualizationInfo()!; - zip.CreateEntryFromObject($"{topicFolder}/viewpoint.bcfv", visInfo); - - // Write snapshot - var snapshotFileName = markup.GetFirstViewPoint()?.Snapshot; - var base64String = markup.GetFirstViewPoint()?.SnapshotData?.Data; - if (snapshotFileName == null || base64String == null) continue; - var bytes = Convert.FromBase64String(base64String); - zip.CreateEntryFromBytes($"{topicFolder}/{snapshotFileName}", bytes); + + foreach (var viewpoint in markup.Topic.Viewpoints) { + zip.CreateEntryFromObject($"{topicFolder}/{viewpoint.Viewpoint}", viewpoint.VisualizationInfo); + + var snapshotFileName = viewpoint.Snapshot; + var snapshotBase64String = viewpoint.SnapshotData?.Data; + if (string.IsNullOrEmpty(snapshotFileName) || snapshotBase64String == null) + continue; + var snapshotBytes = Convert.FromBase64String(snapshotBase64String); + zip.CreateEntryFromBytes($"{topicFolder}/{snapshotFileName}", snapshotBytes); + } } zip.CreateEntryFromObject("extensions.xml", bcfObject.Extensions); @@ -207,20 +207,22 @@ public static async Task SerializeAndWriteBcfToFolder( writeTasks.Add( BcfExtensions.SerializeAndWriteXmlFile(topicFolder, "markup.bcf", markup)); - - var visInfo = - (VisualizationInfo)markup.GetFirstViewPoint()?.GetVisualizationInfo()!; - writeTasks.Add(BcfExtensions.SerializeAndWriteXmlFile( - topicFolder, - "viewpoint.bcfv", - visInfo)); - - var snapshotFileName = markup.GetFirstViewPoint()?.Snapshot; - var base64String = markup.GetFirstViewPoint()?.SnapshotData?.Data; - if (snapshotFileName == null || base64String == null) continue; - writeTasks.Add(File.WriteAllBytesAsync( - $"{topicFolder}/{snapshotFileName}", - Convert.FromBase64String(base64String))); + + foreach (var viewpoint in markup.Topic.Viewpoints) { + writeTasks.Add(BcfExtensions.SerializeAndWriteXmlFile( + topicFolder, + viewpoint.Viewpoint, + viewpoint.VisualizationInfo)); + + var snapshotFileName = viewpoint.Snapshot; + var snapshotBase64String = viewpoint.SnapshotData?.Data; + if (string.IsNullOrEmpty(snapshotFileName) || + snapshotBase64String == null) + continue; + writeTasks.Add(File.WriteAllBytesAsync( + $"{topicFolder}/{snapshotFileName}", + Convert.FromBase64String(snapshotBase64String))); + } } writeTasks.Add(BcfExtensions.SerializeAndWriteXmlFile(tmpFolder, diff --git a/src/tests/Converter/Bcf21/ConverterTests.cs b/src/tests/Converter/Bcf21/ConverterTests.cs index 9668c70..787533a 100644 --- a/src/tests/Converter/Bcf21/ConverterTests.cs +++ b/src/tests/Converter/Bcf21/ConverterTests.cs @@ -206,4 +206,19 @@ public async Task BuildV30BcfFromStreamWithInternalDocumentTest() { Assert.That(document?.DocumentData.Mime, Is.EqualTo("data:application/xml;base64")); Assert.That(document?.DocumentData.Data.Length, Is.EqualTo(10644)); } + + /// + /// It should generate a bcf skipping the markup file. + /// + [Test] + [Category("BCF v2.1")] + public async Task WriteBcfToFolderTest() { + await using var stream = + new FileStream( + "Resources/Bcf/v2.1/MaximumInformation.bcfzip", + FileMode.Open, + FileAccess.Read); + var bcf = await _converter.BcfFromStream(stream); + await _converter.ToBcf(bcf, "Resources/output/Bcf/v2.1/MaximumInformation.bcfzip"); + } } \ No newline at end of file