[NUI] Remove build warning - CA1041
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / Xaml / XamlServiceProvider.cs
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Reflection;
5 using System.Xml;
6 using Tizen.NUI.Binding;
7 using Tizen.NUI.Binding.Internals;
8
9 namespace Tizen.NUI.Xaml
10 {
11     /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
12     [EditorBrowsable(EditorBrowsableState.Never)]
13     public class XamlServiceProvider : IServiceProvider
14     {
15         readonly Dictionary<Type, object> services = new Dictionary<Type, object>();
16
17         internal XamlServiceProvider(INode node, HydrationContext context)
18         {
19             object targetObject;
20             if (node != null && node.Parent != null && context.Values.TryGetValue(node.Parent, out targetObject))
21                 IProvideValueTarget = new XamlValueTargetProvider(targetObject, node, context, null);
22             if (context != null)
23                 IRootObjectProvider = new XamlRootObjectProvider(context.RootElement);
24             if (node != null)
25             {
26                 IXamlTypeResolver = new XamlTypeResolver(node.NamespaceResolver, XamlParser.GetElementType,
27                     context?.RootElement?.GetType().GetTypeInfo().Assembly);
28
29                 Add(typeof(IReferenceProvider), new ReferenceProvider(node));
30             }
31
32             var xmlLineInfo = node as IXmlLineInfo;
33             if (xmlLineInfo != null)
34                 IXmlLineInfoProvider = new XmlLineInfoProvider(xmlLineInfo);
35
36             IValueConverterProvider = new ValueConverterProvider();
37         }
38
39         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
40         [EditorBrowsable(EditorBrowsableState.Never)]
41         public XamlServiceProvider()
42         {
43             IValueConverterProvider = new ValueConverterProvider();
44         }
45
46         internal IProvideValueTarget IProvideValueTarget
47         {
48             get { return (IProvideValueTarget)GetService(typeof(IProvideValueTarget)); }
49             set { services[typeof(IProvideValueTarget)] = value; }
50         }
51
52         internal IXamlTypeResolver IXamlTypeResolver
53         {
54             get { return (IXamlTypeResolver)GetService(typeof(IXamlTypeResolver)); }
55             set { services[typeof(IXamlTypeResolver)] = value; }
56         }
57
58         internal IRootObjectProvider IRootObjectProvider
59         {
60             get { return (IRootObjectProvider)GetService(typeof(IRootObjectProvider)); }
61             set { services[typeof(IRootObjectProvider)] = value; }
62         }
63
64         internal IXmlLineInfoProvider IXmlLineInfoProvider
65         {
66             get { return (IXmlLineInfoProvider)GetService(typeof(IXmlLineInfoProvider)); }
67             set { services[typeof(IXmlLineInfoProvider)] = value; }
68         }
69
70         internal INameScopeProvider INameScopeProvider
71         {
72             get { return (INameScopeProvider)GetService(typeof(INameScopeProvider)); }
73             set { services[typeof(INameScopeProvider)] = value; }
74         }
75
76         internal IValueConverterProvider IValueConverterProvider
77         {
78             get { return (IValueConverterProvider)GetService(typeof(IValueConverterProvider)); }
79             set { services[typeof(IValueConverterProvider)] = value; }
80         }
81
82         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
83         [EditorBrowsable(EditorBrowsableState.Never)]
84         public object GetService(Type serviceType)
85         {
86             object service;
87             return services.TryGetValue(serviceType, out service) ? service : null;
88         }
89
90         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
91         [EditorBrowsable(EditorBrowsableState.Never)]
92         public void Add(Type type, object service)
93         {
94             services.Add(type, service);
95         }
96     }
97
98     internal class XamlValueTargetProvider : IProvideParentValues, IProvideValueTarget
99     {
100         public XamlValueTargetProvider(object targetObject, INode node, HydrationContext context, object targetProperty)
101         {
102             Context = context;
103             Node = node;
104             TargetObject = targetObject;
105             TargetProperty = targetProperty;
106         }
107
108         INode Node { get; }
109
110         HydrationContext Context { get; }
111         public object TargetObject { get; }
112         public object TargetProperty { get; internal set; } = null;
113
114         IEnumerable<object> IProvideParentValues.ParentObjects
115         {
116             get
117             {
118                 if (Node == null || Context == null)
119                     yield break;
120                 var n = Node;
121                 object obj = null;
122                 var context = Context;
123                 while (n.Parent != null && context != null)
124                 {
125                     if (n.Parent is IElementNode)
126                     {
127                         if (context.Values.TryGetValue(n.Parent, out obj))
128                             yield return obj;
129                         else
130                         {
131                             context = context.ParentContext;
132                             continue;
133                         }
134                     }
135                     n = n.Parent;
136                 }
137             }
138         }
139     }
140
141     /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
142     [EditorBrowsable(EditorBrowsableState.Never)]
143     public class SimpleValueTargetProvider : IProvideParentValues, IProvideValueTarget, IReferenceProvider
144     {
145         readonly object[] objectAndParents;
146         readonly object targetProperty;
147
148         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
149         [EditorBrowsable(EditorBrowsableState.Never)]
150         [Obsolete("SimpleValueTargetProvider(object[] objectAndParents) is obsolete as of version 2.3.4. Please use SimpleValueTargetProvider(object[] objectAndParents, object targetProperty) instead.")]
151         public SimpleValueTargetProvider(object[] objectAndParents) : this(objectAndParents, null)
152         {
153         }
154
155         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
156         [EditorBrowsable(EditorBrowsableState.Never)]
157         public SimpleValueTargetProvider(object[] objectAndParents, object targetProperty)
158         {
159             if (objectAndParents == null)
160                 throw new ArgumentNullException(nameof(objectAndParents));
161             if (objectAndParents.Length == 0)
162                 throw new ArgumentException(nameof(objectAndParents.Length));
163
164             this.objectAndParents = objectAndParents;
165             this.targetProperty = targetProperty;
166         }
167
168         IEnumerable<object> IProvideParentValues.ParentObjects
169             => objectAndParents;
170
171         object IProvideValueTarget.TargetObject
172             => objectAndParents[0];
173
174         object IProvideValueTarget.TargetProperty
175             => targetProperty;
176
177         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
178         [EditorBrowsable(EditorBrowsableState.Never)]
179         public object FindByName(string name)
180         {
181             for (var i = 0; i < objectAndParents.Length; i++)
182             {
183                 var bo = objectAndParents[i] as BindableObject;
184                 if (bo == null) continue;
185                 var ns = NameScope.GetNameScope(bo) as INameScope;
186                 if (ns == null) continue;
187                 var value = ns.FindByName(name);
188                 if (value != null)
189                     return value;
190             }
191             return null;
192         }
193     }
194
195     /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
196     [EditorBrowsable(EditorBrowsableState.Never)]
197     public class XamlTypeResolver : IXamlTypeResolver
198     {
199         readonly Assembly currentAssembly;
200         readonly GetTypeFromXmlName getTypeFromXmlName;
201         readonly IXmlNamespaceResolver namespaceResolver;
202
203         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
204         [EditorBrowsable(EditorBrowsableState.Never)]
205         public XamlTypeResolver(IXmlNamespaceResolver namespaceResolver, Assembly currentAssembly)
206             : this(namespaceResolver, XamlParser.GetElementType, currentAssembly)
207         {
208         }
209
210         internal XamlTypeResolver(IXmlNamespaceResolver namespaceResolver, GetTypeFromXmlName getTypeFromXmlName,
211             Assembly currentAssembly)
212         {
213             this.currentAssembly = currentAssembly;
214             if (namespaceResolver == null)
215                 throw new ArgumentNullException(nameof(namespaceResolver));
216             if (getTypeFromXmlName == null)
217                 throw new ArgumentNullException(nameof(getTypeFromXmlName));
218
219             this.namespaceResolver = namespaceResolver;
220             this.getTypeFromXmlName = getTypeFromXmlName;
221         }
222
223         Type IXamlTypeResolver.Resolve(string qualifiedTypeName, IServiceProvider serviceProvider)
224         {
225             XamlParseException e;
226             var type = Resolve(qualifiedTypeName, serviceProvider, out e);
227             if (e != null)
228                 throw e;
229             return type;
230         }
231
232         bool IXamlTypeResolver.TryResolve(string qualifiedTypeName, out Type type)
233         {
234             XamlParseException exception;
235             type = Resolve(qualifiedTypeName, null, out exception);
236             return exception == null;
237         }
238
239         Type Resolve(string qualifiedTypeName, IServiceProvider serviceProvider, out XamlParseException exception)
240         {
241             exception = null;
242             var split = qualifiedTypeName.Split(':');
243             if (split.Length > 2)
244                 return null;
245
246             string prefix, name;
247             if (split.Length == 2)
248             {
249                 prefix = split[0];
250                 name = split[1];
251             }
252             else
253             {
254                 prefix = "";
255                 name = split[0];
256             }
257
258             IXmlLineInfo xmlLineInfo = null;
259             if (serviceProvider != null)
260             {
261                 var lineInfoProvider = serviceProvider.GetService(typeof(IXmlLineInfoProvider)) as IXmlLineInfoProvider;
262                 if (lineInfoProvider != null)
263                     xmlLineInfo = lineInfoProvider.XmlLineInfo;
264             }
265
266             var namespaceuri = namespaceResolver.LookupNamespace(prefix);
267             if (namespaceuri == null)
268             {
269                 exception = new XamlParseException(string.Format("No xmlns declaration for prefix \"{0}\"", prefix), xmlLineInfo);
270                 return null;
271             }
272
273             return getTypeFromXmlName(new XmlType(namespaceuri, name, null), xmlLineInfo, currentAssembly, out exception);
274         }
275
276         internal delegate Type GetTypeFromXmlName(
277             XmlType xmlType, IXmlLineInfo xmlInfo, Assembly currentAssembly, out XamlParseException exception);
278     }
279
280     internal class XamlRootObjectProvider : IRootObjectProvider
281     {
282         public XamlRootObjectProvider(object rootObject)
283         {
284             RootObject = rootObject;
285         }
286
287         public object RootObject { get; }
288     }
289
290     /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
291     [EditorBrowsable(EditorBrowsableState.Never)]
292     public class XmlLineInfoProvider : IXmlLineInfoProvider
293     {
294         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
295         [EditorBrowsable(EditorBrowsableState.Never)]
296         public XmlLineInfoProvider(IXmlLineInfo xmlLineInfo)
297         {
298             XmlLineInfo = xmlLineInfo;
299         }
300
301         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
302         [EditorBrowsable(EditorBrowsableState.Never)]
303         public IXmlLineInfo XmlLineInfo { get; }
304     }
305
306     class ReferenceProvider : IReferenceProvider
307     {
308         readonly INode _node;
309         internal ReferenceProvider(INode node)
310             => _node = node;
311
312         public object FindByName(string name)
313         {
314             var n = _node;
315             object value = null;
316             while (n != null)
317             {
318                 if ((value = (n as IElementNode)?.Namescope?.FindByName(name)) != null)
319                     return value;
320                 n = n.Parent;
321             }
322             return null;
323         }
324     }
325
326     /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
327     [EditorBrowsable(EditorBrowsableState.Never)]
328     [ObsoleteAttribute(" ", false)]
329     public class NameScopeProvider : INameScopeProvider
330     {
331         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
332         [EditorBrowsable(EditorBrowsableState.Never)]
333         public INameScope NameScope { get; set; }
334     }
335
336     /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
337     [EditorBrowsable(EditorBrowsableState.Never)]
338     public class XmlNamespaceResolver : IXmlNamespaceResolver
339     {
340         readonly Dictionary<string, string> namespaces = new Dictionary<string, string>();
341
342         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
343         [EditorBrowsable(EditorBrowsableState.Never)]
344         public IDictionary<string, string> GetNamespacesInScope(XmlNamespaceScope scope)
345         {
346             throw new NotImplementedException();
347         }
348
349         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
350         [EditorBrowsable(EditorBrowsableState.Never)]
351         public string LookupNamespace(string prefix)
352         {
353             string result;
354             if (namespaces.TryGetValue(prefix, out result))
355                 return result;
356             return null;
357         }
358
359         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
360         [EditorBrowsable(EditorBrowsableState.Never)]
361         public string LookupPrefix(string namespaceName)
362         {
363             throw new NotImplementedException();
364         }
365
366         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
367         [EditorBrowsable(EditorBrowsableState.Never)]
368         public void Add(string prefix, string ns)
369         {
370             namespaces.Add(prefix, ns);
371         }
372     }
373 }