Skip to content

Commit

Permalink
Merge branch 'feature/BMSPT-306-document-references' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
BalintBende committed Jul 26, 2024
2 parents 68a3ae0 + 7aff740 commit ceeba06
Show file tree
Hide file tree
Showing 19 changed files with 385 additions and 143 deletions.
19 changes: 16 additions & 3 deletions bcf-toolkit.sln.DotSettings.user
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@
<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=00488d9b_002Ddfb9_002D47fc_002Da7da_002D60da862eab61/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" Name="All tests from Solution #2" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;
&lt;Solution /&gt;
&lt;/SessionState&gt;</s:String>


<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=64259359_002Daf01_002D4100_002Db5a8_002D06c7d51d9f83/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" Name="BuildMaximumInformationBcfFromStreamTest" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;
&lt;TestAncestor&gt;
&lt;TestId&gt;NUnit3x::8113526D-8A68-4E3E-B4DB-CE235875DDD1::net8.0::tests.Builder.Bcf21.BcfBuilderTests.BuildMaximumInformationBcfFromStreamTest&lt;/TestId&gt;
&lt;/TestAncestor&gt;
&lt;/SessionState&gt;</s:String>


<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=7d7fd643_002Dccec_002D4fc7_002D8938_002D22e83b255cb0/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" Name="BuildEmptyBcfFromStream" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;
&lt;TestAncestor&gt;
&lt;TestId&gt;NUnit3x::8113526D-8A68-4E3E-B4DB-CE235875DDD1::net8.0::tests.Builder.Bcf21.BcfBuilderTests.BuildEmptyBcfFromStream&lt;/TestId&gt;
Expand All @@ -22,20 +31,24 @@




<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=87607a24_002D24bc_002D46e1_002Da035_002D28c18ba9b643/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from Solution" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;
&lt;Solution /&gt;
&lt;/SessionState&gt;</s:String>






<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=b2d5c176_002Dc751_002D42d4_002Da842_002D3ad7ad02438d/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" IsActive="True" Name="WorkerTests" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;
&lt;TestAncestor&gt;
&lt;TestId&gt;NUnit3x::8113526D-8A68-4E3E-B4DB-CE235875DDD1::net8.0::Tests.WorkerTests&lt;/TestId&gt;
&lt;/TestAncestor&gt;
&lt;/SessionState&gt;</s:String>

<s:String x:Key="/Default/Environment/UnitTesting/UnitTestSessionStore/Sessions/=b8bc73b7_002Db468_002D4274_002Dac5e_002D0a6e69b42a05/@EntryIndexedValue">&lt;SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from Solution #3" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"&gt;
&lt;Solution /&gt;
&lt;/SessionState&gt;</s:String>





Expand Down
1 change: 0 additions & 1 deletion src/bcf-toolkit/Builder/Bcf21/BcfBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using System;
using BcfToolkit.Builder.Bcf21.Interfaces;
using BcfToolkit.Builder.Interfaces;
using BcfToolkit.Model;
using BcfToolkit.Model.Bcf21;
using BcfToolkit.Model.Interfaces;

Expand Down
71 changes: 71 additions & 0 deletions src/bcf-toolkit/Builder/Bcf21/BcfBuilderExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Threading.Tasks;
using BcfToolkit.Model;
using BcfToolkit.Model.Bcf21;
using BcfToolkit.Utils;

Expand All @@ -11,6 +16,7 @@ public async Task<Bcf> BuildFromStream(Stream source) {
_bcf.Markups =
await BcfExtensions.ParseMarkups<Markup, VisualizationInfo>(source);
_bcf.Project = await BcfExtensions.ParseProject<ProjectExtension>(source);
SetDocumentDataFromReferences(source);
return BuilderUtils.ValidateItem(_bcf);
}

Expand All @@ -23,4 +29,69 @@ public BcfBuilder SetProject(ProjectExtension? project) {
_bcf.Project = project;
return this;
}

/// <summary>
/// It sets the document file name and base64 data from the specified
/// document data dictionary.
/// </summary>
/// <param name="documentData">
/// Dictionary contains document guid as the key and a tuple of document
/// file name and file data as the value
/// </param>
/// <returns></returns>
public BcfBuilder SetDocumentData(
Dictionary<string, Tuple<string, FileData>>? documentData) {
if (documentData is null) return this;
var documentReferences =
_bcf.Markups.SelectMany(m => m.Topic.DocumentReference).ToList();
foreach (var data in documentData) {
var documentReference =
documentReferences.FirstOrDefault(r =>
r.ReferencedDocument.Equals(data.Key));
if (documentReference is null) continue;
//It is recommended to put files in a folder called Documents in the root
//folder of the zip archive.
documentReference.ReferencedDocument = $"../documents/{data.Value.Item1}";
documentReference.DocumentData = data.Value.Item2;
}
return this;
}

/// <summary>
/// It turns the additional file data that are referenced as internal
/// document in markups into the DocumentInfo.
/// </summary>
/// <param name="stream">The file stream of the BCFzip.</param>
/// <returns></returns>
/// <exception cref="ArgumentException"></exception>
private void SetDocumentDataFromReferences(Stream stream) {
if (stream is null || !stream.CanRead)
throw new ArgumentException("Source stream is not readable.");

Log.Debug($"\nProcessing documents\n");

using var archive = new ZipArchive(stream, ZipArchiveMode.Read, true);

// These 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 documentReferences = _bcf
.Markups
.SelectMany(m => m.Topic.DocumentReference)
.ToList();

documentReferences
.Where(d => !d.IsExternal)
.ToList()
.ForEach(d => {
var fileName = Path.GetFileName(d.ReferencedDocument);
var entry = archive.DocumentEntry(fileName);
if (entry is null) return;
Log.Debug(entry.FullName);
d.SetDocumentData(entry);
});

// Stream must be positioned back to 0 in order to use it again
stream.Position = 0;
}
}
5 changes: 4 additions & 1 deletion src/bcf-toolkit/Builder/Bcf30/DocumentBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
using System;
using BcfToolkit.Builder.Bcf30.Interfaces;
using BcfToolkit.Builder.Interfaces;
using BcfToolkit.Model;
using BcfToolkit.Model.Bcf30;

namespace BcfToolkit.Builder.Bcf30;

public partial class DocumentBuilder :
IDocumentBuilder<DocumentBuilder>,
IDefaultBuilder<DocumentBuilder> {
private readonly Document _document = new();
private readonly Document _document = new() {
DocumentData = new FileData()
};

public DocumentBuilder SetGuid(string guid) {
_document.Guid = guid;
Expand Down
2 changes: 1 addition & 1 deletion src/bcf-toolkit/Builder/Bcf30/DocumentReferenceBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
79 changes: 57 additions & 22 deletions src/bcf-toolkit/Converter/Bcf21/FileWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,15 +110,30 @@ public static void SerializeAndWriteBcfToStream(

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);
Expand Down Expand Up @@ -180,20 +195,40 @@ public static async Task<string> SerializeAndWriteBcfToFolder(
"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(
Expand Down
32 changes: 21 additions & 11 deletions src/bcf-toolkit/Converter/Bcf21/SchemaConverterToBcf30.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using BcfToolkit.Builder.Bcf30;

Expand Down Expand Up @@ -43,21 +44,30 @@ private static Model.Bcf30.Markup ConvertMarkup(Model.Bcf21.Markup from) {
var topic = from.Topic;
builder
.AddHeaderFiles(from.Header.Select(ConvertHeaderFile).ToList())
.AddReferenceLinks(topic.ReferenceLink.Where(referenceLink => !string.IsNullOrEmpty(referenceLink)).ToList())
.AddReferenceLinks(topic.ReferenceLink.Where(referenceLink =>
!string.IsNullOrEmpty(referenceLink))
.ToList())
.SetIndex(topic.Index)
.SetTitle(from.Topic.Title)
.AddLabels(topic.Labels.Where(label => !string.IsNullOrEmpty(label)).ToList())
.AddLabels(topic.Labels.Where(label => !string.IsNullOrEmpty(label))
.ToList())
.SetCreationDate(topic.CreationDate)
.SetCreationAuthor(from.Topic.CreationAuthor)
.SetModifiedDate(topic.ModifiedDate)
.SetDueDate(topic.DueDate)
.AddRelatedTopics(topic.RelatedTopic.Select(t => t.Guid).ToList())
.AddRelatedTopics(topic.RelatedTopic.Select(t => t.Guid)
.ToList())
.AddComments(from.Comment.Select(ConvertComment).ToList())
.AddViewPoints(from.Viewpoints.Select(ConvertViewPoint).ToList())
.SetGuid(from.Topic.Guid)
.SetTopicType(string.IsNullOrEmpty(from.Topic.TopicType) ? "ERROR" : from.Topic.TopicType)
.SetTopicStatus(string.IsNullOrEmpty(from.Topic.TopicStatus) ? "OPEN" : from.Topic.TopicStatus)
.SetTopicType(string.IsNullOrEmpty(from.Topic.TopicType)
? "ERROR"
: from.Topic.TopicType)
.SetTopicStatus(string.IsNullOrEmpty(from.Topic.TopicStatus)
? "OPEN"
: from.Topic.TopicStatus)
.AddDocumentReferences(from.Topic.DocumentReference
.Where(d => !d.IsExternal)
.Select(ConvertDocumentReference).ToList());

var bimSnippet = topic.BimSnippet;
Expand Down Expand Up @@ -113,8 +123,9 @@ private static Model.Bcf30.DocumentReference ConvertDocumentReference(

builder
.SetGuid(from.Guid ??= Guid.NewGuid().ToString())
.SetUrl(from.IsExternal ? from.ReferencedDocument : null)
.SetDocumentGuid(from.IsExternal ? null : Guid.NewGuid().ToString()); //TODO: generate guid based on guid and description
.SetUrl(from.ReferencedDocument)
//TODO: generate guid based on guid and description
.SetDocumentGuid(Guid.NewGuid().ToString());

if (from.Description != string.Empty) {
builder.SetDescription(from.Description);
Expand Down Expand Up @@ -336,15 +347,14 @@ private static Model.Bcf30.Document ConvertDocument(
Model.Bcf21.TopicDocumentReference docReference) {
var builder = new DocumentBuilder();
builder
.SetFileName(docReference.ReferencedDocument)
.SetGuid(docReference.Guid);
.SetFileName(Path.GetFileName(docReference.ReferencedDocument))
.SetGuid(docReference.Guid)
.SetDocumentData(docReference.DocumentData);

if (docReference.Description != string.Empty) {
builder.SetDescription(docReference.Description);
}

return builder.Build();


}
}
Loading

0 comments on commit ceeba06

Please sign in to comment.