blob: 961ec3a90a80fc29fa8fb354c2d8a9e3f3c38c66 [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.Generics;
Constantin Ziesche857c7ab2020-02-25 11:24:51 +010012using BaSyx.Models.Core.Common;
Constantin Ziesche9d45f862021-02-23 23:59:12 +010013using BaSyx.Models.Extensions;
Constantin Ziesche08215502020-09-21 19:08:32 +020014using BaSyx.Utils.ResultHandling;
15using Newtonsoft.Json;
16using System;
17using System.Collections;
18using System.Collections.Generic;
Constantin Ziesche9d45f862021-02-23 23:59:12 +010019using System.Linq;
Constantin Ziesche857c7ab2020-02-25 11:24:51 +010020using System.Runtime.Serialization;
21
Constantin Ziesche08215502020-09-21 19:08:32 +020022namespace BaSyx.Models.Core.AssetAdministrationShell.Implementations
Constantin Ziesche857c7ab2020-02-25 11:24:51 +010023{
Constantin Ziesche08215502020-09-21 19:08:32 +020024 [DataContract, JsonObject]
25 public class SubmodelElementCollection : SubmodelElement, ISubmodelElementCollection, IElementContainer<ISubmodelElement>
Constantin Ziesche857c7ab2020-02-25 11:24:51 +010026 {
27 public override ModelType ModelType => ModelType.SubmodelElementCollection;
28 public IElementContainer<ISubmodelElement> Value { get; set; }
29 public bool AllowDuplicates { get; set; } = false;
30 public bool Ordered { get; set; } = false;
31
Constantin Ziesche08215502020-09-21 19:08:32 +020032 [IgnoreDataMember, JsonIgnore]
33 public IEnumerable<IElementContainer<ISubmodelElement>> Children => Value.Children;
34 [IgnoreDataMember, JsonIgnore]
35 public IEnumerable<ISubmodelElement> Values => Value.Values;
36 [IgnoreDataMember, JsonIgnore]
37 ISubmodelElement IElementContainer<ISubmodelElement>.Value { get => this; set { } }
38 [IgnoreDataMember, JsonIgnore]
39 public string Path
Constantin Ziesche95d51092020-03-04 17:58:10 +010040 {
Constantin Ziesche08215502020-09-21 19:08:32 +020041 get
42 {
43 if (string.IsNullOrEmpty(Value.Path))
44 return IdShort;
45 else
46 return Value.Path;
47 }
48 set { Value.Path = value; }
49 }
50 [IgnoreDataMember, JsonIgnore]
51 public bool IsRoot => Value.IsRoot;
52 [IgnoreDataMember, JsonIgnore]
53 public IElementContainer<ISubmodelElement> ParentContainer { get => this; set { } }
Constantin Ziesche9d45f862021-02-23 23:59:12 +010054 [IgnoreDataMember, JsonIgnore]
Constantin Ziesche0399d412020-09-24 14:31:15 +020055 public int Count => Value.Count;
Constantin Ziesche9d45f862021-02-23 23:59:12 +010056 [IgnoreDataMember, JsonIgnore]
Constantin Ziesche0399d412020-09-24 14:31:15 +020057 public bool IsReadOnly => Value.IsReadOnly;
58
Constantin Ziesche08215502020-09-21 19:08:32 +020059 [IgnoreDataMember, JsonIgnore]
60 public ISubmodelElement this[string idShort] => Value[idShort];
61 [IgnoreDataMember, JsonIgnore]
62 public ISubmodelElement this[int i] => Value[i];
63
64 public SubmodelElementCollection(string idShort) : base(idShort)
65 {
66 Value = new ElementContainer<ISubmodelElement>(this.Parent, this, null);
67
68 Get = element => { return new ElementValue(Value, new DataType(DataObjectType.AnyType)); };
69 Set = (element, value) => { Value = value?.Value as IElementContainer<ISubmodelElement>; };
70 }
71
72 public IResult<IQueryableElementContainer<ISubmodelElement>> RetrieveAll()
73 {
74 return Value.RetrieveAll();
75 }
76
77 public IResult<IQueryableElementContainer<ISubmodelElement>> RetrieveAll(Predicate<ISubmodelElement> predicate)
78 {
79 return Value.RetrieveAll(predicate);
80 }
81
82 public bool HasChildren()
83 {
84 return Value.HasChildren();
85 }
86
87 public bool HasChild(string idShort)
88 {
89 return Value.HasChild(idShort);
90 }
91
92 public bool HasChildPath(string idShortPath)
93 {
94 return Value.HasChildPath(idShortPath);
95 }
96
97 public void Traverse(Action<ISubmodelElement> action)
98 {
99 Value.Traverse(action);
100 }
101
102 public void Add(ISubmodelElement element)
103 {
104 Value.Add(element);
105 }
106
107 public void AddRange(IEnumerable<ISubmodelElement> elements)
108 {
109 Value.AddRange(elements);
110 }
111
Constantin Ziesche09dcb6b2020-10-07 13:47:39 +0200112 public IResult<ISubmodelElement> Create(ISubmodelElement element)
Constantin Ziesche08215502020-09-21 19:08:32 +0200113 {
114 return Value.Create(element);
115 }
116
117 public IResult<ISubmodelElement> Retrieve(string id)
118 {
119 return Value.Retrieve(id);
120 }
121
122 IResult<T> ICrudContainer<string, ISubmodelElement>.Retrieve<T>(string id)
123 {
124 return Value.Retrieve<T>(id);
125 }
126
127 IResult<IQueryableElementContainer<T>> ICrudContainer<string, ISubmodelElement>.RetrieveAll<T>()
128 {
129 return Value.RetrieveAll<T>();
130 }
131
132 IResult<IQueryableElementContainer<T>> ICrudContainer<string, ISubmodelElement>.RetrieveAll<T>(Predicate<T> predicate)
133 {
134 return Value.RetrieveAll(predicate);
135 }
136
137 public IResult<ISubmodelElement> CreateOrUpdate(string id, ISubmodelElement element)
138 {
139 return Value.CreateOrUpdate(id, element);
140 }
141
142 public IResult<ISubmodelElement> Update(string id, ISubmodelElement element)
143 {
144 return Value.Update(id, element);
145 }
146
147 public IResult Delete(string id)
148 {
149 return Value.Delete(id);
150 }
151
152 public IEnumerator<ISubmodelElement> GetEnumerator()
153 {
154 return Value.GetEnumerator();
155 }
156
157 IEnumerator IEnumerable.GetEnumerator()
158 {
159 return Value.GetEnumerator();
160 }
161
162 public IElementContainer<ISubmodelElement> GetChild(string idShortPath)
163 {
164 return Value.GetChild(idShortPath);
165 }
166
167 public void Remove(string idShort)
168 {
169 Value.Remove(idShort);
170 }
171
172 public void AppendRootPath(string rootPath)
173 {
174 Value.AppendRootPath(rootPath);
175 }
176
177 public IEnumerable<ISubmodelElement> Flatten()
178 {
179 return Value.Flatten();
180 }
Constantin Ziesche0399d412020-09-24 14:31:15 +0200181
182 public void Clear()
183 {
184 Value.Clear();
185 }
186
187 public bool Contains(ISubmodelElement item)
188 {
189 return Value.Contains(item);
190 }
191
192 public void CopyTo(ISubmodelElement[] array, int arrayIndex)
193 {
194 Value.CopyTo(array, arrayIndex);
195 }
196
197 public bool Remove(ISubmodelElement item)
198 {
199 return Value.Remove(item);
200 }
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100201 }
Constantin Ziesche9d45f862021-02-23 23:59:12 +0100202
203 [DataContract, JsonObject]
204 public class SubmodelElementCollection<T> : SubmodelElementCollection, IList<T>
205 {
206 [JsonConstructor]
207 public SubmodelElementCollection(string idShort) : base(idShort)
208 {
209 AllowDuplicates = true;
210 Ordered = true;
211 }
212
213 public SubmodelElementCollection(string idShort, IEnumerable<T> enumerable) : this(idShort)
214 {
215 if(enumerable?.Count() > 0)
216 {
217 foreach (var item in enumerable)
218 {
219 this.Add(item);
220 }
221 }
222 }
223
224 T IList<T>.this[int index] {
225 get => Value[index].Cast<IProperty>().ToObject<T>();
226 set => Value[index].Cast<IProperty>().Value = value; }
227
228 public void Add(T item)
229 {
230 string idShort = (Value.Count + 1).ToString();
231 Value.Add(new Property<T>(idShort, item));
232 }
233
234 public bool Contains(T item)
235 {
236 List<ISubmodelElement> list = Value.Flatten()?.ToList();
237 if (list == null)
238 return false;
239
240 return list.Find(p => p.Cast<IProperty<T>>().Value.Equals(item)) == null;
241 }
242
243 public void CopyTo(T[] array, int arrayIndex)
244 {
245 List<T> list = Value.Flatten()?.ToList()?.ConvertAll(c => c.Cast<IProperty<T>>().Value);
246 list?.CopyTo(array, arrayIndex);
247 }
248
249 public int IndexOf(T item)
250 {
251 List<ISubmodelElement> list = Value.Flatten()?.ToList();
252 if (list == null)
253 return -1;
254
255 return list.FindIndex(p => p.Cast<IProperty<T>>().Value.Equals(item));
256 }
257
258 public void Insert(int index, T item)
259 {
260 throw new NotImplementedException();
261 }
262
263 public bool Remove(T item)
264 {
265 List<ISubmodelElement> list = Value.Flatten()?.ToList();
266 if (list == null)
267 return false;
268
269 var index = list.FindIndex(p => p.Cast<IProperty<T>>().Value.Equals(item));
270 if (index != -1)
271 {
272 RemoveAt(index);
273 return true;
274 }
275 else
276 return false;
277 }
278
279 public void RemoveAt(int index)
280 {
281 string idShort = Value[index]?.IdShort;
282
283 if (!string.IsNullOrEmpty(idShort))
284 Remove(idShort);
285 }
286
287 IEnumerator<T> IEnumerable<T>.GetEnumerator()
288 {
289 List<T> list = Value.Flatten()?.ToList()?.ConvertAll(c => c.Cast<IProperty<T>>().Value);
290 return list?.GetEnumerator();
291 }
292 }
Constantin Ziesche857c7ab2020-02-25 11:24:51 +0100293}