Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
JoinedObject.cs
1using System;
3using System.Reflection;
4using System.Text;
9
11{
15 public class JoinedObject
16 {
17 private readonly Dictionary<string, PropertyRecord> properties = new Dictionary<string, PropertyRecord>();
18 private readonly Type leftType;
19 private readonly Type rightType;
20 private readonly GenericObject leftGen;
21 private readonly GenericObject rightGen;
22 private readonly object left;
23 private readonly object right;
24 private readonly string leftName;
25 private readonly string rightName;
26 private readonly bool hasLeftName;
27 private readonly bool hasRightName;
28 private readonly bool isLeftGen;
29 private readonly bool isRightGen;
30 private string objectId = null;
31
39 public JoinedObject(object Left, string LeftName, object Right, string RightName)
40 {
41 this.left = Left;
42 this.leftGen = Left as GenericObject;
43 this.leftType = this.left?.GetType();
44 this.leftName = LeftName;
45 this.hasLeftName = !string.IsNullOrEmpty(this.leftName);
46 this.isLeftGen = !(this.leftGen is null);
47 this.right = Right;
48 this.rightGen = Right as GenericObject;
49 this.rightType = this.right?.GetType();
50 this.rightName = RightName;
51 this.hasRightName = !string.IsNullOrEmpty(this.rightName);
52 this.isRightGen = !(this.rightGen is null);
53 }
54
60 public object this[string Index]
61 {
62 get
63 {
64 if (this.isLeftGen && this.leftGen.TryGetFieldValue(Index, out object Value))
65 return Value;
66 else if (this.isRightGen && this.rightGen.TryGetFieldValue(Index, out Value))
67 return Value;
68 else if (this.hasLeftName && string.Compare(Index, this.leftName, true) == 0)
69 return this.left;
70 else if (this.hasRightName && string.Compare(Index, this.rightName, true) == 0)
71 return this.right;
72
73 PropertyRecord Rec;
74
75 lock (this.properties)
76 {
77 if (!this.properties.TryGetValue(Index, out Rec))
78 {
79 Rec = this.GetRecLocked(Index);
80 this.properties[Index] = Rec;
81 }
82 }
83
84 if (!(Rec.Property is null))
85 {
86 if (Rec.NrIndexParameters == 1)
87 return ScriptNode.UnnestPossibleTaskSync(Rec.Property.GetValue(Rec.Left ? this.left : this.right, Rec.GetIndexArguments(Index))); // TODO: Async
88 else
89 return ScriptNode.UnnestPossibleTaskSync(Rec.Property.GetValue(Rec.Left ? this.left : this.right)); // TODO: Async
90 }
91 else if (!(Rec.Field is null))
92 return ScriptNode.UnnestPossibleTaskSync(Rec.Field.GetValue(Rec.Left ? this.left : this.right)); // TODO: Async
93 else
94 return null;
95 }
96 }
97
98 private PropertyRecord GetRecLocked(string Index)
99 {
100 PropertyInfo PI;
101 FieldInfo FI;
102
103 if (!(this.leftType is null))
104 {
105 PI = this.leftType.GetRuntimeProperty(Index);
106 if (!(PI is null))
107 {
108 if (PI.CanRead && PI.GetMethod.IsPublic)
109 return new PropertyRecord(PI, true);
110 else
111 return new PropertyRecord();
112 }
113
114 FI = this.leftType.GetRuntimeField(Index);
115 if (!(FI is null))
116 {
117 if (FI.IsPublic)
118 return new PropertyRecord(FI, true);
119 else
120 return new PropertyRecord();
121 }
122
123 if (VectorIndex.TryGetIndexProperty(this.leftType, true, false, out PI,
124 out ParameterInfo[] IndexArguments))
125 {
126 return new PropertyRecord(PI, true, IndexArguments);
127 }
128 }
129
130 if (!(this.rightType is null))
131 {
132 PI = this.rightType.GetRuntimeProperty(Index);
133 if (!(PI is null))
134 {
135 if (PI.CanRead && PI.GetMethod.IsPublic)
136 return new PropertyRecord(PI, false);
137 else
138 return new PropertyRecord();
139 }
140
141 FI = this.rightType.GetRuntimeField(Index);
142 if (!(FI is null))
143 {
144 if (FI.IsPublic)
145 return new PropertyRecord(FI, false);
146 else
147 return new PropertyRecord();
148 }
149
150 if (VectorIndex.TryGetIndexProperty(this.rightType, true, false, out PI,
151 out ParameterInfo[] IndexArguments))
152 {
153 return new PropertyRecord(PI, false, IndexArguments);
154 }
155 }
156
157 return new PropertyRecord();
158 }
159
160 private class PropertyRecord
161 {
162 public PropertyInfo Property;
163 public ParameterInfo[] IndexArguments;
164 public FieldInfo Field;
165 public bool Left;
166 public int NrIndexParameters;
167 public bool IsStringIndex;
168
169 public PropertyRecord()
170 {
171 this.Property = null;
172 this.Field = null;
173 this.Left = false;
174 this.IndexArguments = null;
175 this.IsStringIndex = false;
176 this.NrIndexParameters = 0;
177 }
178
179 public PropertyRecord(PropertyInfo Property, bool Left)
180 {
181 this.Property = Property;
182 this.Field = null;
183 this.Left = Left;
184 this.IndexArguments = null;
185 this.IsStringIndex = false;
186 this.NrIndexParameters = 0;
187 }
188
189 public PropertyRecord(FieldInfo Field, bool Left)
190 {
191 this.Property = null;
192 this.Field = Field;
193 this.Left = Left;
194 this.IndexArguments = null;
195 this.IsStringIndex = false;
196 this.NrIndexParameters = 0;
197 }
198
199 public PropertyRecord(PropertyInfo Property, bool Left, ParameterInfo[] IndexArguments)
200 {
201 this.Property = Property;
202 this.Field = null;
203 this.Left = Left;
204 this.IndexArguments = IndexArguments;
205
206 if (IndexArguments is null)
207 {
208 this.NrIndexParameters = 0;
209 this.IsStringIndex = false;
210 }
211 else
212 {
213 this.NrIndexParameters = this.IndexArguments.Length;
214 this.IsStringIndex = this.NrIndexParameters == 1 &&
215 this.IndexArguments[0].ParameterType == typeof(string);
216 }
217 }
218
219 public PropertyRecord(FieldInfo Field, bool Left, ParameterInfo[] IndexArguments)
220 {
221 this.Property = null;
222 this.Field = Field;
223 this.Left = Left;
224 this.IndexArguments = IndexArguments;
225
226 if (IndexArguments is null)
227 {
228 this.NrIndexParameters = 0;
229 this.IsStringIndex = false;
230 }
231 else
232 {
233 this.NrIndexParameters = this.IndexArguments.Length;
234 this.IsStringIndex = this.NrIndexParameters == 1 &&
235 this.IndexArguments[0].ParameterType == typeof(string);
236 }
237 }
238
239 public object[] GetIndexArguments(string Name)
240 {
241 if (this.IsStringIndex)
242 return new object[] { Name };
243
244 object Converted = Expression.ConvertTo(Name, this.IndexArguments[0].ParameterType, null);
245
246 return new object[] { Converted };
247 }
248 }
249
253 public string ObjectId
254 {
255 get
256 {
257 if (this.objectId is null)
258 {
259 StringBuilder sb = new StringBuilder();
260 object Id;
261
262 if (!(this.left is null))
263 {
264 Id = Database.TryGetObjectId(this.left).Result;
265 if (!(Id is null))
266 sb.Append(Id.ToString());
267 }
268
269 sb.Append(':');
270
271 if (!(this.right is null))
272 {
273 Id = Database.TryGetObjectId(this.right).Result;
274 if (!(Id is null))
275 sb.Append(Id.ToString());
276 }
277
278 this.objectId = sb.ToString();
279 }
280
281 return this.objectId;
282 }
283 }
284
286 public override bool Equals(object obj)
287 {
288 return (obj is JoinedObject Obj &&
289 this.ObjectId == Obj.ObjectId);
290 }
291
293 public override int GetHashCode()
294 {
295 return this.ObjectId.GetHashCode();
296
297 }
298 }
299}
Static interface for database persistence. In order to work, a database provider has to be assigned t...
Definition: Database.cs:21
static Task< object > TryGetObjectId(object Object)
Tries to get the Object ID of an object, if it exists.
Definition: Database.cs:2406
Generic object. Contains a sequence of properties.
Class managing a script expression.
Definition: Expression.cs:41
static object ConvertTo(IElement Value, Type DesiredType, ScriptNode Node)
Tries to conevert an element value to a desired type.
Definition: Expression.cs:5385
Base class for all nodes in a parsed script tree.
Definition: ScriptNode.cs:69
static object UnnestPossibleTaskSync(object Result)
Checks if Result is an asynchronous results. If so, blocks the current thread until the result is co...
Definition: ScriptNode.cs:460
static bool TryGetIndexProperty(Type T, bool ForReading, bool ForWriting, out PropertyInfo PropertyInfo, out ParameterInfo[] Parameters)
Tries to get a one-dimensional index property of a Type.
Definition: VectorIndex.cs:138
JoinedObject(object Left, string LeftName, object Right, string RightName)
Represents a joined object.
Definition: JoinedObject.cs:39