blob: 36ef924b155a4be38ad7722dc82a225a7897c21f [file] [log] [blame]
Constantin Ziesche857c7ab2020-02-25 11:24:51 +01001/*******************************************************************************
2* Copyright (c) 2020 Robert Bosch GmbH
3* Author: Constantin Ziesche (constantin.ziesche@bosch.com)
4*
5* This program and the accompanying materials are made available under the
6* terms of the Eclipse Public License 2.0 which is available at
7* http://www.eclipse.org/legal/epl-2.0
8*
9* SPDX-License-Identifier: EPL-2.0
10*******************************************************************************/
11using BaSyx.Models.Core.AssetAdministrationShell.Enums;
12using BaSyx.Models.Core.AssetAdministrationShell.Implementations.SubmodelElementTypes;
13using BaSyx.Models.Core.AssetAdministrationShell.References;
14using BaSyx.Models.Core.AssetAdministrationShell.Semantics;
15using Newtonsoft.Json;
16using System;
17using System.Collections.Generic;
18using System.Reflection;
19using System.Runtime.Serialization;
20
21namespace BaSyx.Models.Core.Common
22{
23
24 [DataContract]
25 public class DataType : IHasSemantics, IEquatable<DataType>
26 {
27 [IgnoreDataMember]
28 public bool? IsCollection { get; internal set; }
29
30 [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "dataObjectType")]
31 public DataObjectType DataObjectType { get; internal set; }
32
33 [IgnoreDataMember]
34 public Type SystemType { get; internal set; }
35
36 public IReference SemanticId { get; internal set; }
37
38 [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "schemaType")]
39 public SchemaType? SchemaType { get; internal set; }
40
41 [DataMember(EmitDefaultValue = false, IsRequired = false, Name = "schema")]
42 public string Schema { get; internal set; }
43
44 //[DataMember(EmitDefaultValue = false, IsRequired = false, Name = "valueRank")]
45 //public ValueRank? ValueRank { get; }
46
47 internal DataType() { }
48
49 public DataType(DataObjectType dataObjectType) : this(dataObjectType, false, null)
50 { }
51
52 [JsonConstructor]
53 public DataType(DataObjectType dataObjectType, bool? isCollection, IReference semanticId = null)
54 {
55 DataObjectType = dataObjectType;
56 SemanticId = semanticId;
57
58 SystemType = GetSystemTypeFromDataType(dataObjectType);
59
60
61 if (isCollection.HasValue)
62 IsCollection = isCollection;
63 else
64 IsCollection = false;
65
66 }
67 public DataType(IReference semanticId, SchemaType schemaType, string schema)
68 :this(DataObjectType.AnyType, false, semanticId)
69 {
70 SchemaType = schemaType;
71 Schema = schema;
72 }
73
74 public override string ToString()
75 {
76 return DataObjectType?.Name;
77 }
78
79 /*
80 public enum ValueRank : int
81 {
82 Scalar = -1,
83 OneDimensional = 1,
84 TwoDimensional = 2,
85 ScalarOrOneDimensional = 3
86 }
87 */
88 public static DataType GetDataTypeFromSystemType(Type type)
89 {
90 DataType dataType = new DataType();
Constantin Zieschefa612082020-04-03 09:54:56 +020091 Type innerType;
Constantin Ziesche857c7ab2020-02-25 11:24:51 +010092 if (IsGenericList(type))
93 {
94 dataType.IsCollection = true;
95 innerType = type.GetGenericArguments()[0];
96 }
97 else if (IsArray(type))
98 {
99 dataType.IsCollection = true;
100 innerType = type.GetElementType();
101 }
102 else
103 {
104 dataType.IsCollection = false;
105 innerType = type;
106 }
107 dataType.SystemType = innerType;
108
109 switch (innerType.FullName)
110 {
111 case "System.Decimal": dataType.DataObjectType = DataObjectType.Decimal; break;
112 case "System.String": dataType.DataObjectType = DataObjectType.String; break;
113 case "System.SByte": dataType.DataObjectType = DataObjectType.Int8; break;
114 case "System.Int16": dataType.DataObjectType = DataObjectType.Int16; break;
115 case "System.Int32": dataType.DataObjectType = DataObjectType.Int32; break;
116 case "System.Int64": dataType.DataObjectType = DataObjectType.Int64; break;
117 case "System.Byte": dataType.DataObjectType = DataObjectType.UInt8; break;
118 case "System.UInt16": dataType.DataObjectType = DataObjectType.UInt16; break;
119 case "System.UInt32": dataType.DataObjectType = DataObjectType.UInt32; break;
120 case "System.UInt64": dataType.DataObjectType = DataObjectType.UInt64; break;
121 case "System.Boolean": dataType.DataObjectType = DataObjectType.Bool; break;
122 case "System.Single": dataType.DataObjectType = DataObjectType.Float; break;
123 case "System.Double": dataType.DataObjectType = DataObjectType.Double; break;
124 case "System.DateTime": dataType.DataObjectType = DataObjectType.DateTime; break;
125 case "System.Uri": dataType.DataObjectType = DataObjectType.AnyURI; break;
126 default:
127 if (!IsSimpleType(innerType))
128 {
129 dataType.DataObjectType = DataObjectType.AnyType;
130 return dataType;
131 }
132 else
133 return null;
134 }
135 return dataType;
136 }
137
138 public static bool IsGenericList(Type type)
139 {
140 return (type.IsGenericType && (
141 type.GetGenericTypeDefinition() == typeof(List<>) ||
142 type.GetGenericTypeDefinition() == typeof(IEnumerable<>)));
143 }
144
145 public static bool IsArray(Type type)
146 {
147 return type.IsArray;
148 }
149
150 public static Type GetSystemTypeFromDataType(DataObjectType dataObjectType)
151 {
152 if (dataObjectType == DataObjectType.String)
153 return typeof(string);
154 if (dataObjectType == DataObjectType.LangString)
155 return typeof(string);
156 else if (dataObjectType == DataObjectType.Bool)
157 return typeof(bool);
158 else if (dataObjectType == DataObjectType.Float)
159 return typeof(float);
160 else if (dataObjectType == DataObjectType.Double)
161 return typeof(double);
162 else if (dataObjectType == DataObjectType.UInt8)
163 return typeof(byte);
164 else if (dataObjectType == DataObjectType.UInt16)
165 return typeof(UInt16);
166 else if (dataObjectType == DataObjectType.UInt32)
167 return typeof(UInt32);
168 else if (dataObjectType == DataObjectType.UInt64)
169 return typeof(UInt64);
170 else if (dataObjectType == DataObjectType.Int8)
171 return typeof(sbyte);
172 else if (dataObjectType == DataObjectType.Int16)
173 return typeof(Int16);
174 else if (dataObjectType == DataObjectType.Int32)
175 return typeof(Int32);
176 else if (dataObjectType == DataObjectType.Int64)
177 return typeof(Int64);
178 else if (dataObjectType == DataObjectType.Integer)
179 return typeof(decimal);
180 else if (dataObjectType == DataObjectType.NegativeInteger)
181 return typeof(decimal);
182 else if (dataObjectType == DataObjectType.PositiveInteger)
183 return typeof(decimal);
184 else if (dataObjectType == DataObjectType.NonNegativeInteger)
185 return typeof(decimal);
186 else if (dataObjectType == DataObjectType.NonPositiveInteger)
187 return typeof(decimal);
188 else if (dataObjectType == DataObjectType.AnyType)
189 return typeof(object);
190 else if (dataObjectType == DataObjectType.AnySimpleType)
191 return typeof(string);
192 else if (dataObjectType == DataObjectType.DateTime)
193 return typeof(DateTime);
194 else if (dataObjectType == DataObjectType.DateTimeStamp)
195 return typeof(DateTime);
196 else if (dataObjectType == DataObjectType.AnyURI)
197 return typeof(Uri);
198 else if (dataObjectType == DataObjectType.Base64Binary)
199 return typeof(byte[]);
200 else if (dataObjectType == DataObjectType.HexBinary)
201 return typeof(byte[]);
202 else if (dataObjectType == DataObjectType.Duration)
203 return typeof(TimeSpan);
204 else if (dataObjectType == DataObjectType.DayTimeDuration)
205 return typeof(TimeSpan);
206 else if (dataObjectType == DataObjectType.YearMonthDuration)
207 return typeof(TimeSpan);
208 else if (dataObjectType == ModelType.Property)
209 return typeof(Property);
210 else if (dataObjectType == ModelType.Blob)
211 return typeof(Blob);
212 else if (dataObjectType == ModelType.File)
213 return typeof(File);
214 else if (dataObjectType == ModelType.ReferenceElement)
215 return typeof(ReferenceElement);
216 else if (dataObjectType == ModelType.SubmodelElementCollection)
217 return typeof(SubmodelElementCollection);
218 else
219 return null;
220 }
221
222 public static Type GetSystemTypeFromDataType(DataType dataType)
223 {
224 return GetSystemTypeFromDataType(dataType.DataObjectType);
225 }
226
227 public static bool IsSimpleType(Type type)
228 {
229 TypeInfo typeInfo = type.GetTypeInfo();
230 if (typeInfo.IsGenericType && typeInfo.GetGenericTypeDefinition() == typeof(Nullable<>))
231 return IsSimpleType(typeInfo.GetGenericArguments()[0]);
232
233 return typeInfo.IsEnum || typeInfo.IsPrimitive || type.Equals(typeof(string)) || type.Equals(typeof(decimal));
234 }
235 #region IEquatable Interface Implementation
236 public bool Equals(DataType other)
237 {
238 if (ReferenceEquals(null, other))
239 {
240 return false;
241 }
242 if (ReferenceEquals(this, other))
243 {
244 return true;
245 }
246
247 return this.DataObjectType.Equals(other.DataObjectType)
248 && this.IsCollection.Equals(other.IsCollection);
249 }
250 public override bool Equals(object obj)
251 {
252 if (ReferenceEquals(null, obj))
253 {
254 return false;
255 }
256 if (ReferenceEquals(this, obj))
257 {
258 return true;
259 }
260
261 return obj.GetType() == GetType() && Equals((DataType)obj);
262 }
263
264
265 public override int GetHashCode()
266 {
267 unchecked
268 {
269 var result = 0;
270 result = (result * 397) ^ DataObjectType.GetHashCode();
271 result = (result * 397) ^ (IsCollection.Value ? 1 : 0);
272 return result;
273 }
274 }
275
276 public static bool operator ==(DataType x, DataType y)
277 {
278
279 if (ReferenceEquals(x, y))
280 {
281 return true;
282 }
283
284 if (ReferenceEquals(x, null))
285 {
286 return false;
287 }
288 if (ReferenceEquals(y, null))
289 {
290 return false;
291 }
292
293 return x.DataObjectType == y.DataObjectType && x.IsCollection == y.IsCollection;
294 }
295 public static bool operator !=(DataType x, DataType y)
296 {
297 return !(x == y);
298 }
299 #endregion
300
301 }
302
303
304}