Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
XmlExportFormat.cs
1using System;
2using System.IO;
3using System.Threading.Tasks;
4using System.Xml;
5using Waher.Content;
7using Waher.Events;
11
13{
18 {
19 private XmlWriter output;
20 private bool exportCollection = false;
21 private bool inCollection = false;
22 private bool inMetaData = false;
23
33 public XmlExportFormat(string FileName, DateTime Created, XmlWriter Output, FileStream File,
34 bool OnlySelectedCollections, Array SelectedCollections)
35 : base(FileName, Created, File, OnlySelectedCollections, SelectedCollections)
36 {
37 this.output = Output;
38 }
39
41 public override void Dispose()
42 {
43 if (!(this.output is null))
44 {
45 this.output.Flush();
46 this.output.Close();
47 this.output.Dispose();
48 this.output = null;
49 }
50
51 base.Dispose();
52 }
53
58 public override async Task<bool> Start()
59 {
60 await this.output.WriteStartDocumentAsync();
61 await this.output.WriteStartElementAsync(string.Empty, "Export", XmlFileLedger.Namespace);
62
63 return true;
64 }
65
70 public override async Task<bool> End()
71 {
72 await this.output.WriteEndElementAsync();
73 await this.output.WriteEndDocumentAsync();
74
75 return await this.UpdateClient(true);
76 }
77
82 public override async Task<bool> StartDatabase()
83 {
84 await this.output.WriteStartElementAsync(string.Empty, "Database", XmlFileLedger.Namespace);
85 return true;
86 }
87
92 public override async Task<bool> EndDatabase()
93 {
94 await this.output.WriteEndElementAsync();
95
96 return await this.UpdateClient(false);
97 }
98
103 public override async Task<bool> StartLedger()
104 {
105 await this.output.WriteStartElementAsync(string.Empty, "Ledger", XmlFileLedger.Namespace);
106 return true;
107 }
108
113 public override async Task<bool> EndLedger()
114 {
115 await this.output.WriteEndElementAsync();
116 return await this.UpdateClient(false);
117 }
118
124 public override async Task<bool> StartCollection(string CollectionName)
125 {
126 this.inCollection = true;
127 if (this.exportCollection = this.ExportCollection(CollectionName))
128 {
129 await this.output.WriteStartElementAsync(string.Empty, "Collection", XmlFileLedger.Namespace);
130 await this.output.WriteAttributeStringAsync(string.Empty, "name", string.Empty, CollectionName);
131 }
132
133 return true;
134 }
135
140 public override async Task<bool> EndCollection()
141 {
142 this.inCollection = false;
143 if (this.exportCollection)
144 await this.output.WriteEndElementAsync();
145
146 return true;
147 }
148
153 public override async Task<bool> StartIndex()
154 {
155 if (this.exportCollection)
156 await this.output.WriteStartElementAsync(string.Empty, "Index", XmlFileLedger.Namespace);
157
158 return true;
159 }
160
165 public override async Task<bool> EndIndex()
166 {
167 if (this.exportCollection)
168 await this.output.WriteEndElementAsync();
169
170 return true;
171 }
172
179 public override async Task<bool> ReportIndexField(string FieldName, bool Ascending)
180 {
181 if (this.exportCollection)
182 {
183 await this.output.WriteStartElementAsync(string.Empty, "Field", XmlFileLedger.Namespace);
184 await this.output.WriteAttributeStringAsync(string.Empty, "name", string.Empty, FieldName);
185 await this.output.WriteAttributeStringAsync(string.Empty, "ascending", string.Empty, CommonTypes.Encode(Ascending));
186 await this.output.WriteEndElementAsync();
187 }
188
189 return true;
190 }
191
197 public override async Task<bool> StartBlock(string BlockID)
198 {
199 if (this.exportCollection)
200 {
201 await this.output.WriteStartElementAsync(string.Empty, "Block", XmlFileLedger.Namespace);
202 await this.output.WriteAttributeStringAsync(string.Empty, "id", string.Empty, BlockID);
203 }
204
205 return true;
206 }
207
212 public override async Task<bool> EndBlock()
213 {
214 if (this.exportCollection)
215 {
216 if (this.inMetaData)
217 {
218 await this.output.WriteEndElementAsync();
219 this.inMetaData = false;
220 }
221
222 await this.output.WriteEndElementAsync();
223 }
224
225 return true;
226 }
227
234 public override async Task<bool> BlockMetaData(string Key, object Value)
235 {
236 if (this.exportCollection)
237 {
238 if (!this.inMetaData)
239 {
240 await this.output.WriteStartElementAsync(string.Empty, "MetaData", XmlFileLedger.Namespace);
241 this.inMetaData = true;
242 }
243
244 await this.ReportProperty(Key, Value);
245 }
246
247 return true;
248 }
249
255 public override async Task<string> StartObject(string ObjectId, string TypeName)
256 {
257 if (this.exportCollection)
258 {
259 await this.output.WriteStartElementAsync(string.Empty, "Obj", XmlFileLedger.Namespace);
260 await this.output.WriteAttributeStringAsync(string.Empty, "id", string.Empty, ObjectId);
261 await this.output.WriteAttributeStringAsync(string.Empty, "type", string.Empty, TypeName);
262 }
263
264 return ObjectId;
265 }
266
271 public override async Task<bool> EndObject()
272 {
273 if (this.exportCollection)
274 {
275 await this.output.WriteEndElementAsync();
276 return await this.UpdateClient(false);
277 }
278 else
279 return true;
280 }
281
290 public override async Task<bool> StartEntry(string ObjectId, string TypeName, EntryType EntryType, DateTimeOffset EntryTimestamp)
291 {
292 if (this.exportCollection)
293 {
294 if (this.inMetaData)
295 {
296 await this.output.WriteEndElementAsync();
297 this.inMetaData = false;
298 }
299
300 await this.output.WriteStartElementAsync(string.Empty, EntryType.ToString(), XmlFileLedger.Namespace);
301 await this.output.WriteAttributeStringAsync(string.Empty, "id", string.Empty, ObjectId);
302 await this.output.WriteAttributeStringAsync(string.Empty, "type", string.Empty, TypeName);
303 await this.output.WriteAttributeStringAsync(string.Empty, "ts", string.Empty, XML.Encode(EntryTimestamp));
304 }
305
306 return true;
307 }
308
313 public override async Task<bool> EndEntry()
314 {
315 if (this.exportCollection)
316 {
317 await this.output.WriteEndElementAsync();
318 return await this.UpdateClient(false);
319 }
320 else
321 return true;
322 }
323
329 public override async Task<bool> CollectionCleared(DateTimeOffset EntryTimestamp)
330 {
331 if (this.exportCollection)
332 {
333 if (this.inMetaData)
334 {
335 await this.output.WriteEndElementAsync();
336 this.inMetaData = false;
337 }
338
339 await this.output.WriteStartElementAsync(string.Empty, nameof(EntryType.Clear), XmlFileLedger.Namespace);
340 await this.output.WriteAttributeStringAsync(string.Empty, "ts", string.Empty, XML.Encode(EntryTimestamp));
341 }
342
343 return true;
344 }
345
352 public override async Task<bool> ReportProperty(string PropertyName, object PropertyValue)
353 {
354 if (this.exportCollection)
355 await XmlFileLedger.ReportProperty(this.output, PropertyName, PropertyValue, XmlFileLedger.Namespace);
356
357 return true;
358 }
359
365 public override async Task<bool> ReportError(string Message)
366 {
367 if (!this.inCollection || this.exportCollection)
368 await this.output.WriteElementStringAsync(string.Empty, "Error", XmlFileLedger.Namespace, Message);
369
370 return true;
371 }
372
378 public override async Task<bool> ReportException(Exception Exception)
379 {
380 if (!this.inCollection || this.exportCollection)
381 {
382 await this.output.WriteStartElementAsync(string.Empty, "Exception", XmlFileLedger.Namespace);
383 await this.output.WriteAttributeStringAsync(string.Empty, "message", string.Empty, Exception.Message);
384 this.output.WriteElementString("StackTrace", Log.CleanStackTrace(Exception.StackTrace));
385
386 if (Exception is AggregateException AggregateException)
387 {
388 foreach (Exception ex in AggregateException.InnerExceptions)
389 await this.ReportException(ex);
390 }
391 else if (!(Exception.InnerException is null))
392 await this.ReportException(Exception.InnerException);
393
394 await this.output.WriteEndElementAsync();
395 }
396
397 return true;
398 }
399
403 public override async Task<bool> StartFiles()
404 {
405 await this.output.WriteStartElementAsync(string.Empty, "Files", XmlFileLedger.Namespace);
406 return true;
407 }
408
412 public override async Task<bool> EndFiles()
413 {
414 await this.output.WriteEndElementAsync();
415 return true;
416 }
417
424 public override async Task<bool> ExportFile(string FileName, Stream File)
425 {
426 await this.output.WriteStartElementAsync(string.Empty, "File", XmlFileLedger.Namespace);
427
428 await this.output.WriteAttributeStringAsync(string.Empty, "fileName", string.Empty, FileName);
429
430 byte[] Buf = null;
431 long c = File.Length;
432 long i = 0;
433 long d;
434 int j;
435
436 while (i < c)
437 {
438 d = c - i;
439 if (d > 49152)
440 j = 49152;
441 else
442 j = (int)d;
443
444 if (Buf is null)
445 Buf = new byte[j];
446
447 await File.ReadAllAsync(Buf, 0, j);
448
449 this.output.WriteElementString("Chunk", Convert.ToBase64String(Buf, 0, j, Base64FormattingOptions.None));
450 i += j;
451 }
452
453 await this.output.WriteEndElementAsync();
454
455 return true;
456 }
457
458 }
459}
Helps with parsing of commong data types.
Definition: CommonTypes.cs:13
static string Encode(bool x)
Encodes a Boolean for use in XML and other formats.
Definition: CommonTypes.cs:594
Helps with common XML-related tasks.
Definition: XML.cs:19
static string Encode(string s)
Encodes a string for use in XML.
Definition: XML.cs:27
Static class managing the application event log. Applications and services log events on this static ...
Definition: Log.cs:13
static string CleanStackTrace(string StackTrace)
Cleans a Stack Trace string, removing entries from the asynchronous execution model,...
Definition: Log.cs:184
Abstract base class for export formats.
Definition: ExportFormat.cs:14
Task< bool > UpdateClient(bool ForceUpdate)
If any clients should be updated about export status.
bool ExportCollection(string CollectionName)
Checks if a collection is to be exported or not.
Definition: ExportFormat.cs:91
XmlExportFormat(string FileName, DateTime Created, XmlWriter Output, FileStream File, bool OnlySelectedCollections, Array SelectedCollections)
XML File export
override async Task< bool > StartBlock(string BlockID)
Is called when a block in a collection is started.
override async Task< bool > ReportProperty(string PropertyName, object PropertyValue)
Is called when a property is reported.
override async Task< bool > EndLedger()
Is called when export of ledger is finished.
override async Task< bool > ExportFile(string FileName, Stream File)
Export file.
override async Task< bool > EndCollection()
Is called when a collection is finished.
override async Task< bool > EndEntry()
Is called when an entry is finished.
override async Task< string > StartObject(string ObjectId, string TypeName)
Is called when an object is started.
override async Task< bool > StartCollection(string CollectionName)
Is called when a collection is started.
override async Task< bool > EndObject()
Is called when an object is finished.
override async Task< bool > ReportError(string Message)
Is called when an error is reported.
override async Task< bool > StartLedger()
Is called when export of ledger is started.
override async Task< bool > EndFiles()
Ends export of files.
override async Task< bool > StartEntry(string ObjectId, string TypeName, EntryType EntryType, DateTimeOffset EntryTimestamp)
Is called when an entry is started.
override async Task< bool > StartIndex()
Is called when an index in a collection is started.
override async Task< bool > StartFiles()
Starts export of files.
override async Task< bool > End()
Ends export
override async Task< bool > EndBlock()
Is called when a block in a collection is finished.
override async Task< bool > EndIndex()
Is called when an index in a collection is finished.
override async Task< bool > BlockMetaData(string Key, object Value)
Reports block meta-data.
override async Task< bool > ReportIndexField(string FieldName, bool Ascending)
Is called when a field in an index is reported.
override async Task< bool > CollectionCleared(DateTimeOffset EntryTimestamp)
Is called when a collection has been cleared.
override async Task< bool > StartDatabase()
Is called when export of database is started.
override async Task< bool > Start()
Starts export
override async Task< bool > ReportException(Exception Exception)
Is called when an exception has occurred.
override async Task< bool > EndDatabase()
Is called when export of database is finished.
Simple ledger that records anything that happens in the database to XML files in the program data fol...
const string Namespace
http://waher.se/Schema/Export.xsd
static async Task ReportProperty(XmlWriter Output, string PropertyName, object PropertyValue, string Namespace)
Serializes a property to XML.
EntryType
Ledger entry type.
Definition: ILedgerEntry.cs:9