Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
KycOrderingComparer.cs
1using System;
8
10{
14 internal sealed class KycOrderingComparer : IComparer<string>
15 {
16 private readonly Dictionary<string, OrderKey> orderByKey;
17 private readonly PropertyOrderComparer propertyComparer;
18 private readonly DisplayQuadOrderComparer displayComparer;
19
20 private KycOrderingComparer(Dictionary<string, OrderKey> OrderByKey)
21 {
22 this.orderByKey = OrderByKey;
23 this.propertyComparer = new PropertyOrderComparer(this);
24 this.displayComparer = new DisplayQuadOrderComparer(this);
25 }
26
27 public static KycOrderingComparer Create(KycProcess Process)
28 {
29 if (Process is null)
30 {
31 throw new ArgumentNullException(nameof(Process));
32 }
33
34 Dictionary<string, OrderKey> Map = BuildOrderMap(Process);
35 return new KycOrderingComparer(Map);
36 }
37
38 public IComparer<Property> PropertyComparer => this.propertyComparer;
39
40 public IComparer<DisplayQuad> DisplayComparer => this.displayComparer;
41
42 public int Compare(string? Left, string? Right)
43 {
44 OrderKey LeftKey = this.GetOrderKey(Left);
45 OrderKey RightKey = this.GetOrderKey(Right);
46
47 int Result = LeftKey.PageIndex.CompareTo(RightKey.PageIndex);
48 if (Result != 0)
49 {
50 return Result;
51 }
52
53 Result = LeftKey.FieldIndex.CompareTo(RightKey.FieldIndex);
54 if (Result != 0)
55 {
56 return Result;
57 }
58
59 Result = LeftKey.MappingIndex.CompareTo(RightKey.MappingIndex);
60 if (Result != 0)
61 {
62 return Result;
63 }
64
65 return string.Compare(LeftKey.Name, RightKey.Name, StringComparison.OrdinalIgnoreCase);
66 }
67
68 private OrderKey GetOrderKey(string? Key)
69 {
70 if (string.IsNullOrWhiteSpace(Key))
71 {
72 return OrderKey.Unknown;
73 }
74
75 if (this.orderByKey.TryGetValue(Key, out OrderKey Existing))
76 {
77 return Existing;
78 }
79
80 string Normalized = Key.Trim();
81 return new OrderKey(int.MaxValue, int.MaxValue, int.MaxValue, Normalized);
82 }
83
84 private static Dictionary<string, OrderKey> BuildOrderMap(KycProcess process)
85 {
86 Dictionary<string, OrderKey> Map = new Dictionary<string, OrderKey>(StringComparer.OrdinalIgnoreCase);
87 for (int PageIndex = 0; PageIndex < process.Pages.Count; PageIndex++)
88 {
89 KycPage Page = process.Pages[PageIndex];
90 int FieldIndex = 0;
91
92 foreach (ObservableKycField Field in Page.AllFields)
93 {
94 RegisterFieldMappings(Map, Field, PageIndex, FieldIndex);
95 FieldIndex++;
96 }
97
98 foreach (KycSection Section in Page.AllSections)
99 {
100 foreach (ObservableKycField Field in Section.AllFields)
101 {
102 RegisterFieldMappings(Map, Field, PageIndex, FieldIndex);
103 FieldIndex++;
104 }
105 }
106 }
107
108 return Map;
109 }
110
111 private static void RegisterFieldMappings(Dictionary<string, OrderKey> map, ObservableKycField field, int pageIndex, int fieldIndex)
112 {
113 if (field is null)
114 {
115 return;
116 }
117
118 for (int MappingIndex = 0; MappingIndex < field.Mappings.Count; MappingIndex++)
119 {
120 KycMapping Mapping = field.Mappings[MappingIndex];
121 if (Mapping is null)
122 {
123 continue;
124 }
125
126 string Key = Mapping.Key ?? string.Empty;
127 if (string.IsNullOrWhiteSpace(Key))
128 {
129 continue;
130 }
131
132 string TrimmedKey = Key.Trim();
133 if (map.ContainsKey(TrimmedKey))
134 {
135 continue;
136 }
137
138 OrderKey Order = new OrderKey(pageIndex, fieldIndex, MappingIndex, TrimmedKey);
139 map[TrimmedKey] = Order;
140
141 HandleAliases(map, TrimmedKey, Order);
142 }
143 }
144
145 private static void HandleAliases(Dictionary<string, OrderKey> map, string key, OrderKey order)
146 {
147 if (key.Equals(Constants.XmppProperties.BirthDay, StringComparison.OrdinalIgnoreCase) ||
148 key.Equals(Constants.XmppProperties.BirthMonth, StringComparison.OrdinalIgnoreCase) ||
149 key.Equals(Constants.XmppProperties.BirthYear, StringComparison.OrdinalIgnoreCase))
150 {
151 RegisterAlias(map, Constants.CustomXmppProperties.BirthDate, order);
152 }
153
154 if (key.StartsWith("ORGREP", StringComparison.OrdinalIgnoreCase))
155 {
156 RegisterAlias(map, "ORGREPBDATE", order);
157 }
158 }
159
160 private static void RegisterAlias(Dictionary<string, OrderKey> map, string alias, OrderKey order)
161 {
162 if (string.IsNullOrWhiteSpace(alias))
163 {
164 return;
165 }
166
167 if (map.ContainsKey(alias))
168 {
169 return;
170 }
171
172 OrderKey AliasOrder = new OrderKey(order.PageIndex, order.FieldIndex, order.MappingIndex, alias.Trim());
173 map[alias] = AliasOrder;
174 }
175
176 private readonly struct OrderKey
177 {
178 public OrderKey(int pageIndex, int fieldIndex, int mappingIndex, string name)
179 {
180 this.PageIndex = pageIndex;
181 this.FieldIndex = fieldIndex;
182 this.MappingIndex = mappingIndex;
183 this.Name = name;
184 }
185
186 public int PageIndex { get; }
187
188 public int FieldIndex { get; }
189
190 public int MappingIndex { get; }
191
192 public string Name { get; }
193
194 public static OrderKey Unknown => new OrderKey(int.MaxValue, int.MaxValue, int.MaxValue, string.Empty);
195 }
196
197 private sealed class PropertyOrderComparer : IComparer<Property>
198 {
199 private readonly KycOrderingComparer owner;
200
201 public PropertyOrderComparer(KycOrderingComparer owner)
202 {
203 this.owner = owner;
204 }
205
206 public int Compare(Property? left, Property? right)
207 {
208 if (left is null && right is null)
209 {
210 return 0;
211 }
212
213 if (left is null)
214 {
215 return 1;
216 }
217
218 if (right is null)
219 {
220 return -1;
221 }
222
223 return this.owner.Compare(left.Name, right.Name);
224 }
225 }
226
227 private sealed class DisplayQuadOrderComparer : IComparer<DisplayQuad>
228 {
229 private readonly KycOrderingComparer owner;
230
231 public DisplayQuadOrderComparer(KycOrderingComparer owner)
232 {
233 this.owner = owner;
234 }
235
236 public int Compare(DisplayQuad? left, DisplayQuad? right)
237 {
238 if (left is null && right is null)
239 {
240 return 0;
241 }
242
243 if (left is null)
244 {
245 return 1;
246 }
247
248 if (right is null)
249 {
250 return -1;
251 }
252
253 int Result = this.owner.Compare(left.Mapping, right.Mapping);
254 if (Result != 0)
255 {
256 return Result;
257 }
258
259 return string.Compare(left.Label, right.Label, StringComparison.OrdinalIgnoreCase);
260 }
261 }
262 }
263}
Custom XMPP Protocol Properties.
Definition: Constants.cs:322
const string BirthYear
Birth Year
Definition: Constants.cs:454
const string BirthMonth
Birth Month
Definition: Constants.cs:449
A set of never changing property constants and helpful values.
Definition: Constants.cs:24
Represents a displayable set of three related strings: a label, a value, and an optional mapping.
Mapping from a field value to an identity property, including optional transform pipeline.
Definition: KycMapping.cs:9
Represents a page in a KYC process containing fields and sections.
Definition: KycPage.cs:20
ObservableCollection< KycSection > AllSections
Gets all sections contained in the page.
Definition: KycPage.cs:64
ObservableCollection< ObservableKycField > AllFields
Gets all fields directly contained in the page (excluding sections).
Definition: KycPage.cs:51
Represents a parsed KYC process with pages, fields, and current values.
Definition: KycProcess.cs:11
ObservableCollection< KycPage > Pages
Gets the collection of pages in the KYC process.
Definition: KycProcess.cs:26
The base KYC field model. Use as-is for generic fields, or subclass for custom logic.
ObservableCollection< KycMapping > Mappings
Mappings to apply output.