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
83 public override async Task<bool> StartDatabase(IDatabaseProvider Provider)
84 {
85 await this.output.WriteStartElementAsync(string.Empty, "Database", XmlFileLedger.Namespace);
86
87 if (!(Provider is null))
88 await this.output.WriteAttributeStringAsync(string.Empty, "provider", string.Empty, Provider.GetType().FullName);
89
90 return true;
91 }
92
97 public override async Task<bool> EndDatabase()
98 {
99 await this.output.WriteEndElementAsync();
100
101 return await this.UpdateClient(false);
102 }
103
109 public override async Task<bool> StartLedger(ILedgerProvider Provider)
110 {
111 await this.output.WriteStartElementAsync(string.Empty, "Ledger", XmlFileLedger.Namespace);
112
113 if (!(Provider is null))
114 await this.output.WriteAttributeStringAsync(string.Empty, "provider", string.Empty, Provider.GetType().FullName);
115
116 return true;
117 }
118
123 public override async Task<bool> EndLedger()
124 {
125 await this.output.WriteEndElementAsync();
126 return await this.UpdateClient(false);
127 }
128
134 public override async Task<bool> StartCollection(string CollectionName)
135 {
136 this.inCollection = true;
137 if (this.exportCollection = this.ExportCollection(CollectionName))
138 {
139 await this.output.WriteStartElementAsync(string.Empty, "Collection", XmlFileLedger.Namespace);
140 await this.output.WriteAttributeStringAsync(string.Empty, "name", string.Empty, CollectionName);
141 }
142
143 return true;
144 }
145
150 public override async Task<bool> EndCollection()
151 {
152 this.inCollection = false;
153 if (this.exportCollection)
154 await this.output.WriteEndElementAsync();
155
156 return true;
157 }
158
163 public override async Task<bool> StartIndex()
164 {
165 if (this.exportCollection)
166 await this.output.WriteStartElementAsync(string.Empty, "Index", XmlFileLedger.Namespace);
167
168 return true;
169 }
170
175 public override async Task<bool> EndIndex()
176 {
177 if (this.exportCollection)
178 await this.output.WriteEndElementAsync();
179
180 return true;
181 }
182
189 public override async Task<bool> ReportIndexField(string FieldName, bool Ascending)
190 {
191 if (this.exportCollection)
192 {
193 await this.output.WriteStartElementAsync(string.Empty, "Field", XmlFileLedger.Namespace);
194 await this.output.WriteAttributeStringAsync(string.Empty, "name", string.Empty, FieldName);
195 await this.output.WriteAttributeStringAsync(string.Empty, "ascending", string.Empty, CommonTypes.Encode(Ascending));
196 await this.output.WriteEndElementAsync();
197 }
198
199 return true;
200 }
201
207 public override async Task<bool> StartBlock(string BlockID)
208 {
209 if (this.exportCollection)
210 {
211 await this.output.WriteStartElementAsync(string.Empty, "Block", XmlFileLedger.Namespace);
212 await this.output.WriteAttributeStringAsync(string.Empty, "id", string.Empty, BlockID);
213 }
214
215 return true;
216 }
217
222 public override async Task<bool> EndBlock()
223 {
224 if (this.exportCollection)
225 {
226 if (this.inMetaData)
227 {
228 await this.output.WriteEndElementAsync();
229 this.inMetaData = false;
230 }
231
232 await this.output.WriteEndElementAsync();
233 }
234
235 return true;
236 }
237
244 public override async Task<bool> BlockMetaData(string Key, object Value)
245 {
246 if (this.exportCollection)
247 {
248 if (!this.inMetaData)
249 {
250 await this.output.WriteStartElementAsync(string.Empty, "MetaData", XmlFileLedger.Namespace);
251 this.inMetaData = true;
252 }
253
254 await this.ReportProperty(Key, Value);
255 }
256
257 return true;
258 }
259
265 public override async Task<string> StartObject(string ObjectId, string TypeName)
266 {
267 if (this.exportCollection)
268 {
269 await this.output.WriteStartElementAsync(string.Empty, "Obj", XmlFileLedger.Namespace);
270 await this.output.WriteAttributeStringAsync(string.Empty, "id", string.Empty, ObjectId);
271 await this.output.WriteAttributeStringAsync(string.Empty, "type", string.Empty, TypeName);
272 }
273
274 return ObjectId;
275 }
276
281 public override async Task<bool> EndObject()
282 {
283 if (this.exportCollection)
284 {
285 await this.output.WriteEndElementAsync();
286 return await this.UpdateClient(false);
287 }
288 else
289 return true;
290 }
291
300 public override async Task<bool> StartEntry(string ObjectId, string TypeName, EntryType EntryType, DateTimeOffset EntryTimestamp)
301 {
302 if (this.exportCollection)
303 {
304 if (this.inMetaData)
305 {
306 await this.output.WriteEndElementAsync();
307 this.inMetaData = false;
308 }
309
310 await this.output.WriteStartElementAsync(string.Empty, EntryType.ToString(), XmlFileLedger.Namespace);
311 await this.output.WriteAttributeStringAsync(string.Empty, "id", string.Empty, ObjectId);
312 await this.output.WriteAttributeStringAsync(string.Empty, "type", string.Empty, TypeName);
313 await this.output.WriteAttributeStringAsync(string.Empty, "ts", string.Empty, XML.Encode(EntryTimestamp));
314 }
315
316 return true;
317 }
318
323 public override async Task<bool> EndEntry()
324 {
325 if (this.exportCollection)
326 {
327 await this.output.WriteEndElementAsync();
328 return await this.UpdateClient(false);
329 }
330 else
331 return true;
332 }
333
339 public override async Task<bool> CollectionCleared(DateTimeOffset EntryTimestamp)
340 {
341 if (this.exportCollection)
342 {
343 if (this.inMetaData)
344 {
345 await this.output.WriteEndElementAsync();
346 this.inMetaData = false;
347 }
348
349 await this.output.WriteStartElementAsync(string.Empty, nameof(EntryType.Clear), XmlFileLedger.Namespace);
350 await this.output.WriteAttributeStringAsync(string.Empty, "ts", string.Empty, XML.Encode(EntryTimestamp));
351 }
352
353 return true;
354 }
355
362 public override async Task<bool> ReportProperty(string PropertyName, object PropertyValue)
363 {
364 if (this.exportCollection)
365 await XmlFileLedger.ReportProperty(this.output, PropertyName, PropertyValue, XmlFileLedger.Namespace);
366
367 return true;
368 }
369
375 public override async Task<bool> ReportError(string Message)
376 {
377 if (!this.inCollection || this.exportCollection)
378 await this.output.WriteElementStringAsync(string.Empty, "Error", XmlFileLedger.Namespace, Message);
379
380 return true;
381 }
382
388 public override async Task<bool> ReportException(Exception Exception)
389 {
390 if (!this.inCollection || this.exportCollection)
391 {
392 await this.output.WriteStartElementAsync(string.Empty, "Exception", XmlFileLedger.Namespace);
393 await this.output.WriteAttributeStringAsync(string.Empty, "message", string.Empty, Exception.Message);
394 this.output.WriteElementString("StackTrace", Log.CleanStackTrace(Exception.StackTrace));
395
396 if (Exception is AggregateException AggregateException)
397 {
398 foreach (Exception ex in AggregateException.InnerExceptions)
399 await this.ReportException(ex);
400 }
401 else if (!(Exception.InnerException is null))
402 await this.ReportException(Exception.InnerException);
403
404 await this.output.WriteEndElementAsync();
405 }
406
407 return true;
408 }
409
413 public override async Task<bool> StartFiles()
414 {
415 await this.output.WriteStartElementAsync(string.Empty, "Files", XmlFileLedger.Namespace);
416 return true;
417 }
418
422 public override async Task<bool> EndFiles()
423 {
424 await this.output.WriteEndElementAsync();
425 return true;
426 }
427
434 public override async Task<bool> ExportFile(string FileName, Stream File)
435 {
436 await this.output.WriteStartElementAsync(string.Empty, "File", XmlFileLedger.Namespace);
437
438 await this.output.WriteAttributeStringAsync(string.Empty, "fileName", string.Empty, FileName);
439
440 byte[] Buf = null;
441 long c = File.Length;
442 long i = 0;
443 long d;
444 int j;
445
446 while (i < c)
447 {
448 d = c - i;
449 if (d > 49152)
450 j = 49152;
451 else
452 j = (int)d;
453
454 if (Buf is null)
455 Buf = new byte[j];
456
457 await File.ReadAllAsync(Buf, 0, j);
458
459 this.output.WriteElementString("Chunk", Convert.ToBase64String(Buf, 0, j, Base64FormattingOptions.None));
460 i += j;
461 }
462
463 await this.output.WriteEndElementAsync();
464
465 return true;
466 }
467
468 }
469}
Helps with parsing of commong data types.
Definition: CommonTypes.cs:15
static string Encode(bool x)
Encodes a Boolean for use in XML and other formats.
Definition: CommonTypes.cs:596
Helps with common XML-related tasks.
Definition: XML.cs:21
static string Encode(string s)
Encodes a string for use in XML.
Definition: XML.cs:29
Static class managing the application event log. Applications and services log events on this static ...
Definition: Log.cs:14
static string CleanStackTrace(string StackTrace)
Cleans a Stack Trace string, removing entries from the asynchronous execution model,...
Definition: Log.cs:194
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 > StartDatabase(IDatabaseProvider Provider)
Is called when export of database is started.
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 > EndFiles()
Ends export of files.
override async Task< bool > StartLedger(ILedgerProvider Provider)
Is called when export of ledger is started.
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 > 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.
Interface for database providers that can be plugged into the static Database class.
Interface for ledger providers that can be plugged into the static Ledger class.
EntryType
Ledger entry type.
Definition: ILedgerEntry.cs:9