Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
ContactInfo.cs
2using System.Globalization;
3using System.Text;
9
11{
15 [CollectionName("ContactInformation")]
16 [TypeName(TypeNameSerialization.None)]
17 [Index("BareJid", "SourceId", "Partition", "NodeId")]
18 [Index("IsThing", "BareJid", "SourceId", "Partition", "NodeId")]
19 [Index("LegalId")]
20 public class ContactInfo
21 {
22 private string? objectId = null;
25 private LegalIdentity? legalIdentity = null;
26 private Property[]? metaData = null;
27 private string friendlyName = string.Empty;
28 private string sourceId = string.Empty;
29 private string partition = string.Empty;
30 private string nodeId = string.Empty;
31 private CaseInsensitiveString registryJid = string.Empty;
32 private bool? subscribeTo = null;
33 private bool? allowSubscriptionFrom = null;
34 private bool? isThing = null;
35 private bool? isSensor = null;
36 private bool? isActuator = null;
37 private bool? isConcentrator = null;
38 private bool? supportsSensorEvents = null;
39 private bool? owner = null;
40
44 public ContactInfo()
45 {
46 }
47
51 [ObjectId]
52 public string? ObjectId
53 {
54 get => this.objectId;
55 set => this.objectId = value;
56 }
57
62 {
63 get => this.bareJid;
64 set => this.bareJid = value;
65 }
66
71 {
72 get => this.legalId;
73 set => this.legalId = value;
74 }
75
79 [DefaultValueNull]
81 {
82 get => this.legalIdentity;
83 set => this.legalIdentity = value;
84 }
85
89 [DefaultValueStringEmpty]
90 public string FriendlyName
91 {
92 get => this.friendlyName;
93 set => this.friendlyName = value;
94 }
95
99 public string SourceId
100 {
101 get => this.sourceId;
102 set => this.sourceId = value;
103 }
104
108 public string Partition
109 {
110 get => this.partition;
111 set => this.partition = value;
112 }
113
117 public string NodeId
118 {
119 get => this.nodeId;
120 set => this.nodeId = value;
121 }
122
127 {
128 get => this.registryJid;
129 set => this.registryJid = value;
130 }
131
135 public bool? SubscribeTo
136 {
137 get => this.subscribeTo;
138 set => this.subscribeTo = value;
139 }
140
145 {
146 get => this.allowSubscriptionFrom;
147 set => this.allowSubscriptionFrom = value;
148 }
149
153 public bool? IsThing
154 {
155 get => this.isThing;
156 set => this.isThing = value;
157 }
158
162 public bool? IsSensor
163 {
164 get => this.isSensor;
165 set => this.isSensor = value;
166 }
167
172 {
173 get => this.supportsSensorEvents;
174 set => this.supportsSensorEvents = value;
175 }
176
180 public bool? IsActuator
181 {
182 get => this.isActuator;
183 set => this.isActuator = value;
184 }
185
189 public bool? IsConcentrator
190 {
191 get => this.isConcentrator;
192 set => this.isConcentrator = value;
193 }
194
198 [DefaultValueNull]
199 public bool? Owner
200 {
201 get => this.owner;
202 set => this.owner = value;
203 }
204
208 [DefaultValueNull]
210 {
211 get => this.metaData;
212 set => this.metaData = value;
213 }
214
220 public static Task<ContactInfo> FindByBareJid(string BareJid)
221 {
222 return Database.FindFirstIgnoreRest<ContactInfo>(new FilterFieldEqualTo("BareJid", BareJid));
223 }
224
233 public static Task<ContactInfo> FindByBareJid(string BareJid, string SourceId, string Partition, string NodeId)
234 {
235 return Database.FindFirstIgnoreRest<ContactInfo>(new FilterAnd(
236 new FilterFieldEqualTo("BareJid", BareJid),
237 new FilterFieldEqualTo("SourceId", SourceId),
238 new FilterFieldEqualTo("Partition", Partition),
239 new FilterFieldEqualTo("NodeId", NodeId)));
240 }
241
247 public static Task<ContactInfo> FindByLegalId(string LegalId)
248 {
249 return Database.FindFirstIgnoreRest<ContactInfo>(new FilterFieldEqualTo("LegalId", LegalId));
250 }
251
257 public static async Task<string> GetFriendlyName(CaseInsensitiveString RemoteId)
258 {
259 int i = RemoteId.IndexOf('@');
260
261 if (i < 0)
262 return RemoteId;
263
264 if (RemoteId == ServiceRef.TagProfile.LegalIdentity?.Id)
265 return ServiceRef.Localizer[nameof(AppResources.Me)];
266
267 string Account = RemoteId.Substring(0, i);
268 ContactInfo Info;
269 bool AccountIsGuid;
270
271 if (AccountIsGuid = Guid.TryParse(Account, out Guid _))
272 {
273 Info = await FindByLegalId(RemoteId);
274
275 if (!string.IsNullOrEmpty(Info?.FriendlyName))
276 return Info.FriendlyName;
277
278 if (Info?.LegalIdentity is not null)
279 return GetFriendlyName(Info.LegalIdentity);
280 }
281
282 Info = await FindByBareJid(RemoteId);
283 if (Info is not null)
284 {
285 if (!string.IsNullOrEmpty(Info.FriendlyName))
286 return Info.FriendlyName;
287
288 if (Info.LegalIdentity is not null)
289 return GetFriendlyName(Info.LegalIdentity);
290
291 if (Info.MetaData is not null)
292 {
293 string? s = GetFriendlyName(Info.MetaData);
294
295 if (!string.IsNullOrEmpty(s))
296 return s;
297 }
298 }
299
300 RosterItem? Item = ServiceRef.XmppService.GetRosterItem(RemoteId);
301 if (Item is not null)
302 return Item.NameOrBareJid;
303
304 lock (identityCache)
305 if (identityCache.TryGetValue(RemoteId, out LegalIdentity? Id))
306 if (Id is not null)
307 return GetFriendlyName(Id);
308 else
309 AccountIsGuid = false;
310
311 if (AccountIsGuid)
312 {
313 lock (identityCache)
314 identityCache[RemoteId] = null;
315
316 Task _ = Task.Run(async () =>
317 {
318 try
319 {
320 LegalIdentity Id = await ServiceRef.XmppService.GetLegalIdentity(RemoteId);
321
322 lock (identityCache)
323 identityCache[RemoteId] = Id;
324 }
325 catch (Exception)
326 {
327 // Ignore
328 }
329 });
330 }
331
332 return RemoteId;
333 }
334
335 private static readonly Dictionary<CaseInsensitiveString, LegalIdentity?> identityCache = [];
336
342 public static async Task<string[]?> GetFriendlyName(string[] RemoteId)
343 {
344 if (RemoteId is null)
345 return null;
346
347 int i, c = RemoteId.Length;
348 string[] Result = new string[c];
349
350 for (i = 0; i < c; i++)
351 Result[i] = await GetFriendlyName(RemoteId[i]);
352
353 return Result;
354 }
355
361 public static string? GetFriendlyName(IEnumerable<Property> MetaData)
362 {
363 string? Apartment = null;
364 string? Area = null;
365 string? Building = null;
366 string? City = null;
367 string? Class = null;
368 string? Country = null;
369 string? Manufacturer = null;
370 string? MeterLocation = null;
371 string? MeterNumber = null;
372 string? Model = null;
373 string? Name = null;
374 string? Region = null;
375 string? Room = null;
376 string? SerialNumber = null;
377 string? Street = null;
378 string? StreetNumber = null;
379 string? Version = null;
380 string? Phone = null;
381
382 foreach (Property P in MetaData)
383 switch (P.Name.ToUpper(CultureInfo.InvariantCulture))
384 {
386 Apartment = P.Value;
387 break;
388
390 Area = P.Value;
391 break;
392
394 Building = P.Value;
395 break;
396
398 City = P.Value;
399 break;
400
402 Country = P.Value;
403 break;
404
406 Region = P.Value;
407 break;
408
410 Room = P.Value;
411 break;
412
414 Street = P.Value;
415 break;
416
418 StreetNumber = P.Value;
419 break;
420
422 Class = P.Value;
423 break;
424
426 Manufacturer = P.Value;
427 break;
428
430 MeterLocation = P.Value;
431 break;
432
434 MeterNumber = P.Value;
435 break;
436
438 Model = P.Value;
439 break;
440
442 Name = P.Value;
443 break;
444
446 SerialNumber = P.Value;
447 break;
448
450 Version = P.Value;
451 break;
452
454 Phone = P.Value;
455 break;
456 }
457
458 StringBuilder? sb = null;
459
460 AppendName(ref sb, Class);
461 AppendName(ref sb, Model);
462 AppendName(ref sb, Version);
463 AppendName(ref sb, Room);
464 AppendName(ref sb, Name);
465 AppendName(ref sb, Apartment);
466 AppendName(ref sb, Building);
467 AppendName(ref sb, Street);
468 AppendName(ref sb, StreetNumber);
469 AppendName(ref sb, Area);
470 AppendName(ref sb, City);
471 AppendName(ref sb, Region);
472 AppendName(ref sb, Country);
473 AppendName(ref sb, MeterNumber);
474 AppendName(ref sb, MeterLocation);
475 AppendName(ref sb, Manufacturer);
476 AppendName(ref sb, SerialNumber);
477 AppendName(ref sb, Phone);
478
479 return sb?.ToString();
480 }
481
487 public static string GetFriendlyName(LegalIdentity? Identity)
488 {
489 if (Identity is null)
490 return string.Empty;
491
492 string? FirstName = null;
493 string? MiddleName = null;
494 string? LastName = null;
495 string? PersonalNumber = null;
496 string? Domain = null;
497 string? OrgDepartment = null;
498 string? OrgRole = null;
499 string? OrgName = null;
500 bool HasName = false;
501 bool HasOrg = false;
502 bool HasDomain = false;
503
504 foreach (Property P in Identity.Properties)
505 {
506 switch (P.Name.ToUpper(CultureInfo.InvariantCulture))
507 {
509 FirstName = P.Value;
510 HasName = true;
511 break;
512
514 MiddleName = P.Value;
515 HasName = true;
516 break;
517
519 LastName = P.Value;
520 HasName = true;
521 break;
522
524 PersonalNumber = P.Value;
525 break;
526
528 OrgName = P.Value;
529 HasOrg = true;
530 break;
531
533 OrgDepartment = P.Value;
534 HasOrg = true;
535 break;
536
538 OrgRole = P.Value;
539 HasOrg = true;
540 break;
541
543 Domain = P.Value;
544 HasDomain = true;
545 break;
546 }
547 }
548
549 StringBuilder? sb = null;
550
551 if (HasName)
552 {
553 AppendName(ref sb, FirstName);
554 AppendName(ref sb, MiddleName);
555 AppendName(ref sb, LastName);
556 }
557
558 if (HasOrg)
559 {
560 AppendName(ref sb, OrgRole);
561 AppendName(ref sb, OrgDepartment);
562 AppendName(ref sb, OrgName);
563 }
564
565 string Result = sb is not null ? sb.ToString() : !string.IsNullOrEmpty(PersonalNumber) ? PersonalNumber : Identity.Id;
566
567 if (HasDomain)
568 Result = Domain + " (" + Result + ")";
569
570 return Result;
571 }
572
577 public static string GetFullName(LegalIdentity? Identity)
578 {
579 string? FirstName = null;
580 string? MiddleNames = null;
581 string? LastNames = null;
582
583 if (Identity?.Properties is not null)
584 foreach (Property P in Identity.Properties)
585 switch (P.Name)
586 {
588 FirstName = P.Value;
589 break;
590
592 LastNames = P.Value;
593 break;
594
596 MiddleNames = P.Value;
597 break;
598 }
599
600 return GetFullName(FirstName, MiddleNames, LastNames);
601 }
602
609 public static string GetFullName(string? FirstName, string? MiddleNames, string? LastNames)
610 {
611 StringBuilder? sb = null;
612
613 AppendName(ref sb, FirstName);
614 AppendName(ref sb, MiddleNames);
615 AppendName(ref sb, LastNames);
616
617 return sb?.ToString() ?? string.Empty;
618 }
619
625 internal static void AppendName(ref StringBuilder? sb, string? Value)
626 {
627 if (!string.IsNullOrEmpty(Value))
628 {
629 if (sb is null)
630 sb = new StringBuilder();
631 else
632 sb.Append(' ');
633
634 sb.Append(Value);
635 }
636 }
637
646 public static async Task<string> GetFriendlyName(CaseInsensitiveString BareJid, string SourceId, string PartitionId, string NodeId)
647 {
648 if (string.IsNullOrEmpty(NodeId) && string.IsNullOrEmpty(PartitionId) && string.IsNullOrEmpty(SourceId))
649 return await GetFriendlyName(BareJid);
650
651 ContactInfo Thing = await FindByBareJid(BareJid, SourceId, PartitionId, NodeId);
652
653 if (Thing is not null)
654 return Thing.FriendlyName;
655
656 string s = NodeId;
657
658 if (!string.IsNullOrEmpty(PartitionId))
659 if (string.IsNullOrEmpty(s))
660 s = PartitionId;
661 else
662 s = ServiceRef.Localizer[nameof(AppResources.XInY), s, PartitionId];
663
664 if (!string.IsNullOrEmpty(SourceId))
665 if (string.IsNullOrEmpty(s))
666 s = SourceId;
667 else
668 s = ServiceRef.Localizer[nameof(AppResources.XInY), s, SourceId];
669
670 return ServiceRef.Localizer[nameof(AppResources.XOnY), s, BareJid];
671 }
672
678 public string this[string PropertyName]
679 {
680 get
681 {
682 if (this.metaData is not null)
683 foreach (Property P in this.metaData)
684 if (string.Equals(P.Name, PropertyName, StringComparison.OrdinalIgnoreCase))
685 return P.Value;
686
687 return string.Empty;
688 }
689 }
690
695 {
696 get
697 {
698 return GetThingNotificationCategoryKey(this.bareJid, this.nodeId, this.sourceId, this.partition);
699 }
700 }
701
710 public static string GetThingNotificationCategoryKey(string BareJid, string? NodeId, string? SourceId, string? Partition)
711 {
712 StringBuilder sb = new();
713
714 sb.Append(BareJid);
715 sb.Append('|');
716
717 if (SourceId is not null)
718 sb.Append(SourceId);
719
720 sb.Append('|');
721
722 if (Partition is not null)
723 sb.Append(Partition);
724
725 sb.Append('|');
726
727 if (NodeId is not null)
728 sb.Append(NodeId);
729
730 return sb.ToString();
731 }
732 }
733}
const string MeterNumber
MeterNumber
Definition: Constants.cs:479
const string PersonalNumber
Personal number
Definition: Constants.cs:284
const string SerialNumber
Serial Number
Definition: Constants.cs:504
const string OrgRole
Organization Role
Definition: Constants.cs:399
const string StreetName
Street Name
Definition: Constants.cs:509
const string Phone
Phone number
Definition: Constants.cs:414
const string MiddleNames
Middle names
Definition: Constants.cs:274
const string OrgDepartment
Organization Department
Definition: Constants.cs:394
const string Domain
Domain name.
Definition: Constants.cs:424
const string StreetNumber
Street Number
Definition: Constants.cs:514
const string LastNames
Last names
Definition: Constants.cs:279
const string MeterLocation
Meter Location
Definition: Constants.cs:474
const string Manufacturer
Manufacturer
Definition: Constants.cs:469
const string FirstName
First name
Definition: Constants.cs:269
const string OrgName
Organization name
Definition: Constants.cs:349
A set of never changing property constants and helpful values.
Definition: Constants.cs:7
Contains information about a contact.
Definition: ContactInfo.cs:21
Property?[] MetaData
Meta-data related to a thing.
Definition: ContactInfo.cs:210
static string GetFullName(string? FirstName, string? MiddleNames, string? LastNames)
Gets the full name of a person.
Definition: ContactInfo.cs:609
bool? Owner
If the account is registered as the owner of the thing.
Definition: ContactInfo.cs:200
static string GetFriendlyName(LegalIdentity? Identity)
Gets the friendly name of a legal identity.
Definition: ContactInfo.cs:487
bool? SubscribeTo
Subscribe to this contact
Definition: ContactInfo.cs:136
CaseInsensitiveString RegistryJid
Registry JID
Definition: ContactInfo.cs:127
ContactInfo()
Contains information about a contact.
Definition: ContactInfo.cs:44
static async Task< string > GetFriendlyName(CaseInsensitiveString RemoteId)
Gets the friendly name of a remote identity (Legal ID or Bare JID).
Definition: ContactInfo.cs:257
static async Task< string > GetFriendlyName(CaseInsensitiveString BareJid, string SourceId, string PartitionId, string NodeId)
Gets the friendly name of a thing.
Definition: ContactInfo.cs:646
LegalIdentity? LegalIdentity
Legal Identity object.
Definition: ContactInfo.cs:81
string ThingNotificationCategoryKey
Category key used for thing notifications.
Definition: ContactInfo.cs:695
static Task< ContactInfo > FindByBareJid(string BareJid, string SourceId, string Partition, string NodeId)
Finds information about a contact, given its Bare JID.
Definition: ContactInfo.cs:233
bool? IsSensor
The contact is a sensor
Definition: ContactInfo.cs:163
bool? IsConcentrator
The contact is a concentrator
Definition: ContactInfo.cs:190
static async Task< string[]?> GetFriendlyName(string[] RemoteId)
Gets the friendly name of a remote identity (Legal ID or Bare JID).
Definition: ContactInfo.cs:342
bool? AllowSubscriptionFrom
Allow subscriptions from this contact
Definition: ContactInfo.cs:145
static string GetFullName(LegalIdentity? Identity)
Gets the full name of a person.
Definition: ContactInfo.cs:577
bool? IsActuator
The contact is a actuator
Definition: ContactInfo.cs:181
bool? SupportsSensorEvents
The contact supports sensor events
Definition: ContactInfo.cs:172
static Task< ContactInfo > FindByLegalId(string LegalId)
Finds information about a contact, given its Legal ID.
Definition: ContactInfo.cs:247
static Task< ContactInfo > FindByBareJid(string BareJid)
Finds information about a contact, given its Bare JID.
Definition: ContactInfo.cs:220
static string GetThingNotificationCategoryKey(string BareJid, string? NodeId, string? SourceId, string? Partition)
Category key used for thing notifications.
Definition: ContactInfo.cs:710
CaseInsensitiveString LegalId
Legal ID of contact.
Definition: ContactInfo.cs:71
CaseInsensitiveString BareJid
Bare JID of contact.
Definition: ContactInfo.cs:62
static ? string GetFriendlyName(IEnumerable< Property > MetaData)
Gets the friendly name from a set of meta-data tags.
Definition: ContactInfo.cs:361
Base class that references services in the app.
Definition: ServiceRef.cs:31
static ITagProfile TagProfile
TAG Profile service.
Definition: ServiceRef.cs:79
static IStringLocalizer Localizer
Localization service
Definition: ServiceRef.cs:235
static IXmppService XmppService
The XMPP service for XMPP communication.
Definition: ServiceRef.cs:67
Maintains information about an item in the roster.
Definition: RosterItem.cs:75
string NameOrBareJid
Returns the name of the contact, or the Bare JID, if there's no name provided.
Definition: RosterItem.cs:436
Represents a case-insensitive string.
static readonly CaseInsensitiveString Empty
Empty case-insensitive string
int IndexOf(CaseInsensitiveString value, StringComparison comparisonType)
Reports the zero-based index of the first occurrence of the specified string in the current System....
CaseInsensitiveString Substring(int startIndex, int length)
Retrieves a substring from this instance. The substring starts at a specified character position and ...
Static interface for database persistence. In order to work, a database provider has to be assigned t...
Definition: Database.cs:19
This filter selects objects that conform to all child-filters provided.
Definition: FilterAnd.cs:10
This filter selects objects that have a named field equal to a given value.
TypeNameSerialization
How the type name should be serialized.