Update according to design review
[platform/core/csapi/tizenfx.git] / src / Tizen.Network.IoTConnectivity / Tizen.Network.IoTConnectivity / ResourceInterfaces.cs
1  /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17
18 using System;
19 using System.Collections;
20 using System.Collections.Generic;
21 using System.Text.RegularExpressions;
22
23 namespace Tizen.Network.IoTConnectivity
24 {
25     /// <summary>
26     /// This class contains resource interfaces and provides APIs to manage, add, remove those interfaces.
27     /// A resource interface indicates a class or category of resources.
28     /// </summary>
29     public class ResourceInterfaces : IEnumerable<string>, IDisposable
30     {
31         /// <summary>
32         /// Default Interface
33         /// </summary>
34         public const string DefaultInterface = "oic.if.baseline";
35
36         /// <summary>
37         /// List Links Interface which is used to list the references to other resources contained in a resource.
38         /// </summary>
39         public const string LinkInterface = "oic.if.ll";
40
41         /// <summary>
42         /// Batch Interface which is used to manipulate (GET, PUT, POST, DELETE) on other resource contained in a resource.
43         /// </summary>
44         public const string BatchInterface = "oic.if.b";
45
46         /// <summary>
47         /// Group Interface which is used to manipulate (GET, PUT, POST) a group of remote resources.
48         /// </summary>
49         public const string GroupInterface = "oic.mi.grp";
50
51         /// <summary>
52         /// Read-Only Interface which is used to limit the methods that can be applied to a resource to GET only.
53         /// </summary>
54         public const string ReadonlyInterface = "oic.if.r";
55
56         private readonly IntPtr _resourceInterfacesHandle = IntPtr.Zero;
57         private const int MaxLength = 61;
58         private readonly HashSet<string> _resourceInterfaces = new HashSet<string>();
59         private bool _disposed = false;
60
61         /// <summary>
62         /// Constructor of ResourceInterfaces
63         /// </summary>
64         /// <seealso cref="Add()"/>
65         /// <seealso cref="Remove()"/>
66         /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
67         /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory</exception>
68         /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
69         /// <code>
70         /// ResourceInterfaces resourceInterfaces = new ResourceInterfaces();
71         /// </code>
72         public ResourceInterfaces()
73         {
74             int ret = Interop.IoTConnectivity.Common.ResourceInterfaces.Create(out _resourceInterfacesHandle);
75             if (ret != (int)IoTConnectivityError.None)
76             {
77                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create interface");
78                 throw IoTConnectivityErrorFactory.GetException(ret);
79             }
80         }
81
82         /// <summary>
83         /// Constructor of ResourceInterfaces using list of interfaces
84         /// </summary>
85         /// <param name="ifaces">List of resource interfaces</param>
86         /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
87         /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory</exception>
88         /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
89         /// <code>
90         /// ResourceInterfaces resourceInterfaces = new ResourceInterfaces(new List<string>()
91         ///     { ResourceInterfaces.LinkInterface, ResourceInterfaces.ReadonlyInterface });
92         /// </code>
93         public ResourceInterfaces(IEnumerable<string> ifaces)
94         {
95             int ret = Interop.IoTConnectivity.Common.ResourceInterfaces.Create(out _resourceInterfacesHandle);
96             if (ret != (int)IoTConnectivityError.None)
97             {
98                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create interface");
99                 throw IoTConnectivityErrorFactory.GetException(ret);
100             }
101             foreach (string iface in ifaces)
102             {
103                 Add(iface);
104             }
105         }
106
107         internal ResourceInterfaces(IntPtr ifacesHandleToClone)
108         {
109             int ret = Interop.IoTConnectivity.Common.ResourceInterfaces.Clone(ifacesHandleToClone, out _resourceInterfacesHandle);
110             if (ret != (int)IoTConnectivityError.None)
111             {
112                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create interface");
113                 throw IoTConnectivityErrorFactory.GetException(ret);
114             }
115
116             Interop.IoTConnectivity.Common.ResourceInterfaces.ForeachCallback cb = (string iface, IntPtr data) =>
117             {
118                 _resourceInterfaces.Add(iface);
119                 return true;
120             };
121
122             ret = Interop.IoTConnectivity.Common.ResourceInterfaces.Foreach(ifacesHandleToClone, cb, IntPtr.Zero);
123             if (ret != (int)IoTConnectivityError.None)
124             {
125                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to create type");
126                 throw IoTConnectivityErrorFactory.GetException(ret);
127             }
128         }
129
130         /// <summary>
131         /// Destructor of the ResourceInterfaces class.
132         /// </summary>
133         ~ResourceInterfaces()
134         {
135             Dispose(false);
136         }
137
138         internal IntPtr ResourceInterfacesHandle
139         {
140             get
141             {
142                 return _resourceInterfacesHandle;
143             }
144         }
145
146         /// <summary>
147         /// Indicates count of interfaces in the list
148         /// </summary>
149         /// <code>
150         /// ResourceInterfaces resourceInterfaces = new ResourceInterfaces(new List<string>()
151         ///     { ResourceInterfaces.LinkInterface, ResourceInterfaces.ReadonlyInterface });
152         /// Console.WriteLine("There are {0} interfaces", resourceInterfaces.Count);
153         /// </code>
154         public int Count
155         {
156             get
157             {
158                 return _resourceInterfaces.Count;
159             }
160         }
161
162         /// <summary>
163         /// Adds a resource interface into the list.
164         /// </summary>
165         /// <remarks>
166         /// @a item could be a value such as <see cref="DefaultInterface"/>
167         /// </remarks>
168         /// <param name="item">The string data to insert into the resource interfaces</param>
169         /// <seealso cref="Remove()"/>
170         /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
171         /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
172         /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
173         /// <code>
174         /// ResourceInterfaces resourceInterfaces = new ResourceInterfaces();
175         /// resourceInterfaces.Add(ResourceInterfaces.BatchInterface);
176         /// </code>
177         public void Add(string item)
178         {
179             if (IsValid(item))
180             {
181                 int ret = Interop.IoTConnectivity.Common.ResourceInterfaces.Add(_resourceInterfacesHandle, item);
182                 if (ret != (int)IoTConnectivityError.None)
183                 {
184                     Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to add interface");
185                     throw IoTConnectivityErrorFactory.GetException(ret);
186                 }
187                 _resourceInterfaces.Add(item);
188             }
189             else
190             {
191                 Log.Error(IoTConnectivityErrorFactory.LogTag, "Invalid interface");
192                 throw IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.InvalidParameter);
193             }
194         }
195
196         /// <summary>
197         /// Removes a resource interface from the list
198         /// </summary>
199         /// <param name="item">The string data to delete from the resource ifaces</param>
200         /// <seealso cref="Add()"/>
201         /// <exception cref="NotSupportedException">Thrown when the iotcon is not supported</exception>
202         /// <exception cref="ArgumentException">Thrown when there is an invalid parameter</exception>
203         /// <exception cref="InvalidOperationException">Thrown when the operation is invalid</exception>
204         /// <code>
205         /// ResourceInterfaces resourceInterfaces = new ResourceInterfaces(new List<string>(){ ResourceInterfaces.BatchInterface });
206         /// resourceInterfaces.Add(ResourceInterfaces.BatchInterface);
207         /// </code>
208         public void Remove(string item)
209         {
210             bool isRemoved = _resourceInterfaces.Remove(item);
211             if (isRemoved)
212             {
213                 int ret = Interop.IoTConnectivity.Common.ResourceInterfaces.Remove(_resourceInterfacesHandle, item);
214                 if (ret != (int)IoTConnectivityError.None)
215                 {
216                     Log.Error(IoTConnectivityErrorFactory.LogTag, "Failed to remove interface");
217                     throw IoTConnectivityErrorFactory.GetException(ret);
218                 }
219             }
220             else
221                 throw IoTConnectivityErrorFactory.GetException((int)IoTConnectivityError.InvalidParameter);
222         }
223
224         /// <summary>
225         /// Return enumerator for the list of interfaces
226         /// </summary>
227         /// <returns>The enumerator</returns>
228         /// <code>
229         /// ResourceInterfaces resourceInterfaces = new ResourceInterfaces(new List<string>()
230         ///     { ResourceInterfaces.LinkInterface, ResourceInterfaces.ReadonlyInterface });
231         /// foreach(string item in resourceInterfaces)
232         /// {
233         ///     Console.WriteLine("Interface : {0}", item);
234         /// }
235         /// </code>
236         public IEnumerator<string> GetEnumerator()
237         {
238             return _resourceInterfaces.GetEnumerator();
239         }
240
241         /// <summary>
242         /// Return enumerator for the list of interfaces
243         /// </summary>
244         /// <returns>The enumerator</returns>
245         /// <code>
246         /// ResourceInterfaces resourceInterfaces = new ResourceInterfaces(new List<string>()
247         ///     { ResourceInterfaces.LinkInterface, ResourceInterfaces.ReadonlyInterface });
248         /// foreach(string item in resourceInterfaces)
249         /// {
250         ///     Console.WriteLine("Interface : {0}", item);
251         /// }
252         /// </code>
253         IEnumerator IEnumerable.GetEnumerator()
254         {
255             return _resourceInterfaces.GetEnumerator();
256         }
257
258         /// <summary>
259         /// Releases any unmanaged resources used by this object.
260         /// </summary>
261         public void Dispose()
262         {
263             Dispose(true);
264             GC.SuppressFinalize(this);
265         }
266
267         internal static bool IsValid(string type)
268         {
269             Regex r = new Regex("^[a-zA-Z0-9.-]+$");
270             return (type.Length <= MaxLength && char.IsLower(type[0]) && r.IsMatch(type));
271         }
272
273         /// <summary>
274         /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
275         /// </summary>
276         /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
277         protected virtual void Dispose(bool disposing)
278         {
279             if (_disposed)
280                 return;
281
282             if (disposing)
283             {
284                 // Free managed objects
285             }
286
287             Interop.IoTConnectivity.Common.ResourceInterfaces.Destroy(_resourceInterfacesHandle);
288             _disposed = true;
289         }
290     }
291 }