Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
ContactInfo.cs
3using System.Globalization;
4using System.Text;
10
12{
16 [CollectionName("ContactInformation")]
17 [TypeName(TypeNameSerialization.None)]
18 [Index("BareJid", "SourceId", "Partition", "NodeId")]
19 [Index("IsThing", "BareJid", "SourceId", "Partition", "NodeId")]
20 [Index("LegalId")]
21 public class ContactInfo
22 {
23 private string? objectId = null;
26 private LegalIdentity? legalIdentity = null;
27 private Property[]? metaData = null;
28 private string friendlyName = string.Empty;
29 private string sourceId = string.Empty;
30 private string partition = string.Empty;
31 private string nodeId = string.Empty;
32 private CaseInsensitiveString registryJid = string.Empty;
33 private bool? subscribeTo = null;
34 private bool? allowSubscriptionFrom = null;
35 private bool? isThing = null;
36 private bool? isSensor = null;
37 private bool? isActuator = null;
38 private bool? isConcentrator = null;
39 private bool? supportsSensorEvents = null;
40 private bool? owner = null;
41
45 public ContactInfo()
46 {
47 }
48
52 [ObjectId]
53 public string? ObjectId
54 {
55 get => this.objectId;
56 set => this.objectId = value;
57 }
58
63 {
64 get => this.bareJid;
65 set => this.bareJid = value;
66 }
67
72 {
73 get => this.legalId;
74 set => this.legalId = value;
75 }
76
80 [DefaultValueNull]
82 {
83 get => this.legalIdentity;
84 set => this.legalIdentity = value;
85 }
86
90 [DefaultValueStringEmpty]
91 public string FriendlyName
92 {
93 get => this.friendlyName;
94 set => this.friendlyName = value;
95 }
96
100 public string SourceId
101 {
102 get => this.sourceId;
103 set => this.sourceId = value;
104 }
105
109 public string Partition
110 {
111 get => this.partition;
112 set => this.partition = value;
113 }
114
118 public string NodeId
119 {
120 get => this.nodeId;
121 set => this.nodeId = value;
122 }
123
128 {
129 get => this.registryJid;
130 set => this.registryJid = value;
131 }
132
136 public bool? SubscribeTo
137 {
138 get => this.subscribeTo;
139 set => this.subscribeTo = value;
140 }
141
146 {
147 get => this.allowSubscriptionFrom;
148 set => this.allowSubscriptionFrom = value;
149 }
150
154 public bool? IsThing
155 {
156 get => this.isThing;
157 set => this.isThing = value;
158 }
159
163 public bool? IsSensor
164 {
165 get => this.isSensor;
166 set => this.isSensor = value;
167 }
168
173 {
174 get => this.supportsSensorEvents;
175 set => this.supportsSensorEvents = value;
176 }
177
181 public bool? IsActuator
182 {
183 get => this.isActuator;
184 set => this.isActuator = value;
185 }
186
190 public bool? IsConcentrator
191 {
192 get => this.isConcentrator;
193 set => this.isConcentrator = value;
194 }
195
199 [DefaultValueNull]
200 public bool? Owner
201 {
202 get => this.owner;
203 set => this.owner = value;
204 }
205
209 [DefaultValueNull]
211 {
212 get => this.metaData;
213 set => this.metaData = value;
214 }
215
221 public static Task<ContactInfo> FindByBareJid(string BareJid)
222 {
223 return Database.FindFirstIgnoreRest<ContactInfo>(new FilterFieldEqualTo("BareJid", BareJid));
224 }
225
234 public static Task<ContactInfo> FindByBareJid(string BareJid, string SourceId, string Partition, string NodeId)
235 {
236 return Database.FindFirstIgnoreRest<ContactInfo>(new FilterAnd(
237 new FilterFieldEqualTo("BareJid", BareJid),
238 new FilterFieldEqualTo("SourceId", SourceId),
239 new FilterFieldEqualTo("Partition", Partition),
240 new FilterFieldEqualTo("NodeId", NodeId)));
241 }
242
248 public static async Task<ContactInfo?> FindByLegalId(string LegalId)
249 {
250 return await Database.FindFirstIgnoreRest<ContactInfo>(new FilterFieldEqualTo("LegalId", LegalId));
251 }
252
258 public static async Task<string> GetFriendlyName(CaseInsensitiveString RemoteId)
259 {
260 int i = RemoteId.IndexOf('@');
261
262 if (i < 0)
263 return RemoteId;
264
265 if (RemoteId == ServiceRef.TagProfile.LegalIdentity?.Id)
266 return ServiceRef.Localizer[nameof(AppResources.Me)];
267
268 string Account = RemoteId.Substring(0, i);
269 ContactInfo? Info;
270 bool AccountIsGuid;
271
272 if (AccountIsGuid = Guid.TryParse(Account, out Guid _))
273 {
274 Info = await FindByLegalId(RemoteId);
275
276 if (!string.IsNullOrEmpty(Info?.FriendlyName))
277 return Info.FriendlyName;
278
279 if (Info?.LegalIdentity is not null)
280 return GetFriendlyName(Info.LegalIdentity);
281 }
282
283 Info = await FindByBareJid(RemoteId);
284 if (Info is not null)
285 {
286 if (!string.IsNullOrEmpty(Info.FriendlyName))
287 return Info.FriendlyName;
288
289 if (Info.LegalIdentity is not null)
290 return GetFriendlyName(Info.LegalIdentity);
291
292 if (Info.MetaData is not null)
293 {
294 string? s = GetFriendlyName(Info.MetaData);
295
296 if (!string.IsNullOrEmpty(s))
297 return s;
298 }
299 }
300
301 RosterItem? Item = ServiceRef.XmppService.GetRosterItem(RemoteId);
302 if (Item is not null)
303 return Item.NameOrBareJid;
304
305 lock (identityCache)
306 if (identityCache.TryGetValue(RemoteId, out LegalIdentity? Id))
307 if (Id is not null)
308 return GetFriendlyName(Id);
309 else
310 AccountIsGuid = false;
311
312 if (AccountIsGuid)
313 {
314 lock (identityCache)
315 identityCache[RemoteId] = null;
316
317 Task _ = Task.Run(async () =>
318 {
319 try
320 {
321 LegalIdentity Id = await ServiceRef.XmppService.GetLegalIdentity(RemoteId);
322
323 lock (identityCache)
324 identityCache[RemoteId] = Id;
325 }
326 catch (Exception)
327 {
328 // Ignore
329 }
330 });
331 }
332
333 return RemoteId;
334 }
335
336 private static readonly Dictionary<CaseInsensitiveString, LegalIdentity?> identityCache = [];
337
343 public static async Task<string[]?> GetFriendlyName(string[] RemoteId)
344 {
345 if (RemoteId is null)
346 return null;
347
348 int i, c = RemoteId.Length;
349 string[] Result = new string[c];
350
351 for (i = 0; i < c; i++)
352 Result[i] = await GetFriendlyName(RemoteId[i]);
353
354 return Result;
355 }
356
362 public static string? GetFriendlyName(IEnumerable<Property> MetaData)
363 {
364 string? Apartment = null;
365 string? Area = null;
366 string? Building = null;
367 string? City = null;
368 string? Class = null;
369 string? Country = null;
370 string? Manufacturer = null;
371 string? MeterLocation = null;
372 string? MeterNumber = null;
373 string? Model = null;
374 string? Name = null;
375 string? Region = null;
376 string? Room = null;
377 string? SerialNumber = null;
378 string? Street = null;
379 string? StreetNumber = null;
380 string? Version = null;
381 string? Phone = null;
382
383 foreach (Property P in MetaData)
384 switch (P.Name.ToUpper(CultureInfo.InvariantCulture))
385 {
387 Apartment = P.Value;
388 break;
389
391 Area = P.Value;
392 break;
393
395 Building = P.Value;
396 break;
397
399 City = P.Value;
400 break;
401
403 Country = P.Value;
404 break;
405
407 Region = P.Value;
408 break;
409
411 Room = P.Value;
412 break;
413
415 Street = P.Value;
416 break;
417
419 StreetNumber = P.Value;
420 break;
421
423 Class = P.Value;
424 break;
425
427 Manufacturer = P.Value;
428 break;
429
431 MeterLocation = P.Value;
432 break;
433
435 MeterNumber = P.Value;
436 break;
437
439 Model = P.Value;
440 break;
441
443 Name = P.Value;
444 break;
445
447 SerialNumber = P.Value;
448 break;
449
451 Version = P.Value;
452 break;
453
455 Phone = P.Value;
456 break;
457 }
458
459 StringBuilder? sb = null;
460
461 AppendName(ref sb, Class);
462 AppendName(ref sb, Model);
463 AppendName(ref sb, Version);
464 AppendName(ref sb, Room);
465 AppendName(ref sb, Name);
466 AppendName(ref sb, Apartment);
467 AppendName(ref sb, Building);
468 AppendName(ref sb, Street);
469 AppendName(ref sb, StreetNumber);
470 AppendName(ref sb, Area);
471 AppendName(ref sb, City);
472 AppendName(ref sb, Region);
473 AppendName(ref sb, Country);
474 AppendName(ref sb, MeterNumber);
475 AppendName(ref sb, MeterLocation);
476 AppendName(ref sb, Manufacturer);
477 AppendName(ref sb, SerialNumber);
478 AppendName(ref sb, Phone);
479
480 return sb?.ToString();
481 }
482
488 public static string GetFriendlyName(LegalIdentity? Identity)
489 {
490 if (Identity is null)
491 return string.Empty;
492
493 string? FirstName = null;
494 string? MiddleName = null;
495 string? LastName = null;
496 string? PersonalNumber = null;
497 string? Domain = null;
498 string? OrgDepartment = null;
499 string? OrgRole = null;
500 string? OrgName = null;
501 bool HasName = false;
502 bool HasOrg = false;
503 bool HasDomain = false;
504
505 foreach (Property P in Identity.Properties)
506 {
507 switch (P.Name.ToUpper(CultureInfo.InvariantCulture))
508 {
510 FirstName = P.Value;
511 HasName = true;
512 break;
513
515 MiddleName = P.Value;
516 HasName = true;
517 break;
518
520 LastName = P.Value;
521 HasName = true;
522 break;
523
525 PersonalNumber = P.Value;
526 break;
527
529 OrgName = P.Value;
530 HasOrg = true;
531 break;
532
534 OrgDepartment = P.Value;
535 HasOrg = true;
536 break;
537
539 OrgRole = P.Value;
540 HasOrg = true;
541 break;
542
544 Domain = P.Value;
545 HasDomain = true;
546 break;
547 }
548 }
549
550 StringBuilder? sb = null;
551
552 if (HasName)
553 {
554 AppendName(ref sb, FirstName);
555 AppendName(ref sb, MiddleName);
556 AppendName(ref sb, LastName);
557 }
558
559 if (HasOrg)
560 {
561 AppendName(ref sb, OrgRole);
562 AppendName(ref sb, OrgDepartment);
563 AppendName(ref sb, OrgName);
564 }
565
566 string Result = sb is not null ? sb.ToString() : !string.IsNullOrEmpty(PersonalNumber) ? PersonalNumber : Identity.Id;
567
568 if (HasDomain)
569 Result = Domain + " (" + Result + ")";
570
571 return Result;
572 }
573
578 public static string GetFullName(LegalIdentity? Identity)
579 {
580 string? FirstName = null;
581 string? MiddleNames = null;
582 string? LastNames = null;
583
584 if (Identity?.Properties is not null)
585 foreach (Property P in Identity.Properties)
586 switch (P.Name)
587 {
589 FirstName = P.Value;
590 break;
591
593 LastNames = P.Value;
594 break;
595
597 MiddleNames = P.Value;
598 break;
599 }
600
601 return GetFullName(FirstName, MiddleNames, LastNames);
602 }
603
610 public static string GetFullName(string? FirstName, string? MiddleNames, string? LastNames)
611 {
612 StringBuilder? sb = null;
613
614 AppendName(ref sb, FirstName);
615 AppendName(ref sb, MiddleNames);
616 AppendName(ref sb, LastNames);
617
618 return sb?.ToString() ?? string.Empty;
619 }
620
626 internal static void AppendName(ref StringBuilder? sb, string? Value)
627 {
628 if (!string.IsNullOrEmpty(Value))
629 {
630 if (sb is null)
631 sb = new StringBuilder();
632 else
633 sb.Append(' ');
634
635 sb.Append(Value);
636 }
637 }
638
647 public static async Task<string> GetFriendlyName(CaseInsensitiveString BareJid, string SourceId, string PartitionId, string NodeId)
648 {
649 if (string.IsNullOrEmpty(NodeId) && string.IsNullOrEmpty(PartitionId) && string.IsNullOrEmpty(SourceId))
650 return await GetFriendlyName(BareJid);
651
652 ContactInfo Thing = await FindByBareJid(BareJid, SourceId, PartitionId, NodeId);
653
654 if (Thing is not null)
655 return Thing.FriendlyName;
656
657 string s = NodeId;
658
659 if (!string.IsNullOrEmpty(PartitionId))
660 if (string.IsNullOrEmpty(s))
661 s = PartitionId;
662 else
663 s = ServiceRef.Localizer[nameof(AppResources.XInY), s, PartitionId];
664
665 if (!string.IsNullOrEmpty(SourceId))
666 if (string.IsNullOrEmpty(s))
667 s = SourceId;
668 else
670
671 return ServiceRef.Localizer[nameof(AppResources.XOnY), s, BareJid];
672 }
673
679 public string this[string PropertyName]
680 {
681 get
682 {
683 if (this.metaData is not null)
684 foreach (Property P in this.metaData)
685 if (string.Equals(P.Name, PropertyName, StringComparison.OrdinalIgnoreCase))
686 return P.Value;
687
688 return string.Empty;
689 }
690 }
691
696 {
697 get
698 {
699 return GetThingNotificationCategoryKey(this.bareJid, this.nodeId, this.sourceId, this.partition);
700 }
701 }
702
711 public static string GetThingNotificationCategoryKey(string BareJid, string? NodeId, string? SourceId, string? Partition)
712 {
713 StringBuilder sb = new();
714
715 sb.Append(BareJid);
716 sb.Append('|');
717
718 if (SourceId is not null)
719 sb.Append(SourceId);
720
721 sb.Append('|');
722
723 if (Partition is not null)
724 sb.Append(Partition);
725
726 sb.Append('|');
727
728 if (NodeId is not null)
729 sb.Append(NodeId);
730
731 return sb.ToString();
732 }
733 }
734}
const string MeterNumber
MeterNumber
Definition: Constants.cs:589
const string PersonalNumber
Personal number
Definition: Constants.cs:394
const string SerialNumber
Serial Number
Definition: Constants.cs:614
const string OrgRole
Organization Role
Definition: Constants.cs:509
const string StreetName
Street Name
Definition: Constants.cs:619
const string Phone
Phone number
Definition: Constants.cs:524
const string MiddleNames
Middle names
Definition: Constants.cs:379
const string OrgDepartment
Organization Department
Definition: Constants.cs:504
const string Domain
Domain name.
Definition: Constants.cs:534
const string StreetNumber
Street Number
Definition: Constants.cs:624
const string LastNames
Last names
Definition: Constants.cs:384
const string MeterLocation
Meter Location
Definition: Constants.cs:584
const string Manufacturer
Manufacturer
Definition: Constants.cs:579
const string FirstName
First name
Definition: Constants.cs:374
const string OrgName
Organization name
Definition: Constants.cs:459
A set of never changing property constants and helpful values.
Definition: Constants.cs:24
A strongly-typed resource class, for looking up localized strings, etc.
static string XInY
Looks up a localized string similar to {0} in {1}.
static string Me
Looks up a localized string similar to (me).
static string XOnY
Looks up a localized string similar to {0} on {1}.
Contains information about a contact.
Definition: ContactInfo.cs:22
Property?[] MetaData
Meta-data related to a thing.
Definition: ContactInfo.cs:211
static string GetFullName(string? FirstName, string? MiddleNames, string? LastNames)
Gets the full name of a person.
Definition: ContactInfo.cs:610
bool? Owner
If the account is registered as the owner of the thing.
Definition: ContactInfo.cs:201
static string GetFriendlyName(LegalIdentity? Identity)
Gets the friendly name of a legal identity.
Definition: ContactInfo.cs:488
bool? SubscribeTo
Subscribe to this contact
Definition: ContactInfo.cs:137
CaseInsensitiveString RegistryJid
Registry JID
Definition: ContactInfo.cs:128
ContactInfo()
Contains information about a contact.
Definition: ContactInfo.cs:45
static async Task< string > GetFriendlyName(CaseInsensitiveString RemoteId)
Gets the friendly name of a remote identity (Legal ID or Bare JID).
Definition: ContactInfo.cs:258
static async Task< string > GetFriendlyName(CaseInsensitiveString BareJid, string SourceId, string PartitionId, string NodeId)
Gets the friendly name of a thing.
Definition: ContactInfo.cs:647
static async Task< ContactInfo?> FindByLegalId(string LegalId)
Finds information about a contact, given its Legal ID.
Definition: ContactInfo.cs:248
LegalIdentity? LegalIdentity
Legal Identity object.
Definition: ContactInfo.cs:82
string ThingNotificationCategoryKey
Category key used for thing notifications.
Definition: ContactInfo.cs:696
static Task< ContactInfo > FindByBareJid(string BareJid, string SourceId, string Partition, string NodeId)
Finds information about a contact, given its Bare JID.
Definition: ContactInfo.cs:234
bool? IsSensor
The contact is a sensor
Definition: ContactInfo.cs:164
bool? IsConcentrator
The contact is a concentrator
Definition: ContactInfo.cs:191
static async Task< string[]?> GetFriendlyName(string[] RemoteId)
Gets the friendly name of a remote identity (Legal ID or Bare JID).
Definition: ContactInfo.cs:343
bool? AllowSubscriptionFrom
Allow subscriptions from this contact
Definition: ContactInfo.cs:146
static string GetFullName(LegalIdentity? Identity)
Gets the full name of a person.
Definition: ContactInfo.cs:578
bool? IsActuator
The contact is a actuator
Definition: ContactInfo.cs:182
bool? SupportsSensorEvents
The contact supports sensor events
Definition: ContactInfo.cs:173
static Task< ContactInfo > FindByBareJid(string BareJid)
Finds information about a contact, given its Bare JID.
Definition: ContactInfo.cs:221
static string GetThingNotificationCategoryKey(string BareJid, string? NodeId, string? SourceId, string? Partition)
Category key used for thing notifications.
Definition: ContactInfo.cs:711
CaseInsensitiveString LegalId
Legal ID of contact.
Definition: ContactInfo.cs:72
CaseInsensitiveString BareJid
Bare JID of contact.
Definition: ContactInfo.cs:63
static ? string GetFriendlyName(IEnumerable< Property > MetaData)
Gets the friendly name from a set of meta-data tags.
Definition: ContactInfo.cs:362
Base class that references services in the app.
Definition: ServiceRef.cs:43
static ITagProfile TagProfile
TAG Profile service.
Definition: ServiceRef.cs:202
static IReportingStringLocalizer Localizer
Localization service
Definition: ServiceRef.cs:370
static IXmppService XmppService
The XMPP service for XMPP communication.
Definition: ServiceRef.cs:190
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:21
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.
Definition: ImplTypes.g.cs:58
TypeNameSerialization
How the type name should be serialized.